Remove MRUCache

Now we're using ConcurrentHashMap, it's usefulness in terms of performance is debatable
This commit is contained in:
Luck 2020-07-03 18:23:34 +01:00
parent adbd2fc81f
commit 4514a17eaf
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
2 changed files with 2 additions and 95 deletions

View File

@ -1,66 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.cache;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Implementation of a most-recently-used cache with a mod counter, to prevent race conditions
* occurring when the cache is cleared whilst a calculation is taking place.
*
* @param <T> the cached type
*/
public abstract class MRUCache<T> {
private volatile T recent;
private final AtomicInteger modCount = new AtomicInteger();
protected int modCount() {
return this.modCount.get();
}
protected T getRecent() {
return this.recent;
}
protected void offerRecent(int validAt, T offer) {
synchronized (this) {
if (validAt == this.modCount.get()) {
this.recent = offer;
}
}
}
/**
* Calling clearRecent effectively resets the instance. any other threads going to call
* offerRecent in the future with the previous mod count will be ignored.
*/
protected void clearRecent() {
synchronized (this) {
this.recent = null;
this.modCount.incrementAndGet();
}
}
}

View File

@ -26,7 +26,6 @@
package me.lucko.luckperms.common.cacheddata;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.cache.MRUCache;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
@ -183,7 +182,7 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
this.meta.cleanup();
}
private static final class AbstractContainer<C extends I, I extends CachedData> extends MRUCache<RecentData<C>> implements Container<I> {
private static final class AbstractContainer<C extends I, I extends CachedData> implements Container<I> {
private final Function<QueryOptions, C> cacheLoader;
private final LoadingMap<QueryOptions, C> cache;
@ -200,16 +199,8 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
public @NonNull C get(@NonNull QueryOptions queryOptions) {
Objects.requireNonNull(queryOptions, "queryOptions");
RecentData<C> recent = getRecent();
if (recent != null && queryOptions.equals(recent.queryOptions)) {
((UsageTracked) recent.data).recordUsage();
return recent.data;
}
int modCount = modCount();
C data = this.cache.get(queryOptions);
((UsageTracked) data).recordUsage();
offerRecent(modCount, new RecentData<>(queryOptions, data));
return data;
}
@ -225,7 +216,6 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
CompletableFuture.runAsync(() -> {
final C value = this.cacheLoader.apply(queryOptions);
this.cache.put(queryOptions, value);
clearRecent();
}, CaffeineFactory.executor());
}
@ -235,14 +225,9 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
// invalidate the previous value until we're done recalculating
this.cache.remove(queryOptions);
clearRecent();
// request recalculation from the cache
return CompletableFuture.supplyAsync(() -> {
C value = this.cache.get(queryOptions);
clearRecent();
return value;
}, CaffeineFactory.executor());
return CompletableFuture.supplyAsync(() -> this.cache.get(queryOptions), CaffeineFactory.executor());
}
@Override
@ -261,13 +246,11 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
public void invalidate(@NonNull QueryOptions queryOptions) {
Objects.requireNonNull(queryOptions, "queryOptions");
this.cache.remove(queryOptions);
clearRecent();
}
@Override
public void invalidate() {
this.cache.clear();
clearRecent();
}
}
@ -291,14 +274,4 @@ public abstract class AbstractCachedDataManager implements CachedDataManager {
);
}
private static final class RecentData<T> {
final QueryOptions queryOptions;
final T data;
RecentData(QueryOptions queryOptions, T data) {
this.queryOptions = queryOptions;
this.data = data;
}
}
}