Skip to content

Commit d16f116

Browse files
committed
Single threaded cache
1 parent cedd226 commit d16f116

File tree

1 file changed

+24
-29
lines changed

1 file changed

+24
-29
lines changed

src/main/java/io/izzel/mesmerize/impl/service/SimpleStatsService.java

Lines changed: 24 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.github.benmanes.caffeine.cache.CacheLoader;
44
import com.github.benmanes.caffeine.cache.Caffeine;
55
import com.github.benmanes.caffeine.cache.LoadingCache;
6+
import com.github.benmanes.caffeine.cache.Scheduler;
67
import io.izzel.mesmerize.api.cause.CauseManager;
78
import io.izzel.mesmerize.api.event.DamageCalculator;
89
import io.izzel.mesmerize.api.event.StatsRefreshEvent;
@@ -29,12 +30,17 @@
2930
import org.bukkit.entity.Entity;
3031
import org.bukkit.persistence.PersistentDataContainer;
3132
import org.bukkit.persistence.PersistentDataType;
33+
import org.checkerframework.checker.index.qual.Positive;
34+
import org.checkerframework.checker.nullness.qual.NonNull;
3235
import org.jetbrains.annotations.NotNull;
3336

3437
import java.util.Collections;
3538
import java.util.Set;
3639
import java.util.concurrent.Callable;
3740
import java.util.concurrent.ConcurrentHashMap;
41+
import java.util.concurrent.Executor;
42+
import java.util.concurrent.Future;
43+
import java.util.concurrent.FutureTask;
3844
import java.util.concurrent.TimeUnit;
3945

4046
public class SimpleStatsService implements StatsService {
@@ -45,32 +51,34 @@ public class SimpleStatsService implements StatsService {
4551
private final ElementFactory elementFactory = new SimpleElementFactory();
4652
private final DamageCalculator calculator = new SimpleCalculator();
4753

48-
private final Set<Integer> entityLock = Collections.newSetFromMap(new ConcurrentHashMap<>());
49-
5054
private final CacheLoader<Entity, StatsSet> cacheLoader = entity -> {
51-
Callable<StatsSet> callable = () -> {
52-
if (!entity.isValid() || entity.isDead()) {
53-
return null;
54-
}
55+
if (!entity.isValid() || entity.isDead()) {
56+
return null;
57+
}
58+
if (Bukkit.isPrimaryThread()) {
5559
StatsSet statsSet = new StatsSet();
5660
newEntityReader(entity).accept(statsSet, VisitMode.VALUE);
5761
Bukkit.getPluginManager().callEvent(new StatsRefreshEvent(entity, statsSet));
5862
return statsSet;
59-
};
60-
if (Bukkit.isPrimaryThread()) {
61-
return callable.call();
6263
} else {
63-
try {
64-
entityLock.add(entity.getEntityId());
65-
return Bukkit.getScheduler().callSyncMethod(Mesmerize.instance(), callable).get();
66-
} finally {
67-
entityLock.remove(entity.getEntityId());
68-
}
64+
throw new IllegalStateException("async stats load");
6965
}
7066
};
7167

7268
private final LoadingCache<Entity, StatsSet> statsSetCache = Caffeine
7369
.newBuilder()
70+
.scheduler((executor, command, delay, unit) -> {
71+
FutureTask<?> task = new FutureTask<>(command, null);
72+
Bukkit.getScheduler().runTaskLater(Mesmerize.instance(), () -> executor.execute(task), unit.toMillis(delay) / 50);
73+
return task;
74+
})
75+
.executor(r -> {
76+
if (Bukkit.isPrimaryThread()) {
77+
r.run();
78+
} else {
79+
throw new IllegalStateException("async stats load");
80+
}
81+
})
7482
.refreshAfterWrite(ConfigSpec.spec().performance().entityStatsCacheMs(), TimeUnit.MILLISECONDS)
7583
.build(cacheLoader);
7684

@@ -91,20 +99,7 @@ public CauseManager getCauseManager() {
9199

92100
@Override
93101
public StatsSet cachedSetFor(@NotNull Entity entity) {
94-
if (!Bukkit.isPrimaryThread()) {
95-
throw new IllegalStateException("async stats get");
96-
}
97-
StatsSet set;
98-
if (entityLock.contains(entity.getEntityId())) {
99-
try {
100-
set = cacheLoader.load(entity);
101-
} catch (Exception e) {
102-
throw new RuntimeException(e);
103-
}
104-
} else {
105-
set = statsSetCache.get(entity);
106-
}
107-
return set == null ? new StatsSet() : set;
102+
return statsSetCache.get(entity);
108103
}
109104

110105
@Override

0 commit comments

Comments
 (0)