ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdderTable.java
Revision: 1.4
Committed: Tue Aug 30 07:16:56 2011 UTC (12 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.3: +1 -1 lines
Log Message:
whitespace

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