ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdderTable.java
Revision: 1.1
Committed: Sun Jul 31 14:20:01 2011 UTC (12 years, 9 months ago) by dl
Branch: MAIN
Log Message:
Rename classes

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