diff options
author | nharmata <nharmata@google.com> | 2018-03-28 15:50:02 -0700 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-03-28 15:51:47 -0700 |
commit | 81cc4132547d00c2dd3af86537cfb5ffd602b06e (patch) | |
tree | 27c39fae974a1a37f6fdc3a3cfa334d79d706a6a /src/main/java/com/google/devtools/build/lib/concurrent | |
parent | 500e17be9da4c334c02b8e08f2d5c62254432178 (diff) |
Introduce FastHotKeyAtomicLongMap#getCounter. This is useful for when clients have a particular super-hot key, and want to avoid the cpu cost of doing a map lookup.
RELNOTES: None
PiperOrigin-RevId: 190848508
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/concurrent')
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/concurrent/FastHotKeyAtomicLongMap.java | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/concurrent/FastHotKeyAtomicLongMap.java b/src/main/java/com/google/devtools/build/lib/concurrent/FastHotKeyAtomicLongMap.java index 92d8b9979b..4136331134 100644 --- a/src/main/java/com/google/devtools/build/lib/concurrent/FastHotKeyAtomicLongMap.java +++ b/src/main/java/com/google/devtools/build/lib/concurrent/FastHotKeyAtomicLongMap.java @@ -47,24 +47,40 @@ public class FastHotKeyAtomicLongMap<T> { } public long incrementAndGet(T key) { - return getOrInsertCounter(key).incrementAndGet(); + return getCounter(key).incrementAndGet(); } public long decrementAndGet(T key) { - return getOrInsertCounter(key).decrementAndGet(); + return getCounter(key).decrementAndGet(); } public ImmutableMap<T, Long> asImmutableMap() { return ImmutableMap.copyOf(Maps.transformValues(map, AtomicLong::get)); } - public void clear() { - map.clear(); - } - - private AtomicLong getOrInsertCounter(T element) { + /** + * Returns the {@link AtomicLong} for the given {@code element}. Mutations to this + * {@link AtomicLong} will be reflected in the {@link FastHotKeyAtomicLongMap}: for example, + * {@code map.getCounter(e).incrementAndGet()} has exactly the same side effects as + * {@code map.incrementAndGet(e)}. + * + * <p>Consider using this method when you have a super-hot key that you know about a priori. + * Prefer {@link #incrementAndGet} and {@link #decrementAndGet} otherwise. + */ + public AtomicLong getCounter(T element) { // Optimize for the case where 'element' is already in our map. See the class javadoc. AtomicLong counter = map.get(element); return counter != null ? counter : map.computeIfAbsent(element, s -> new AtomicLong(0)); } + + /** + * Clears the {@link FastHotKeyAtomicLongMap}. + * + * <p>Any {@link AtomicLong} instances previously returned by a call to {@link #getCounter} are + * now meaningless: mutations to them will not be reflected in the + * {@link FastHotKeyAtomicLongMap}. + */ + public void clear() { + map.clear(); + } } |