001
014
015 package com.liferay.portal.kernel.concurrent;
016
017 import com.liferay.portal.kernel.util.StringBundler;
018 import com.liferay.portal.kernel.util.Validator;
019
020 import java.util.concurrent.atomic.AtomicMarkableReference;
021
022
025 public abstract class IncreasableEntry<K, V> {
026
027 public IncreasableEntry(K key, V value) {
028 _key = key;
029 _markedValue = new AtomicMarkableReference<V>(value, false);
030 }
031
032 public abstract V doIncrease(V originalValue, V deltaValue);
033
034 @Override
035 public boolean equals(Object obj) {
036 if (this == obj) {
037 return true;
038 }
039
040 if (!(obj instanceof IncreasableEntry<?, ?>)) {
041 return false;
042 }
043
044 IncreasableEntry<K, V> increasableEntry = (IncreasableEntry<K, V>)obj;
045
046 if (Validator.equals(_key, increasableEntry._key) &&
047 Validator.equals(
048 _markedValue.getReference(),
049 increasableEntry._markedValue.getReference())) {
050
051 return true;
052 }
053
054 return false;
055 }
056
057 public final K getKey() {
058 return _key;
059 }
060
061 public final V getValue() {
062 while (true) {
063 V value = _markedValue.getReference();
064
065 if (_markedValue.attemptMark(value, true)) {
066 return value;
067 }
068 }
069 }
070
071 @Override
072 public int hashCode() {
073 int hash = 77;
074
075 if (_key != null) {
076 hash += _key.hashCode();
077 }
078
079 hash = 11 * hash;
080
081 V value = _markedValue.getReference();
082
083 if (value != null) {
084 hash += value.hashCode();
085 }
086
087 return hash;
088 }
089
090 public final boolean increase(V deltaValue) {
091 boolean[] marked = {false};
092
093 while (true) {
094 V originalValue = _markedValue.get(marked);
095
096 if (marked[0]) {
097 return false;
098 }
099
100 V newValue = doIncrease(originalValue, deltaValue);
101
102 if (_markedValue.compareAndSet(
103 originalValue, newValue, false, false)) {
104
105 return true;
106 }
107 }
108 }
109
110 @Override
111 public String toString() {
112 StringBundler sb = new StringBundler(5);
113
114 sb.append("{key=");
115 sb.append(String.valueOf(_key.toString()));
116 sb.append(", value=");
117 sb.append(String.valueOf(_markedValue.getReference()));
118 sb.append("}");
119
120 return sb.toString();
121 }
122
123 private final K _key;
124 private final AtomicMarkableReference<V> _markedValue;
125
126 }