ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdderTable.java
Revision: 1.2
Committed: Sun Jul 31 19:24:37 2011 UTC (12 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
Move out of package extra

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package jsr166e;
8 import jsr166e.LongAdder;
9 import java.util.concurrent.ConcurrentHashMap;
10 import java.util.Map;
11 import java.util.Set;
12 import java.io.Serializable;
13
14 /**
15 * A keyed table of adders, that may be useful in computing frequency
16 * counts and histograms, or may be used a form of multiset. A {@link
17 * LongAdder} is associated with each key. Keys are added to the table
18 * implicitly upon any attempt to update, or may be added explicitly
19 * using method {@link #install}.
20 *
21 * <p><em>jsr166e note: This class is targeted to be placed in
22 * java.util.concurrent.atomic<em>
23 *
24 * @author Doug Lea
25 */
26 public class LongAdderTable<K> implements Serializable {
27 /** Relies on default serialization */
28 private static final long serialVersionUID = 7249369246863182397L;
29
30 /** Concurrency parameter for map -- we assume high contention */
31 private static final int MAP_SEGMENTS =
32 Math.max(16, Runtime.getRuntime().availableProcessors());
33
34 /** The underlying map */
35 private final ConcurrentHashMap<K, LongAdder> map;
36
37 /**
38 * Creates a new empty table.
39 */
40 public LongAdderTable() {
41 map = new ConcurrentHashMap<K, LongAdder>(16, 0.75f, MAP_SEGMENTS);
42 }
43
44 /**
45 * If the given key does not already exist in the table, inserts
46 * the key with initial sum of zero; in either case returning the
47 * adder associated with this key.
48 *
49 * @param key the key
50 * @return the adder associated with the key
51 */
52 public LongAdder install(K key) {
53 LongAdder a = map.get(key);
54 if (a == null) {
55 LongAdder r = new LongAdder();
56 if ((a = map.putIfAbsent(key, r)) == null)
57 a = r;
58 }
59 return a;
60 }
61
62 /**
63 * Adds the given value to the sum associated with the given
64 * key. If the key does not already exist in the table, it is
65 * inserted.
66 *
67 * @param key the key
68 * @param x the value to add
69 */
70 public void add(K key, long x) {
71 LongAdder a = map.get(key);
72 if (a == null) {
73 LongAdder r = new LongAdder();
74 if ((a = map.putIfAbsent(key, r)) == null)
75 a = r;
76 }
77 a.add(x);
78 }
79
80 /**
81 * Increments the sum associated with the given key. If the key
82 * does not already exist in the table, it is inserted.
83 *
84 * @param key the key
85 */
86 public void increment(K key) { add(key, 1L); }
87
88 /**
89 * Decrements the sum associated with the given key. If the key
90 * does not already exist in the table, it is inserted.
91 *
92 * @param key the key
93 */
94 public void decrement(K key) { add(key, -1L); }
95
96 /**
97 * Returns the sum associated with the given key, or zero if the
98 * key does not currently exist in the table.
99 *
100 * @param key the key
101 * @return the sum associated with the key, or zero if the key is
102 * not in the table
103 */
104 public long sum(K key) {
105 LongAdder a = map.get(key);
106 return a == null ? 0L : a.sum();
107 }
108
109 /**
110 * Resets the sum associated with the given key to zero if the key
111 * exists in the table. This method does <em>NOT</em> add or
112 * remove the key from the table (see {@link #remove}).
113 *
114 * @param key the key
115 */
116 public void reset(K key) {
117 LongAdder a = map.get(key);
118 if (a != null)
119 a.reset();
120 }
121
122 /**
123 * Resets the sum associated with the given key to zero if the key
124 * exists in the table. This method does <em>NOT</em> add or
125 * remove the key from the table (see {@link #remove}).
126 *
127 * @param key the key
128 * @return the previous sum, or zero if the key is not
129 * in the table
130 */
131 public long sumThenReset(K key) {
132 LongAdder a = map.get(key);
133 return a == null ? 0L : a.sumThenReset();
134 }
135
136 /**
137 * Returns the sum totalled across all keys.
138 *
139 * @return the sum totalled across all keys.
140 */
141 public long sumAll() {
142 long sum = 0L;
143 for (LongAdder a : map.values())
144 sum += a.sum();
145 return sum;
146 }
147
148 /**
149 * Resets the sum associated with each key to zero.
150 */
151 public void resetAll() {
152 for (LongAdder a : map.values())
153 a.reset();
154 }
155
156 /**
157 * Totals, then resets, the sums associated with all keys.
158 *
159 * @return the sum totalled across all keys.
160 */
161 public long sumThenResetAll() {
162 long sum = 0L;
163 for (LongAdder a : map.values())
164 sum += a.sumThenReset();
165 return sum;
166 }
167
168 /**
169 * Removes the given key from the table.
170 *
171 * @param key the key
172 */
173 public void remove(K key) { map.remove(key); }
174
175 /**
176 * Removes all keys from the table.
177 */
178 public void removeAll() { map.clear(); }
179
180 /**
181 * Returns the current set of keys.
182 *
183 * @return the current set of keys
184 */
185 public Set<K> keySet() {
186 return map.keySet();
187 }
188
189 /**
190 * Returns the current set of key-value mappings.
191 *
192 * @return the current set of key-value mappings
193 */
194 public Set<Map.Entry<K,LongAdder>> entrySet() {
195 return map.entrySet();
196 }
197
198 }