org.babyfish.jimmer.sql.cache.caffeine.CaffeineHashBinder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jimmer-sql Show documentation
Show all versions of jimmer-sql Show documentation
A revolutionary ORM framework for both java and kotlin
package org.babyfish.jimmer.sql.cache.caffeine;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.babyfish.jimmer.meta.ImmutableProp;
import org.babyfish.jimmer.meta.ImmutableType;
import org.babyfish.jimmer.sql.cache.CacheTracker;
import org.babyfish.jimmer.sql.cache.chain.SimpleBinder;
import org.babyfish.jimmer.sql.cache.spi.AbstractTrackingConsumerBinder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CaffeineHashBinder extends AbstractTrackingConsumerBinder implements SimpleBinder.Parameterized {
private final Cache, V>> cache;
private final ReadWriteLock rwl = new ReentrantReadWriteLock();
public CaffeineHashBinder(
@Nullable ImmutableType type,
@Nullable ImmutableProp prop,
@Nullable CacheTracker tracker,
int maximumSize,
@NotNull Duration duration
) {
super(type, prop, tracker);
cache = Caffeine
.newBuilder()
.maximumSize(maximumSize)
.expireAfterWrite(duration)
.build();
}
@Override
public Map getAll(Collection keys, SortedMap parameterMap) {
Lock lock = rwl.readLock();
lock.lock();
try {
Map resutMap = new LinkedHashMap<>((keys.size() * 4 + 2) / 3);
Map, V>> subMapMap = cache.getAllPresent(keys);
for (Map.Entry, V>> e : subMapMap.entrySet()) {
Map, V> subMap = e.getValue();
if (subMap == null) {
continue;
}
V value = subMap.get(parameterMap);
if (value == null && subMap.containsKey(parameterMap)) {
continue;
}
resutMap.put(e.getKey(), value);
}
return resutMap;
} finally {
lock.unlock();
}
}
@Override
public void setAll(Map map, SortedMap parameterMap) {
Lock lock = rwl.writeLock();
lock.lock();
try {
Map, V>> subMapMap = cache.getAllPresent(map.keySet());
Map, V>> newSubMapMap = new HashMap<>((map.size() * 4 + 2) / 3);
for (Map.Entry e : map.entrySet()) {
Map, V> subMap = subMapMap.get(e.getKey());
if (subMap == null) {
subMap = new HashMap<>();
} else {
subMap = new HashMap<>(subMap);
}
subMap.put(parameterMap, e.getValue());
newSubMapMap.put(e.getKey(), subMap);
}
cache.putAll(newSubMapMap);
} finally {
lock.unlock();
}
}
@Override
public void deleteAllImpl(@NotNull Collection keys) {
Lock lock = rwl.writeLock();
lock.lock();
try {
cache.invalidateAll(keys);
} finally {
lock.unlock();
}
}
@Override
protected void invalidateAll() {
cache.invalidateAll();
}
@Override
protected boolean matched(@Nullable Object reason) {
return "caffeine".equals(reason);
}
@NotNull
public static Builder forProp(ImmutableProp prop) {
return new Builder<>(null, prop);
}
public static class Builder {
private final ImmutableType type;
private final ImmutableProp prop;
private CacheTracker tracker;
private int maximumSize = 100;
private Duration duration = Duration.ofMinutes(1);
public Builder(ImmutableType type, ImmutableProp prop) {
this.type = type;
this.prop = prop;
}
public Builder subscribe(CacheTracker tracker) {
this.tracker = tracker;
return this;
}
public Builder maximumSize(int maximumSize) {
this.maximumSize = maximumSize;
return this;
}
public Builder duration(Duration duration) {
this.duration = duration;
return this;
}
public CaffeineHashBinder build() {
return new CaffeineHashBinder<>(
type,
prop,
tracker,
maximumSize,
duration
);
}
}
}