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 public boolean equals(Object obj) {
035 if (this == obj) {
036 return true;
037 }
038
039 if (!(obj instanceof IncreasableEntry<?, ?>)) {
040 return false;
041 }
042
043 IncreasableEntry<K, V> increasableEntry = (IncreasableEntry<K, V>)obj;
044
045 if (Validator.equals(_key, increasableEntry._key) &&
046 Validator.equals(
047 _markedValue.getReference(),
048 increasableEntry._markedValue.getReference())) {
049
050 return true;
051 }
052
053 return false;
054 }
055
056 public final K getKey() {
057 return _key;
058 }
059
060 public final V getValue() {
061 while (true) {
062 V value = _markedValue.getReference();
063
064 if (_markedValue.attemptMark(value, true)) {
065 return value;
066 }
067 }
068 }
069
070 public int hashCode() {
071 int hash = 77;
072
073 if (_key != null) {
074 hash += _key.hashCode();
075 }
076
077 hash = 11 * hash;
078
079 V value = _markedValue.getReference();
080
081 if (value != null) {
082 hash += value.hashCode();
083 }
084
085 return hash;
086 }
087
088 public final boolean increase(V deltaValue) {
089 boolean[] marked = {false};
090
091 while (true) {
092 V originalValue = _markedValue.get(marked);
093
094 if (marked[0]) {
095 return false;
096 }
097 else {
098 V newValue = doIncrease(originalValue, deltaValue);
099
100 if (_markedValue.compareAndSet(
101 originalValue, newValue, false, false)) {
102
103 return true;
104 }
105 }
106 }
107 }
108
109 public String toString() {
110 StringBundler sb = new StringBundler(5);
111
112 sb.append("{key=");
113 sb.append(String.valueOf(_key.toString()));
114 sb.append(", value=");
115 sb.append(String.valueOf(_markedValue.getReference()));
116 sb.append("}");
117
118 return sb.toString();
119 }
120
121 private final K _key;
122 private final AtomicMarkableReference<V> _markedValue;
123
124 }