ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdderTable.java
Revision: 1.11
Committed: Sun Jan 18 20:17:33 2015 UTC (9 years, 4 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +1 -0 lines
Log Message:
exactly one blank line before and after package statements

File Contents

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