diff --git a/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java b/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java index 9732120b..df5bf68b 100644 --- a/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java +++ b/common/src/main/java/me/lucko/luckperms/common/calculator/PermissionCalculator.java @@ -25,26 +25,25 @@ package me.lucko.luckperms.common.calculator; -import com.github.benmanes.caffeine.cache.CacheLoader; -import com.github.benmanes.caffeine.cache.Caffeine; -import com.github.benmanes.caffeine.cache.LoadingCache; import com.google.common.collect.ImmutableList; import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.common.cacheddata.CacheMetadata; import me.lucko.luckperms.common.calculator.processor.PermissionProcessor; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.util.LoadingMap; import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent; import org.checkerframework.checker.nullness.qual.NonNull; import java.util.List; import java.util.Map; +import java.util.function.Function; /** * Calculates and caches permissions */ -public class PermissionCalculator implements CacheLoader { +public class PermissionCalculator implements Function { /** * The plugin instance @@ -64,7 +63,7 @@ public class PermissionCalculator implements CacheLoader { /** * Loading cache for permission checks */ - private final LoadingCache lookupCache = Caffeine.newBuilder().build(this); + private final LoadingMap lookupCache = LoadingMap.of(this); public PermissionCalculator(LuckPermsPlugin plugin, CacheMetadata metadata, ImmutableList processors) { this.plugin = plugin; @@ -97,7 +96,7 @@ public class PermissionCalculator implements CacheLoader { } @Override - public Tristate load(@NonNull String permission) { + public Tristate apply(@NonNull String permission) { // offer the permission to the permission vault // we only need to do this once per permission, so it doesn't matter // that this call is behind the cache. @@ -131,6 +130,6 @@ public class PermissionCalculator implements CacheLoader { } public void invalidateCache() { - this.lookupCache.invalidateAll(); + this.lookupCache.clear(); } } diff --git a/common/src/main/java/me/lucko/luckperms/common/util/LoadingMap.java b/common/src/main/java/me/lucko/luckperms/common/util/LoadingMap.java new file mode 100644 index 00000000..85d7060a --- /dev/null +++ b/common/src/main/java/me/lucko/luckperms/common/util/LoadingMap.java @@ -0,0 +1,116 @@ +/* + * This file is part of LuckPerms, licensed under the MIT License. + * + * Copyright (c) lucko (Luck) + * 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.util; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Function; + +public interface LoadingMap extends Map { + static LoadingMap of(Map map, Function function) { + return new LoadingMapImpl<>(map, function); + } + + static LoadingMap of(Function function) { + return of(new ConcurrentHashMap<>(), function); + } +} + +final class LoadingMapImpl implements LoadingMap { + private final Map map; + private final Function function; + + LoadingMapImpl(Map map, Function function) { + this.map = map; + this.function = function; + } + + @Override + public int size() { + return this.map.size(); + } + + @Override + public boolean isEmpty() { + return this.map.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return this.map.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return this.map.containsValue(value); + } + + @Override + public V get(Object key) { + V value = this.map.get(key); + if (value != null) { + return value; + } + return this.map.computeIfAbsent((K) key, this.function); + } + + @Override + public V put(K key, V value) { + return this.map.put(key, value); + } + + @Override + public V remove(Object key) { + return this.map.remove(key); + } + + @Override + public void putAll(Map that) { + this.map.putAll(that); + } + + @Override + public void clear() { + this.map.clear(); + } + + @Override + public Set keySet() { + return this.map.keySet(); + } + + @Override + public Collection values() { + return this.map.values(); + } + + @Override + public Set> entrySet() { + return this.map.entrySet(); + } +} \ No newline at end of file