Replace guava caches with caffeine

This commit is contained in:
Luck 2017-04-03 00:53:04 +01:00
parent e7e2e3f7e0
commit 2749563f5d
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
23 changed files with 228 additions and 394 deletions

View File

@ -50,6 +50,7 @@ import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.ServerCalculator; import me.lucko.luckperms.common.contexts.ServerCalculator;
import me.lucko.luckperms.common.core.UuidCache; import me.lucko.luckperms.common.core.UuidCache;
import me.lucko.luckperms.common.core.model.User; import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.dependencies.Dependency;
import me.lucko.luckperms.common.dependencies.DependencyManager; import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager; import me.lucko.luckperms.common.locale.NoopLocaleManager;
@ -89,6 +90,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
@ -130,12 +132,18 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private PermissionVault permissionVault; private PermissionVault permissionVault;
@Override @Override
public void onEnable() { public void onLoad() {
// setup minimal functionality in order to load initial dependencies
scheduler = new LPBukkitScheduler(this); scheduler = new LPBukkitScheduler(this);
localeManager = new NoopLocaleManager(); localeManager = new NoopLocaleManager();
senderFactory = new BukkitSenderFactory(this); senderFactory = new BukkitSenderFactory(this);
log = new LoggerImpl(getConsoleSender()); log = new LoggerImpl(getConsoleSender());
DependencyManager.loadDependencies(this, Collections.singletonList(Dependency.CAFFEINE));
}
@Override
public void onEnable() {
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this); LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
ignoringLogs = ConcurrentHashMap.newKeySet(); ignoringLogs = ConcurrentHashMap.newKeySet();

View File

@ -41,6 +41,7 @@ import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.contexts.ServerCalculator; import me.lucko.luckperms.common.contexts.ServerCalculator;
import me.lucko.luckperms.common.core.UuidCache; import me.lucko.luckperms.common.core.UuidCache;
import me.lucko.luckperms.common.core.model.User; import me.lucko.luckperms.common.core.model.User;
import me.lucko.luckperms.common.dependencies.Dependency;
import me.lucko.luckperms.common.dependencies.DependencyManager; import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager; import me.lucko.luckperms.common.locale.NoopLocaleManager;
@ -73,6 +74,7 @@ import net.md_5.bungee.api.plugin.Plugin;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@ -105,11 +107,18 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
private PermissionVault permissionVault; private PermissionVault permissionVault;
@Override @Override
public void onEnable() { public void onLoad() {
// setup minimal functionality in order to load initial dependencies
scheduler = new LPBungeeScheduler(this); scheduler = new LPBungeeScheduler(this);
localeManager = new NoopLocaleManager(); localeManager = new NoopLocaleManager();
senderFactory = new BungeeSenderFactory(this); senderFactory = new BungeeSenderFactory(this);
log = new LoggerImpl(getConsoleSender()); log = new LoggerImpl(getConsoleSender());
DependencyManager.loadDependencies(this, Collections.singletonList(Dependency.CAFFEINE));
}
@Override
public void onEnable() {
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this); LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
verboseHandler = new VerboseHandler(scheduler.getAsyncExecutor(), getVersion()); verboseHandler = new VerboseHandler(scheduler.getAsyncExecutor(), getVersion());
permissionVault = new PermissionVault(scheduler.getAsyncExecutor()); permissionVault = new PermissionVault(scheduler.getAsyncExecutor());

View File

@ -118,6 +118,13 @@
<version>19.0</version> <version>19.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- caffeine -->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.4.0</version>
<scope>provided</scope>
</dependency>
<!-- Lombok --> <!-- Lombok -->
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>

View File

@ -25,12 +25,10 @@ package me.lucko.luckperms.common.caching;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.CacheLoader;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.MetaData; import me.lucko.luckperms.api.caching.MetaData;
@ -49,6 +47,7 @@ import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor @RequiredArgsConstructor
public class UserCache implements UserData { public class UserCache implements UserData {
/** /**
* The user whom this data instance is representing * The user whom this data instance is representing
*/ */
@ -59,7 +58,7 @@ public class UserCache implements UserData {
*/ */
private final CalculatorFactory calculatorFactory; private final CalculatorFactory calculatorFactory;
private final LoadingCache<Contexts, PermissionCache> permission = CacheBuilder.newBuilder() private final LoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(10, TimeUnit.MINUTES)
.build(new CacheLoader<Contexts, PermissionCache>() { .build(new CacheLoader<Contexts, PermissionCache>() {
@Override @Override
@ -68,13 +67,13 @@ public class UserCache implements UserData {
} }
@Override @Override
public ListenableFuture<PermissionCache> reload(Contexts contexts, PermissionCache oldData) { public PermissionCache reload(Contexts contexts, PermissionCache oldData) {
oldData.comparePermissions(user.exportNodes(ExtractedContexts.generate(contexts), true)); oldData.comparePermissions(user.exportNodes(ExtractedContexts.generate(contexts), true));
return Futures.immediateFuture(oldData); return oldData;
} }
}); });
private final LoadingCache<Contexts, MetaCache> meta = CacheBuilder.newBuilder() private final LoadingCache<Contexts, MetaCache> meta = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(10, TimeUnit.MINUTES)
.build(new CacheLoader<Contexts, MetaCache>() { .build(new CacheLoader<Contexts, MetaCache>() {
@Override @Override
@ -83,20 +82,20 @@ public class UserCache implements UserData {
} }
@Override @Override
public ListenableFuture<MetaCache> reload(Contexts contexts, MetaCache oldData) { public MetaCache reload(Contexts contexts, MetaCache oldData) {
oldData.loadMeta(user.accumulateMeta(null, null, ExtractedContexts.generate(contexts))); oldData.loadMeta(user.accumulateMeta(null, null, ExtractedContexts.generate(contexts)));
return Futures.immediateFuture(oldData); return oldData;
} }
}); });
@Override @Override
public PermissionData getPermissionData(@NonNull Contexts contexts) { public PermissionData getPermissionData(@NonNull Contexts contexts) {
return permission.getUnchecked(contexts); return permission.get(contexts);
} }
@Override @Override
public MetaData getMetaData(@NonNull Contexts contexts) { public MetaData getMetaData(@NonNull Contexts contexts) {
return meta.getUnchecked(contexts); return meta.get(contexts);
} }
@Override @Override
@ -142,8 +141,8 @@ public class UserCache implements UserData {
@Override @Override
public void preCalculate(@NonNull Contexts contexts) { public void preCalculate(@NonNull Contexts contexts) {
permission.getUnchecked(contexts); permission.get(contexts);
meta.getUnchecked(contexts); meta.get(contexts);
} }
public void invalidateCache() { public void invalidateCache() {

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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.caching.holder;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.Contexts;
@Getter
@ToString
@EqualsAndHashCode
@AllArgsConstructor(staticName = "of")
public class ExportNodesHolder {
private final Contexts contexts;
private final Boolean lowerCase;
}

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* 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.caching.holder;
import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.utils.ExtractedContexts;
@Getter
@ToString
@EqualsAndHashCode
@AllArgsConstructor(staticName = "of")
public class GetAllNodesRequest {
private final ImmutableSet<String> excludedGroups;
private final ExtractedContexts contexts;
}

View File

@ -24,9 +24,8 @@ package me.lucko.luckperms.common.calculators;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -43,13 +42,7 @@ public class PermissionCalculator {
private final String objectName; private final String objectName;
private final List<PermissionProcessor> processors; private final List<PermissionProcessor> processors;
private final LoadingCache<String, Tristate> cache = CacheBuilder.newBuilder() private final LoadingCache<String, Tristate> cache = Caffeine.newBuilder().build(this::lookupPermissionValue);
.build(new CacheLoader<String, Tristate>() {
@Override
public Tristate load(String s) {
return lookupPermissionValue(s);
}
});
public void invalidateCache() { public void invalidateCache() {
cache.invalidateAll(); cache.invalidateAll();
@ -57,7 +50,7 @@ public class PermissionCalculator {
public Tristate getPermissionValue(String permission) { public Tristate getPermissionValue(String permission) {
permission = permission.toLowerCase(); permission = permission.toLowerCase();
Tristate t = cache.getUnchecked(permission); Tristate t = cache.get(permission);
plugin.getVerboseHandler().offer(objectName, permission, t); plugin.getVerboseHandler().offer(objectName, permission, t);
plugin.getPermissionVault().offer(permission); plugin.getPermissionVault().offer(permission);
return t; return t;

View File

@ -24,9 +24,8 @@ package me.lucko.luckperms.common.config;
import lombok.Getter; import lombok.Getter;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import me.lucko.luckperms.common.api.delegates.LPConfigurationDelegate; import me.lucko.luckperms.common.api.delegates.LPConfigurationDelegate;
import me.lucko.luckperms.common.config.keys.EnduringKey; import me.lucko.luckperms.common.config.keys.EnduringKey;
@ -35,27 +34,22 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@SuppressWarnings("unchecked")
public abstract class AbstractConfiguration implements LuckPermsConfiguration { public abstract class AbstractConfiguration implements LuckPermsConfiguration {
private final LoadingCache<ConfigKey<?>, Optional<Object>> cache = CacheBuilder.newBuilder() private final LoadingCache<ConfigKey<?>, Optional<Object>> cache = Caffeine.newBuilder()
.build(new CacheLoader<ConfigKey<?>, Optional<Object>>() { .build(key -> Optional.ofNullable(key.get(AbstractConfiguration.this)));
@Override
public Optional<Object> load(ConfigKey<?> key) {
return Optional.ofNullable(key.get(AbstractConfiguration.this));
}
});
@Getter @Getter
private final LPConfigurationDelegate delegate = new LPConfigurationDelegate(this); private final LPConfigurationDelegate delegate = new LPConfigurationDelegate(this);
@SuppressWarnings("unchecked")
@Override @Override
public <T> T get(ConfigKey<T> key) { public <T> T get(ConfigKey<T> key) {
return (T) cache.getUnchecked(key).orElse(null); return (T) cache.get(key).orElse(null);
} }
@Override @Override
public void loadAll() { public void loadAll() {
ConfigKeys.getAllKeys().forEach(cache::getUnchecked); ConfigKeys.getAllKeys().forEach(cache::get);
} }
@Override @Override

View File

@ -24,40 +24,20 @@ package me.lucko.luckperms.common.constants;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@UtilityClass @UtilityClass
public class Patterns { public class Patterns {
private static final LoadingCache<String, Pattern> CACHE = CacheBuilder.newBuilder() private static final LoadingCache<String, Pattern> CACHE = Caffeine.newBuilder().build(Pattern::compile);
.build(new CacheLoader<String, Pattern>() { private static final LoadingCache<Map.Entry<String, String>, String> DELIMITER_CACHE = Caffeine.newBuilder()
@Override .build(e -> {
public Pattern load(String s) throws Exception {
return Pattern.compile(s);
}
@Override
public ListenableFuture<Pattern> reload(String s, Pattern pattern) {
return Futures.immediateFuture(pattern);
}
});
private static final LoadingCache<Map.Entry<String, String>, String> DELIMITER_CACHE = CacheBuilder.newBuilder()
.build(new CacheLoader<Map.Entry<String, String>, String>() {
@Override
public String load(Map.Entry<String, String> e) {
// note the reversed order // note the reversed order
return "(?<!" + Pattern.quote(e.getValue()) + ")" + Pattern.quote(e.getKey()); return "(?<!" + Pattern.quote(e.getValue()) + ")" + Pattern.quote(e.getKey());
}
}); });
public static final Pattern COMMAND_SEPARATOR = Pattern.compile(" (?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)"); public static final Pattern COMMAND_SEPARATOR = Pattern.compile(" (?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)");
@ -70,14 +50,14 @@ public class Patterns {
public static Pattern compile(String regex) { public static Pattern compile(String regex) {
try { try {
return CACHE.get(regex); return CACHE.get(regex);
} catch (UncheckedExecutionException | ExecutionException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
} }
} }
public static String buildDelimitedMatcher(String delim, String esc) { public static String buildDelimitedMatcher(String delim, String esc) {
return DELIMITER_CACHE.getUnchecked(Maps.immutableEntry(delim, esc)); return DELIMITER_CACHE.get(Maps.immutableEntry(delim, esc));
} }
public static Pattern compileDelimitedMatcher(String delim, String esc) { public static Pattern compileDelimitedMatcher(String delim, String esc) {

View File

@ -22,9 +22,8 @@
package me.lucko.luckperms.common.contexts; package me.lucko.luckperms.common.contexts;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import me.lucko.luckperms.api.context.ContextCalculator; import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
@ -38,15 +37,10 @@ public class ContextManager<T> {
private final List<ContextCalculator<T>> calculators = new CopyOnWriteArrayList<>(); private final List<ContextCalculator<T>> calculators = new CopyOnWriteArrayList<>();
private final LoadingCache<T, ContextSet> cache = CacheBuilder.newBuilder() private final LoadingCache<T, ContextSet> cache = Caffeine.newBuilder()
.weakKeys() .weakKeys()
.expireAfterWrite(50L, TimeUnit.MILLISECONDS) .expireAfterWrite(50L, TimeUnit.MILLISECONDS)
.build(new CacheLoader<T, ContextSet>() { .build(t -> calculateApplicableContext(t, MutableContextSet.create()).makeImmutable());
@Override
public ContextSet load(T t) {
return calculateApplicableContext(t, MutableContextSet.create()).makeImmutable();
}
});
private MutableContextSet calculateApplicableContext(T subject, MutableContextSet accumulator) { private MutableContextSet calculateApplicableContext(T subject, MutableContextSet accumulator) {
for (ContextCalculator<T> calculator : calculators) { for (ContextCalculator<T> calculator : calculators) {
@ -56,7 +50,7 @@ public class ContextManager<T> {
} }
public ContextSet getApplicableContext(T subject) { public ContextSet getApplicableContext(T subject) {
return cache.getUnchecked(subject); return cache.get(subject);
} }
public void registerCalculator(ContextCalculator<T> calculator) { public void registerCalculator(ContextCalculator<T> calculator) {

View File

@ -24,11 +24,9 @@ package me.lucko.luckperms.common.core;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.UncheckedExecutionException;
import me.lucko.luckperms.api.MetaUtils; import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
@ -38,33 +36,22 @@ import me.lucko.luckperms.common.core.model.Group;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException;
/** /**
* Utility class to make Node(Builder) instances from serialised strings or existing Nodes * Utility class to make Node(Builder) instances from serialised strings or existing Nodes
*/ */
@UtilityClass @UtilityClass
public class NodeFactory { public class NodeFactory {
private static final LoadingCache<String, Node> CACHE = CacheBuilder.newBuilder() private static final LoadingCache<String, Node> CACHE = Caffeine.newBuilder()
.build(new CacheLoader<String, Node>() { .build(s -> builderFromSerialisedNode(s, true).build());
@Override
public Node load(String s) throws Exception {
return builderFromSerialisedNode(s, true).build();
}
});
private static final LoadingCache<String, Node> CACHE_NEGATED = CacheBuilder.newBuilder() private static final LoadingCache<String, Node> CACHE_NEGATED = Caffeine.newBuilder()
.build(new CacheLoader<String, Node>() { .build(s -> builderFromSerialisedNode(s, false).build());
@Override
public Node load(String s) throws Exception {
return builderFromSerialisedNode(s, false).build();
}
});
public static Node fromSerialisedNode(String s, Boolean b) { public static Node fromSerialisedNode(String s, Boolean b) {
try { try {
return b ? CACHE.get(s) : CACHE_NEGATED.get(s); return b ? CACHE.get(s) : CACHE_NEGATED.get(s);
} catch (UncheckedExecutionException | ExecutionException e) { } catch (Exception e) {
throw new IllegalArgumentException(e); throw new IllegalArgumentException(e);
} }
} }

View File

@ -25,9 +25,8 @@ package me.lucko.luckperms.common.core;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import me.lucko.luckperms.api.LocalizedNode; import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
@ -48,13 +47,7 @@ public class PriorityComparator implements Comparator<LocalizedNode> {
} }
private final Collator collator = Collator.getInstance(Locale.ENGLISH); private final Collator collator = Collator.getInstance(Locale.ENGLISH);
private final LoadingCache<String, CollationKey> collationKeyCache = CacheBuilder.newBuilder() private final LoadingCache<String, CollationKey> collationKeyCache = Caffeine.newBuilder().build(collator::getCollationKey);
.build(new CacheLoader<String, CollationKey>() {
@Override
public CollationKey load(String s) throws Exception {
return collator.getCollationKey(s);
}
});
@Override @Override
public int compare(LocalizedNode one, LocalizedNode two) { public int compare(LocalizedNode one, LocalizedNode two) {

View File

@ -29,18 +29,18 @@ import lombok.Getter;
@AllArgsConstructor @AllArgsConstructor
public enum Dependency { public enum Dependency {
MYSQL_DRIVER("https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.6/mysql-connector-java-5.1.6.jar", "5.1.6", "com.mysql.jdbc.jdbc2.optional.MysqlDataSource"), CAFFEINE("https://repo1.maven.org/maven2/com/github/ben-manes/caffeine/caffeine/2.4.0/caffeine-2.4.0.jar", "2.4.0"),
POSTGRESQL_DRIVER("https://repo1.maven.org/maven2/org/postgresql/postgresql/9.4.1212/postgresql-9.4.1212.jar", "9.4.1212", "org.postgresql.ds.PGSimpleDataSource"), MYSQL_DRIVER("https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.6/mysql-connector-java-5.1.6.jar", "5.1.6"),
H2_DRIVER("https://repo1.maven.org/maven2/com/h2database/h2/1.4.193/h2-1.4.193.jar", "1.4.193", "org.h2.Driver"), POSTGRESQL_DRIVER("https://repo1.maven.org/maven2/org/postgresql/postgresql/9.4.1212/postgresql-9.4.1212.jar", "9.4.1212"),
SQLITE_DRIVER("https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.15.1/sqlite-jdbc-3.15.1.jar", "3.15.1", "org.sqlite.JDBC"), H2_DRIVER("https://repo1.maven.org/maven2/com/h2database/h2/1.4.193/h2-1.4.193.jar", "1.4.193"),
HIKARI("https://repo1.maven.org/maven2/com/zaxxer/HikariCP/2.6.1/HikariCP-2.6.1.jar", "2.6.1", "com.zaxxer.hikari.HikariConfig"), SQLITE_DRIVER("https://repo1.maven.org/maven2/org/xerial/sqlite-jdbc/3.15.1/sqlite-jdbc-3.15.1.jar", "3.15.1"),
SLF4J_SIMPLE("https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.9/slf4j-simple-1.7.9.jar", "1.7.9", "org.slf4j.impl.SimpleLoggerFactory"), HIKARI("https://repo1.maven.org/maven2/com/zaxxer/HikariCP/2.6.1/HikariCP-2.6.1.jar", "2.6.1"),
SLF4J_API("https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.9/slf4j-api-1.7.9.jar", "1.7.9", "org.slf4j.helpers.BasicMarkerFactory"), SLF4J_SIMPLE("https://repo1.maven.org/maven2/org/slf4j/slf4j-simple/1.7.9/slf4j-simple-1.7.9.jar", "1.7.9"),
MONGODB_DRIVER("https://repo1.maven.org/maven2/org/mongodb/mongo-java-driver/3.4.1/mongo-java-driver-3.4.1.jar", "3.4.1", "com.mongodb.Mongo"), SLF4J_API("https://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.9/slf4j-api-1.7.9.jar", "1.7.9"),
JEDIS("https://github.com/lucko/jedis/releases/download/jedis-2.9.1-shaded/jedis-2.9.1-shaded.jar", "2.9.1-shaded", "redis.clients.jedis.shaded.Jedis"); MONGODB_DRIVER("https://repo1.maven.org/maven2/org/mongodb/mongo-java-driver/3.4.1/mongo-java-driver-3.4.1.jar", "3.4.1"),
JEDIS("https://github.com/lucko/jedis/releases/download/jedis-2.9.1-shaded/jedis-2.9.1-shaded.jar", "2.9.1-shaded");
private final String url; private final String url;
private final String version; private final String version;
private final String testClass;
} }

View File

@ -22,12 +22,10 @@
package me.lucko.luckperms.common.managers; package me.lucko.luckperms.common.managers;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.CacheLoader;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import me.lucko.luckperms.common.utils.Identifiable; import me.lucko.luckperms.common.utils.Identifiable;
@ -41,16 +39,7 @@ import java.util.Map;
*/ */
public abstract class AbstractManager<I, T extends Identifiable<I>> implements Manager<I, T> { public abstract class AbstractManager<I, T extends Identifiable<I>> implements Manager<I, T> {
@SuppressWarnings("unchecked") private final LoadingCache<I, T> objects = Caffeine.newBuilder()
private static <I> I lowerCase(I i) {
if (i instanceof String) {
return (I) ((String) i).toLowerCase();
} else {
return i;
}
}
private final LoadingCache<I, T> objects = CacheBuilder.newBuilder()
.build(new CacheLoader<I, T>() { .build(new CacheLoader<I, T>() {
@Override @Override
public T load(I i) { public T load(I i) {
@ -58,8 +47,8 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements M
} }
@Override @Override
public ListenableFuture<T> reload(I i, T t) { public T reload(I i, T t) {
return Futures.immediateFuture(t); // Never needs to be refreshed. return t; // Never needs to be refreshed.
} }
}); });
@ -70,7 +59,7 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements M
@Override @Override
public T getOrMake(I id) { public T getOrMake(I id) {
return objects.getUnchecked(lowerCase(id)); return objects.get(lowerCase(id));
} }
@Override @Override
@ -102,4 +91,13 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements M
objects.invalidateAll(); objects.invalidateAll();
} }
@SuppressWarnings("unchecked")
private static <I> I lowerCase(I i) {
if (i instanceof String) {
return (I) ((String) i).toLowerCase();
} else {
return i;
}
}
} }

View File

@ -169,6 +169,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
localeManager = new NoopLocaleManager(); localeManager = new NoopLocaleManager();
senderFactory = new SpongeSenderFactory(this); senderFactory = new SpongeSenderFactory(this);
log = new LoggerImpl(getConsoleSender()); log = new LoggerImpl(getConsoleSender());
LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this); LuckPermsPlugin.sendStartupBanner(getConsoleSender(), this);
verboseHandler = new VerboseHandler(scheduler.getAsyncExecutor(), getVersion()); verboseHandler = new VerboseHandler(scheduler.getAsyncExecutor(), getVersion());
permissionVault = new PermissionVault(scheduler.getAsyncExecutor()); permissionVault = new PermissionVault(scheduler.getAsyncExecutor());

View File

@ -22,15 +22,13 @@
package me.lucko.luckperms.sponge.managers; package me.lucko.luckperms.sponge.managers;
import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.CacheLoader;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
@ -53,13 +51,14 @@ import co.aikar.timings.Timing;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class SpongeGroupManager implements GroupManager, LPSubjectCollection { public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
@Getter
private final LPSpongePlugin plugin; private final LPSpongePlugin plugin;
private final LoadingCache<String, SpongeGroup> objects = CacheBuilder.newBuilder() private final LoadingCache<String, SpongeGroup> objects = Caffeine.newBuilder()
.build(new CacheLoader<String, SpongeGroup>() { .build(new CacheLoader<String, SpongeGroup>() {
@Override @Override
public SpongeGroup load(String i) { public SpongeGroup load(String i) {
@ -67,31 +66,28 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
} }
@Override @Override
public ListenableFuture<SpongeGroup> reload(String i, SpongeGroup t) { public SpongeGroup reload(String i, SpongeGroup t) {
return Futures.immediateFuture(t); // Never needs to be refreshed. return t; // Never needs to be refreshed.
} }
}); });
private final LoadingCache<String, LPSubject> subjectLoadingCache = CacheBuilder.newBuilder() private final LoadingCache<String, LPSubject> subjectLoadingCache = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTES) .expireAfterWrite(1, TimeUnit.MINUTES)
.build(new CacheLoader<String, LPSubject>() { .build(s -> {
@Override
public LPSubject load(String s) throws Exception {
if (isLoaded(s)) { if (isLoaded(s)) {
return getIfLoaded(s).getSpongeData(); return getIfLoaded(s).getSpongeData();
} }
// Request load // Request load
plugin.getStorage().createAndLoadGroup(s, CreationCause.INTERNAL).join(); getPlugin().getStorage().createAndLoadGroup(s, CreationCause.INTERNAL).join();
SpongeGroup group = getIfLoaded(s); SpongeGroup group = getIfLoaded(s);
if (group == null) { if (group == null) {
plugin.getLog().severe("Error whilst loading group '" + s + "'."); getPlugin().getLog().severe("Error whilst loading group '" + s + "'.");
throw new RuntimeException(); throw new RuntimeException();
} }
return group.getSpongeData(); return group.getSpongeData();
}
}); });
public SpongeGroupManager(LPSpongePlugin plugin) { public SpongeGroupManager(LPSpongePlugin plugin) {
@ -114,7 +110,7 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
@Override @Override
public SpongeGroup getOrMake(String id) { public SpongeGroup getOrMake(String id) {
return objects.getUnchecked(id.toLowerCase()); return objects.get(id.toLowerCase());
} }
@Override @Override
@ -173,7 +169,7 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
try { try {
return subjectLoadingCache.get(id); return subjectLoadingCache.get(id);
} catch (UncheckedExecutionException | ExecutionException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
plugin.getLog().warn("Couldn't get group subject for id: " + id); plugin.getLog().warn("Couldn't get group subject for id: " + id);
return plugin.getService().getFallbackGroupSubjects().get(id); // fallback to the transient collection return plugin.getService().getFallbackGroupSubjects().get(id); // fallback to the transient collection

View File

@ -22,15 +22,13 @@
package me.lucko.luckperms.sponge.managers; package me.lucko.luckperms.sponge.managers;
import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.CacheLoader;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
@ -57,13 +55,14 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class SpongeUserManager implements UserManager, LPSubjectCollection { public class SpongeUserManager implements UserManager, LPSubjectCollection {
@Getter
private final LPSpongePlugin plugin; private final LPSpongePlugin plugin;
private final LoadingCache<UserIdentifier, SpongeUser> objects = CacheBuilder.newBuilder() private final LoadingCache<UserIdentifier, SpongeUser> objects = Caffeine.newBuilder()
.build(new CacheLoader<UserIdentifier, SpongeUser>() { .build(new CacheLoader<UserIdentifier, SpongeUser>() {
@Override @Override
public SpongeUser load(UserIdentifier i) { public SpongeUser load(UserIdentifier i) {
@ -71,16 +70,14 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
} }
@Override @Override
public ListenableFuture<SpongeUser> reload(UserIdentifier i, SpongeUser t) { public SpongeUser reload(UserIdentifier i, SpongeUser t) {
return Futures.immediateFuture(t); // Never needs to be refreshed. return t; // Never needs to be refreshed.
} }
}); });
private final LoadingCache<UUID, LPSubject> subjectLoadingCache = CacheBuilder.newBuilder() private final LoadingCache<UUID, LPSubject> subjectLoadingCache = Caffeine.<UUID, LPSubject>newBuilder()
.expireAfterWrite(1, TimeUnit.MINUTES) .expireAfterWrite(1, TimeUnit.MINUTES)
.build(new CacheLoader<UUID, LPSubject>() { .build(u -> {
@Override
public LPSubject load(UUID u) throws Exception {
if (isLoaded(UserIdentifier.of(u, null))) { if (isLoaded(UserIdentifier.of(u, null))) {
SpongeUser user = get(u); SpongeUser user = get(u);
@ -92,22 +89,21 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
} }
// Request load // Request load
plugin.getStorage().loadUser(u, "null").join(); getPlugin().getStorage().loadUser(u, "null").join();
SpongeUser user = get(u); SpongeUser user = get(u);
if (user == null) { if (user == null) {
plugin.getLog().severe("Error whilst loading user '" + u + "'."); getPlugin().getLog().severe("Error whilst loading user '" + u + "'.");
throw new RuntimeException(); throw new RuntimeException();
} }
user.setupData(false); user.setupData(false);
if (user.getUserData() == null) { if (user.getUserData() == null) {
plugin.getLog().warn("User data not present for requested user id: " + u); getPlugin().getLog().warn("User data not present for requested user id: " + u);
} }
return user.getSpongeData(); return user.getSpongeData();
}
}); });
public SpongeUserManager(LPSpongePlugin plugin) { public SpongeUserManager(LPSpongePlugin plugin) {
@ -144,7 +140,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
@Override @Override
public SpongeUser getOrMake(UserIdentifier id) { public SpongeUser getOrMake(UserIdentifier id) {
return objects.getUnchecked(id); return objects.get(id);
} }
@Override @Override
@ -251,7 +247,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
UUID u = plugin.getUuidCache().getUUID(uuid); UUID u = plugin.getUuidCache().getUUID(uuid);
try { try {
return subjectLoadingCache.get(u); return subjectLoadingCache.get(u);
} catch (UncheckedExecutionException | ExecutionException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
plugin.getLog().warn("Couldn't get user subject for id: " + id); plugin.getLog().warn("Couldn't get user subject for id: " + id);
return plugin.getService().getFallbackUserSubjects().get(id); // fallback to the transient collection return plugin.getService().getFallbackUserSubjects().get(id); // fallback to the transient collection

View File

@ -24,9 +24,8 @@ package me.lucko.luckperms.sponge.model;
import lombok.Getter; import lombok.Getter;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.api.LocalizedNode; import me.lucko.luckperms.api.LocalizedNode;
@ -68,7 +67,11 @@ public class SpongeGroup extends Group {
} }
public static class GroupSubject implements LPSubject { public static class GroupSubject implements LPSubject {
@Getter
private final SpongeGroup parent; private final SpongeGroup parent;
@Getter
private final LPSpongePlugin plugin; private final LPSpongePlugin plugin;
@Getter @Getter
@ -77,38 +80,32 @@ public class SpongeGroup extends Group {
@Getter @Getter
private final LuckPermsSubjectData transientSubjectData; private final LuckPermsSubjectData transientSubjectData;
private final LoadingCache<ContextSet, NodeTree> permissionCache = CacheBuilder.newBuilder() private final LoadingCache<ContextSet, NodeTree> permissionCache = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(10, TimeUnit.MINUTES)
.build(new CacheLoader<ContextSet, NodeTree>() { .build(contexts -> {
@Override
public NodeTree load(ContextSet contexts) {
// TODO move this away from NodeTree // TODO move this away from NodeTree
Map<String, Boolean> permissions = parent.getAllNodes(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream() Map<String, Boolean> permissions = getParent().getAllNodes(ExtractedContexts.generate(getPlugin().getService().calculateContexts(contexts))).stream()
.map(LocalizedNode::getNode) .map(LocalizedNode::getNode)
.collect(Collectors.toMap(Node::getPermission, Node::getValue)); .collect(Collectors.toMap(Node::getPermission, Node::getValue));
return NodeTree.of(permissions); return NodeTree.of(permissions);
}
}); });
private final LoadingCache<ContextSet, Set<SubjectReference>> parentCache = CacheBuilder.newBuilder() private final LoadingCache<ContextSet, Set<SubjectReference>> parentCache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES) .expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<ContextSet, Set<SubjectReference>>() { .build(contexts -> {
@Override Set<SubjectReference> subjects = getParent().getAllNodes(ExtractedContexts.generate(getPlugin().getService().calculateContexts(contexts))).stream()
public Set<SubjectReference> load(ContextSet contexts) {
Set<SubjectReference> subjects = parent.getAllNodes(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
.map(LocalizedNode::getNode) .map(LocalizedNode::getNode)
.filter(Node::isGroupNode) .filter(Node::isGroupNode)
.map(Node::getGroupName) .map(Node::getGroupName)
.map(s -> plugin.getService().getGroupSubjects().get(s)) .map(s -> getPlugin().getService().getGroupSubjects().get(s))
.map(LPSubject::toReference) .map(LPSubject::toReference)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
subjects.addAll(plugin.getService().getGroupSubjects().getDefaultSubject().resolve(getService()).getParents(contexts)); subjects.addAll(getPlugin().getService().getGroupSubjects().getDefaultSubject().resolve(getService()).getParents(contexts));
subjects.addAll(plugin.getService().getDefaults().getParents(contexts)); subjects.addAll(getPlugin().getService().getDefaults().getParents(contexts));
return ImmutableSet.copyOf(subjects); return ImmutableSet.copyOf(subjects);
}
}); });
private GroupSubject(LPSpongePlugin plugin, SpongeGroup parent) { private GroupSubject(LPSpongePlugin plugin, SpongeGroup parent) {
@ -159,7 +156,7 @@ public class SpongeGroup extends Group {
@Override @Override
public Tristate getPermissionValue(ContextSet contexts, String permission) { public Tristate getPermissionValue(ContextSet contexts, String permission) {
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PERMISSION_VALUE)) { try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PERMISSION_VALUE)) {
NodeTree nt = permissionCache.getUnchecked(contexts); NodeTree nt = permissionCache.get(contexts);
Tristate t = Util.convertTristate(nt.get(permission)); Tristate t = Util.convertTristate(nt.get(permission));
if (t != Tristate.UNDEFINED) { if (t != Tristate.UNDEFINED) {
return t; return t;
@ -185,7 +182,7 @@ public class SpongeGroup extends Group {
@Override @Override
public Set<SubjectReference> getParents(ContextSet contexts) { public Set<SubjectReference> getParents(ContextSet contexts) {
try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PARENTS)) { try (Timing ignored = plugin.getTimings().time(LPTiming.GROUP_GET_PARENTS)) {
return parentCache.getUnchecked(contexts); return parentCache.get(contexts);
} }
} }

View File

@ -30,15 +30,13 @@ import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.ToString; import lombok.ToString;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.CacheLoader;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
@ -109,7 +107,7 @@ public class LuckPermsService implements PermissionService {
private final Set<CalculatedSubjectData> localDataCaches; private final Set<CalculatedSubjectData> localDataCaches;
@Getter(value = AccessLevel.NONE) @Getter(value = AccessLevel.NONE)
private final LoadingCache<String, LPSubjectCollection> collections = CacheBuilder.newBuilder() private final LoadingCache<String, LPSubjectCollection> collections = Caffeine.newBuilder()
.build(new CacheLoader<String, LPSubjectCollection>() { .build(new CacheLoader<String, LPSubjectCollection>() {
@Override @Override
public LPSubjectCollection load(String s) { public LPSubjectCollection load(String s) {
@ -117,8 +115,8 @@ public class LuckPermsService implements PermissionService {
} }
@Override @Override
public ListenableFuture<LPSubjectCollection> reload(String s, LPSubjectCollection collection) { public LPSubjectCollection reload(String s, LPSubjectCollection collection) {
return Futures.immediateFuture(collection); // Never needs to be refreshed. return collection; // Never needs to be refreshed.
} }
}); });
@ -171,7 +169,7 @@ public class LuckPermsService implements PermissionService {
@Override @Override
public LPSubjectCollection getSubjects(String s) { public LPSubjectCollection getSubjects(String s) {
try (Timing ignored = plugin.getTimings().time(LPTiming.GET_SUBJECTS)) { try (Timing ignored = plugin.getTimings().time(LPTiming.GET_SUBJECTS)) {
return collections.getUnchecked(s.toLowerCase()); return collections.get(s.toLowerCase());
} }
} }

View File

@ -25,9 +25,9 @@ package me.lucko.luckperms.sponge.service.calculated;
import lombok.Getter; import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.CacheLoader;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.LoadingCache; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -103,7 +103,7 @@ public class CalculatedSubjectData implements LPSubjectData {
private final String calculatorDisplayName; private final String calculatorDisplayName;
private final Map<ContextSet, Map<String, Boolean>> permissions = new ConcurrentHashMap<>(); private final Map<ContextSet, Map<String, Boolean>> permissions = new ConcurrentHashMap<>();
private final LoadingCache<ContextSet, CalculatorHolder> permissionCache = CacheBuilder.newBuilder() private final LoadingCache<ContextSet, CalculatorHolder> permissionCache = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(10, TimeUnit.MINUTES)
.build(new CacheLoader<ContextSet, CalculatorHolder>() { .build(new CacheLoader<ContextSet, CalculatorHolder>() {
@Override @Override
@ -131,7 +131,7 @@ public class CalculatedSubjectData implements LPSubjectData {
} }
public Tristate getPermissionValue(ContextSet contexts, String permission) { public Tristate getPermissionValue(ContextSet contexts, String permission) {
return permissionCache.getUnchecked(contexts).getCalculator().getPermissionValue(permission); return permissionCache.get(contexts).getCalculator().getPermissionValue(permission);
} }
public void replacePermissions(Map<ImmutableContextSet, Map<String, Boolean>> map) { public void replacePermissions(Map<ImmutableContextSet, Map<String, Boolean>> map) {

View File

@ -27,9 +27,8 @@ import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
@ -55,13 +54,8 @@ public class PersistedCollection implements LPSubjectCollection {
private final boolean transientHasPriority; private final boolean transientHasPriority;
@Getter(AccessLevel.NONE) @Getter(AccessLevel.NONE)
private final LoadingCache<String, PersistedSubject> subjects = CacheBuilder.newBuilder() private final LoadingCache<String, PersistedSubject> subjects = Caffeine.newBuilder()
.build(new CacheLoader<String, PersistedSubject>() { .build(s -> new PersistedSubject(s, getService(), PersistedCollection.this));
@Override
public PersistedSubject load(String s) {
return new PersistedSubject(s, service, PersistedCollection.this);
}
});
public void loadAll() { public void loadAll() {
Map<String, SubjectStorageModel> holders = service.getStorage().loadAllFromFile(identifier); Map<String, SubjectStorageModel> holders = service.getStorage().loadAllFromFile(identifier);
@ -73,7 +67,7 @@ public class PersistedCollection implements LPSubjectCollection {
@Override @Override
public PersistedSubject get(@NonNull String id) { public PersistedSubject get(@NonNull String id) {
return subjects.getUnchecked(id.toLowerCase()); return subjects.get(id.toLowerCase());
} }
@Override @Override

View File

@ -25,9 +25,8 @@ package me.lucko.luckperms.sponge.service.persisted;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
@ -67,31 +66,17 @@ public class PersistedSubject implements LPSubject {
private final PersistedSubjectData subjectData; private final PersistedSubjectData subjectData;
private final CalculatedSubjectData transientSubjectData; private final CalculatedSubjectData transientSubjectData;
private final LoadingCache<PermissionLookup, Tristate> permissionLookupCache = CacheBuilder.newBuilder() private final LoadingCache<PermissionLookup, Tristate> permissionLookupCache = Caffeine.newBuilder()
.expireAfterAccess(20, TimeUnit.MINUTES) .expireAfterAccess(20, TimeUnit.MINUTES)
.build(new CacheLoader<PermissionLookup, Tristate>() { .build(lookup -> lookupPermissionValue(lookup.getContexts(), lookup.getNode()));
@Override
public Tristate load(PermissionLookup lookup) {
return lookupPermissionValue(lookup.getContexts(), lookup.getNode());
}
});
private final LoadingCache<ImmutableContextSet, Set<SubjectReference>> parentLookupCache = CacheBuilder.newBuilder()
.expireAfterAccess(20, TimeUnit.MINUTES)
.build(new CacheLoader<ImmutableContextSet, Set<SubjectReference>>() {
@Override
public Set<SubjectReference> load(ImmutableContextSet contexts) {
return lookupParents(contexts);
}
});
private final LoadingCache<OptionLookup, Optional<String>> optionLookupCache = CacheBuilder.newBuilder()
.expireAfterAccess(20, TimeUnit.MINUTES)
.build(new CacheLoader<OptionLookup, Optional<String>>() {
@Override
public Optional<String> load(OptionLookup lookup) {
return lookupOptionValue(lookup.getContexts(), lookup.getKey());
}
});
private final LoadingCache<ImmutableContextSet, Set<SubjectReference>> parentLookupCache = Caffeine.newBuilder()
.expireAfterAccess(20, TimeUnit.MINUTES)
.build(this::lookupParents);
private final LoadingCache<OptionLookup, Optional<String>> optionLookupCache = Caffeine.newBuilder()
.expireAfterAccess(20, TimeUnit.MINUTES)
.build(lookup -> lookupOptionValue(lookup.getContexts(), lookup.getKey()));
private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, r -> PersistedSubject.this.service.getPlugin().doAsync(r)) { private final BufferedRequest<Void> saveBuffer = new BufferedRequest<Void>(1000L, r -> PersistedSubject.this.service.getPlugin().doAsync(r)) {
@Override @Override
@ -251,7 +236,7 @@ public class PersistedSubject implements LPSubject {
@Override @Override
public Tristate getPermissionValue(@NonNull ContextSet contexts, @NonNull String node) { public Tristate getPermissionValue(@NonNull ContextSet contexts, @NonNull String node) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_PERMISSION_VALUE)) { try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_PERMISSION_VALUE)) {
Tristate t = permissionLookupCache.getUnchecked(PermissionLookup.of(node, contexts.makeImmutable())); Tristate t = permissionLookupCache.get(PermissionLookup.of(node, contexts.makeImmutable()));
service.getPlugin().getVerboseHandler().offer("local:" + getParentCollection().getCollection() + "/" + identifier, node, t); service.getPlugin().getVerboseHandler().offer("local:" + getParentCollection().getCollection() + "/" + identifier, node, t);
return t; return t;
} }
@ -275,14 +260,14 @@ public class PersistedSubject implements LPSubject {
@Override @Override
public Set<SubjectReference> getParents(@NonNull ContextSet contexts) { public Set<SubjectReference> getParents(@NonNull ContextSet contexts) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_PARENTS)) { try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_PARENTS)) {
return parentLookupCache.getUnchecked(contexts.makeImmutable()); return parentLookupCache.get(contexts.makeImmutable());
} }
} }
@Override @Override
public Optional<String> getOption(ContextSet contexts, String key) { public Optional<String> getOption(ContextSet contexts, String key) {
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_OPTION)) { try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_OPTION)) {
return optionLookupCache.getUnchecked(OptionLookup.of(key, contexts.makeImmutable())); return optionLookupCache.get(OptionLookup.of(key, contexts.makeImmutable()));
} }
} }

View File

@ -25,9 +25,8 @@ package me.lucko.luckperms.sponge.service.proxy;
import lombok.NonNull; import lombok.NonNull;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import com.google.common.cache.CacheBuilder; import com.github.benmanes.caffeine.cache.Caffeine;
import com.google.common.cache.CacheLoader; import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
@ -41,28 +40,18 @@ import java.util.Set;
@UtilityClass @UtilityClass
public class Util { public class Util {
private static final LoadingCache<Set<Context>, ImmutableContextSet> SPONGE_TO_LP_CACHE = CacheBuilder.newBuilder() private static final LoadingCache<Set<Context>, ImmutableContextSet> SPONGE_TO_LP_CACHE = Caffeine.newBuilder()
.build(new CacheLoader<Set<Context>, ImmutableContextSet>() { .build(ImmutableContextSet::fromEntries);
@Override
public ImmutableContextSet load(Set<Context> contexts) {
return ImmutableContextSet.fromEntries(contexts);
}
});
private static final LoadingCache<ImmutableContextSet, Set<Context>> LP_TO_SPONGE_CACHE = CacheBuilder.newBuilder() private static final LoadingCache<ImmutableContextSet, Set<Context>> LP_TO_SPONGE_CACHE = Caffeine.newBuilder()
.build(new CacheLoader<ImmutableContextSet, Set<Context>>() { .build(set -> set.toSet().stream().map(e -> new Context(e.getKey(), e.getValue())).collect(ImmutableCollectors.toImmutableSet()));
@Override
public Set<Context> load(ImmutableContextSet set) {
return set.toSet().stream().map(e -> new Context(e.getKey(), e.getValue())).collect(ImmutableCollectors.toImmutableSet());
}
});
public static ContextSet convertContexts(@NonNull Set<Context> contexts) { public static ContextSet convertContexts(@NonNull Set<Context> contexts) {
return SPONGE_TO_LP_CACHE.getUnchecked(ImmutableSet.copyOf(contexts)); return SPONGE_TO_LP_CACHE.get(ImmutableSet.copyOf(contexts));
} }
public static Set<Context> convertContexts(@NonNull ContextSet contexts) { public static Set<Context> convertContexts(@NonNull ContextSet contexts) {
return LP_TO_SPONGE_CACHE.getUnchecked(contexts.makeImmutable()); return LP_TO_SPONGE_CACHE.get(contexts.makeImmutable());
} }
public static Tristate convertTristate(me.lucko.luckperms.api.Tristate tristate) { public static Tristate convertTristate(me.lucko.luckperms.api.Tristate tristate) {