diff --git a/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/cache/SimpleCache.java b/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/cache/SimpleCache.java index 509617aca467..66171cd7528a 100644 --- a/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/cache/SimpleCache.java +++ b/agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/cache/SimpleCache.java @@ -20,13 +20,14 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Function; /** * @author emeroad */ public class SimpleCache implements Cache> { // zero means not exist. - private final ConcurrentMap> cache; + private final ConcurrentMap cache; private final AtomicInteger idGen = new AtomicInteger(); public SimpleCache() { @@ -37,32 +38,40 @@ public SimpleCache(int cacheSize) { this.cache = createCache(cacheSize); } - private ConcurrentMap> createCache(int maxCacheSize) { + private ConcurrentMap createCache(int maxCacheSize) { final Caffeine cacheBuilder = CaffeineBuilder.newBuilder(); cacheBuilder.initialCapacity(maxCacheSize); cacheBuilder.maximumSize(maxCacheSize); - com.github.benmanes.caffeine.cache.Cache> localCache = cacheBuilder.build(); + com.github.benmanes.caffeine.cache.Cache localCache = cacheBuilder.build(); return localCache.asMap(); } @Override public Result put(T value) { - final Result find = this.cache.get(value); - if (find != null) { - return find; + final FirstCall mapping = new FirstCall(); + final Integer id = this.cache.computeIfAbsent(value, mapping); + if (mapping.called) { + return new Result<>(true, id); + } else { + return new Result<>(false, id); } - - // Use negative values too to reduce data size - final int newId = nextId(); - final Result result = new Result<>(false, newId); - final Result before = this.cache.putIfAbsent(value, result); - if (before != null) { - return before; - } - return new Result<>(true, newId); } private int nextId() { return this.idGen.incrementAndGet(); } + + private class FirstCall implements Function { + + private boolean called; + + public FirstCall() { + } + + @Override + public Integer apply(T key) { + this.called = true; + return nextId(); + } + } }