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

# 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     * @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 dl 1.3 /** The underlying map */
30     private final ConcurrentHashMapV8<K, LongAdder> map;
31    
32 jsr166 1.4 static final class CreateAdder
33 dl 1.3 implements ConcurrentHashMapV8.MappingFunction<Object, LongAdder> {
34     public LongAdder map(Object unused) { return new LongAdder(); }
35     }
36 dl 1.1
37 dl 1.3 private static final CreateAdder createAdder = new CreateAdder();
38 dl 1.1
39     /**
40     * Creates a new empty table.
41     */
42     public LongAdderTable() {
43 dl 1.3 map = new ConcurrentHashMapV8<K, LongAdder>();
44 dl 1.1 }
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 dl 1.3 if (a == null)
75     a = map.computeIfAbsent(key, createAdder);
76 dl 1.1 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     }