ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdderTable.java
Revision: 1.9
Committed: Mon Aug 13 15:52:33 2012 UTC (11 years, 9 months ago) by dl
Branch: MAIN
Changes since 1.8: +2 -2 lines
Log Message:
Introduce CHM bulk parallel APIs

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