1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.kernel.concurrent;
16  
17  import com.liferay.portal.kernel.util.StringBundler;
18  import com.liferay.portal.kernel.util.Validator;
19  
20  import java.util.concurrent.atomic.AtomicMarkableReference;
21  
22  /**
23   * <a href="IncreasableEntry.java.html"><b><i>View Source</i></b></a>
24   *
25   * @author Shuyang Zhou
26   */
27  public abstract class IncreasableEntry<K, V> {
28  
29      public IncreasableEntry(K key, V value) {
30          _key = key;
31          _markedValue = new AtomicMarkableReference<V>(value, false);
32      }
33  
34      public abstract V doIncrease(V originalValue, V deltaValue);
35  
36      public boolean equals(Object obj) {
37          if (this == obj) {
38              return true;
39          }
40  
41          if (!(obj instanceof IncreasableEntry<?, ?>)) {
42              return false;
43          }
44  
45          IncreasableEntry<K, V> increasableEntry = (IncreasableEntry<K, V>)obj;
46  
47          if (Validator.equals(_key, increasableEntry._key) &&
48              Validator.equals(
49                  _markedValue.getReference(),
50                  increasableEntry._markedValue.getReference())) {
51  
52              return true;
53          }
54  
55          return false;
56      }
57  
58      public final K getKey() {
59          return _key;
60      }
61  
62      public final V getValue() {
63          while (true) {
64              V value = _markedValue.getReference();
65  
66              if (_markedValue.attemptMark(value, true)) {
67                  return value;
68              }
69          }
70      }
71  
72      public int hashCode() {
73          int hash = 77;
74  
75          if (_key != null) {
76              hash += _key.hashCode();
77          }
78  
79          hash = 11 * hash;
80  
81          V value = _markedValue.getReference();
82  
83          if (value != null) {
84              hash += value.hashCode();
85          }
86  
87          return hash;
88      }
89  
90      public final boolean increase(V deltaValue) {
91          boolean[] marked = {false};
92  
93          while (true) {
94              V originalValue = _markedValue.get(marked);
95  
96              if (marked[0]) {
97                  return false;
98              }
99              else {
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 
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 }