ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdderTable.java
Revision: 1.7
Committed: Sun Oct 2 22:01:06 2011 UTC (12 years, 7 months ago) by dl
Branch: MAIN
Changes since 1.6: +2 -11 lines
Log Message:
Reparameterize compute method; various other improvements

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 dl 1.1 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 jsr166 1.5 * @since 1.8
24 dl 1.1 * @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 dl 1.3 /** The underlying map */
31     private final ConcurrentHashMapV8<K, LongAdder> map;
32    
33 jsr166 1.4 static final class CreateAdder
34 dl 1.3 implements ConcurrentHashMapV8.MappingFunction<Object, LongAdder> {
35     public LongAdder map(Object unused) { return new LongAdder(); }
36     }
37 dl 1.1
38 dl 1.3 private static final CreateAdder createAdder = new CreateAdder();
39 dl 1.1
40     /**
41     * Creates a new empty table.
42     */
43     public LongAdderTable() {
44 dl 1.3 map = new ConcurrentHashMapV8<K, LongAdder>();
45 dl 1.1 }
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 dl 1.7 return map.computeIfAbsent(key, createAdder);
57 dl 1.1 }
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 dl 1.7 map.computeIfAbsent(key, createAdder).add(x);
69 dl 1.1 }
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 jsr166 1.6 * @return the sum totalled across all keys
131 dl 1.1 */
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 jsr166 1.6 * @return the sum totalled across all keys
151 dl 1.1 */
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     }