Skip to content

Commit

Permalink
[#noissue] Improve ID assignment in SimpleCache
Browse files Browse the repository at this point in the history
  • Loading branch information
emeroad committed Sep 13, 2024
1 parent 1ccf6cb commit 689a1e6
Showing 1 changed file with 24 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> implements Cache<T, Result<Integer>> {
// zero means not exist.
private final ConcurrentMap<T, Result<Integer>> cache;
private final ConcurrentMap<T, Integer> cache;
private final AtomicInteger idGen = new AtomicInteger();

public SimpleCache() {
Expand All @@ -37,32 +38,40 @@ public SimpleCache(int cacheSize) {
this.cache = createCache(cacheSize);
}

private ConcurrentMap<T, Result<Integer>> createCache(int maxCacheSize) {
private ConcurrentMap<T, Integer> createCache(int maxCacheSize) {
final Caffeine<Object, Object> cacheBuilder = CaffeineBuilder.newBuilder();
cacheBuilder.initialCapacity(maxCacheSize);
cacheBuilder.maximumSize(maxCacheSize);
com.github.benmanes.caffeine.cache.Cache<T, Result<Integer>> localCache = cacheBuilder.build();
com.github.benmanes.caffeine.cache.Cache<T, Integer> localCache = cacheBuilder.build();
return localCache.asMap();
}

@Override
public Result<Integer> put(T value) {
final Result<Integer> 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<Integer> result = new Result<>(false, newId);
final Result<Integer> 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<T, Integer> {

private boolean called;

public FirstCall() {
}

@Override
public Integer apply(T key) {
this.called = true;
return nextId();
}
}
}

0 comments on commit 689a1e6

Please sign in to comment.