ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/extra/StripedAdderTable.java
Revision: 1.3
Committed: Sun Jul 31 14:20:06 2011 UTC (12 years, 10 months ago) by dl
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +0 -0 lines
State: FILE REMOVED
Log Message:
Rename classes

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.extra;
8 import jsr166e.StripedAdder;
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 scalable adders, that may be useful in computing
16 * frequency counts and histograms, or may be used a form of multiset.
17 * A {@link StripedAdder} is associated with each key. Keys may be
18 * added to the table explicitly ({@link #install}, and are also added
19 * implicitly upon any attempt to update.
20 *
21 * @author Doug Lea
22 */
23 public class StripedAdderTable<K> implements Serializable {
24 /** Relies on default serialization */
25 private static final long serialVersionUID = 7249369246863182397L;
26
27 /** Concurrency parameter for map -- we assume high contention */
28 private static final int MAP_SEGMENTS =
29 Math.max(16, Runtime.getRuntime().availableProcessors());
30
31 /** The underlying map */
32 private final ConcurrentHashMap<K, StripedAdder> map;
33
34 /**
35 * Creates a new empty table.
36 */
37 public StripedAdderTable() {
38 map = new ConcurrentHashMap<K, StripedAdder>(16, 0.75f, MAP_SEGMENTS);
39 }
40
41 /**
42 * If the given key does not already exist in the table, adds the
43 * key with initial sum of zero; in either case returning the
44 * adder associated with this key.
45 *
46 * @param key the key
47 * @return the counter associated with the key
48 */
49 public StripedAdder install(K key) {
50 StripedAdder a = map.get(key);
51 if (a == null) {
52 StripedAdder r = new StripedAdder();
53 if ((a = map.putIfAbsent(key, r)) == null)
54 a = r;
55 }
56 return a;
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 StripedAdder a = map.get(key);
69 if (a == null) {
70 StripedAdder r = new StripedAdder();
71 if ((a = map.putIfAbsent(key, r)) == null)
72 a = r;
73 }
74 a.add(x);
75 }
76
77 /**
78 * Increments the sum associated with the given key. If the key
79 * does not already exist in the table, it is inserted.
80 *
81 * @param key the key
82 */
83 public void increment(K key) { add(key, 1L); }
84
85 /**
86 * Decrements the sum associated with the given key. If the key
87 * does not already exist in the table, it is inserted.
88 *
89 * @param key the key
90 */
91 public void decrement(K key) { add(key, -1L); }
92
93 /**
94 * Returns the sum associated with the given key, or zero if the
95 * key does not currently exist in the table.
96 *
97 * @param key the key
98 * @return the sum associated with the key, or zero if the key is
99 * not in the table
100 */
101 public long sum(K key) {
102 StripedAdder a = map.get(key);
103 return a == null ? 0L : a.sum();
104 }
105
106 /**
107 * Resets the sum associated with the given key to zero if the key
108 * exists in the table. This method does <em>NOT</em> add or
109 * remove the key from the table (see {@link #remove}).
110 *
111 * @param key the key
112 */
113 public void reset(K key) {
114 StripedAdder a = map.get(key);
115 if (a != null)
116 a.reset();
117 }
118
119 /**
120 * Resets the sum associated with the given key to zero if the key
121 * exists in the table. This method does <em>NOT</em> add or
122 * remove the key from the table (see {@link #remove}).
123 *
124 * @param key the key
125 * @return the previous sum, or zero if the key is not
126 * in the table
127 */
128 public long sumThenReset(K key) {
129 StripedAdder a = map.get(key);
130 return a == null ? 0L : a.sumThenReset();
131 }
132
133 /**
134 * Returns the sum totalled across all keys.
135 *
136 * @return the sum totalled across all keys.
137 */
138 public long sumAll() {
139 long sum = 0L;
140 for (StripedAdder a : map.values())
141 sum += a.sum();
142 return sum;
143 }
144
145 /**
146 * Resets the sum associated with each key to zero.
147 */
148 public void resetAll() {
149 for (StripedAdder a : map.values())
150 a.reset();
151 }
152
153 /**
154 * Totals, then resets, the sums associated with all keys.
155 *
156 * @return the sum totalled across all keys.
157 */
158 public long sumThenResetAll() {
159 long sum = 0L;
160 for (StripedAdder a : map.values())
161 sum += a.sumThenReset();
162 return sum;
163 }
164
165 /**
166 * Removes the given key from the table.
167 *
168 * @param key the key
169 */
170 public void remove(K key) { map.remove(key); }
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,StripedAdder>> entrySet() {
187 return map.entrySet();
188 }
189
190 }