Improve consistency of contextual primary group caching

This commit is contained in:
Luck 2018-05-04 17:24:40 +01:00
parent 2dbbea4993
commit 7da0c58b76
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
4 changed files with 53 additions and 55 deletions

View File

@ -29,7 +29,7 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.caching.UserCachedData;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.primarygroup.CachedPrimaryGroupHolder;
import me.lucko.luckperms.common.primarygroup.ContextualHolder;
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
import java.util.Optional;
@ -81,8 +81,8 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
super.invalidateCache();
// invalidate our caches
if (this.primaryGroup instanceof CachedPrimaryGroupHolder) {
((CachedPrimaryGroupHolder) this.primaryGroup).invalidate();
if (this.primaryGroup instanceof ContextualHolder) {
((ContextualHolder) this.primaryGroup).invalidateCache();
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.common.primarygroup;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.inheritance.InheritanceGraph;
@ -34,28 +32,25 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User;
import java.util.List;
import java.util.Optional;
public class AllParentsByWeightHolder extends CachedPrimaryGroupHolder {
import javax.annotation.Nonnull;
public class AllParentsByWeightHolder extends ContextualHolder {
public AllParentsByWeightHolder(User user) {
super(user);
}
@Nonnull
@Override
protected String calculateValue() {
Contexts contexts = this.user.getPlugin().getContextForUser(this.user).orElse(null);
if (contexts == null) {
contexts = this.user.getPlugin().getContextManager().getStaticContexts();
}
protected Optional<String> calculateValue(Contexts contexts) {
InheritanceGraph graph = this.user.getPlugin().getInheritanceHandler().getGraph(contexts);
// fully traverse the graph, obtain a list of permission holders the user inherits from
List<PermissionHolder> traversal = ImmutableList.copyOf(graph.traverse(this.user.getPlugin().getConfiguration().get(ConfigKeys.INHERITANCE_TRAVERSAL_ALGORITHM), this.user));
Iterable<PermissionHolder> traversal = graph.traverse(this.user.getPlugin().getConfiguration().get(ConfigKeys.INHERITANCE_TRAVERSAL_ALGORITHM), this.user);
Group bestGroup = null;
if (!traversal.isEmpty()) {
int best = 0;
for (PermissionHolder holder : traversal) {
if (!(holder instanceof Group)) {
@ -69,8 +64,7 @@ public class AllParentsByWeightHolder extends CachedPrimaryGroupHolder {
best = weight;
}
}
}
return bestGroup == null ? null : bestGroup.getName();
return bestGroup == null ? Optional.empty() : Optional.of(bestGroup.getName());
}
}

View File

@ -25,40 +25,49 @@
package me.lucko.luckperms.common.primarygroup;
import me.lucko.luckperms.common.buffers.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
/**
* Abstract implementation of {@link PrimaryGroupHolder} which caches all lookups.
*/
public abstract class CachedPrimaryGroupHolder extends StoredHolder {
public abstract class ContextualHolder extends StoredHolder {
// cache lookups
private final Cache<String> cache = new Cache<String>() {
@Nonnull
@Override
protected String supply() {
return calculateValue();
}
};
private final LoadingCache<Contexts, Optional<String>> cache = Caffeine.newBuilder()
.expireAfterAccess(1, TimeUnit.MINUTES)
.build(this::calculateValue);
public CachedPrimaryGroupHolder(User user) {
public ContextualHolder(User user) {
super(user);
}
protected abstract String calculateValue();
@Nonnull
protected abstract Optional<String> calculateValue(Contexts contexts);
public void invalidate() {
this.cache.invalidate();;
public void invalidateCache() {
this.cache.invalidateAll();
}
@Override
public final String getValue() {
String s = this.cache.get();
return s != null ? s : getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME);
Contexts contexts = this.user.getPlugin().getContextForUser(this.user).orElse(null);
if (contexts == null) {
contexts = this.user.getPlugin().getContextManager().getStaticContexts();
}
return Objects.requireNonNull(this.cache.get(contexts))
.orElseGet(() -> getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME));
}
}

View File

@ -31,26 +31,21 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
public class ParentsByWeightHolder extends CachedPrimaryGroupHolder {
import javax.annotation.Nonnull;
public class ParentsByWeightHolder extends ContextualHolder {
public ParentsByWeightHolder(User user) {
super(user);
}
@Nonnull
@Override
protected String calculateValue() {
Contexts contexts = this.user.getPlugin().getContextForUser(this.user).orElse(null);
if (contexts == null) {
contexts = this.user.getPlugin().getContextManager().getStaticContexts();
}
protected Optional<String> calculateValue(Contexts contexts) {
Set<Group> groups = new LinkedHashSet<>();
for (Node node : this.user.getOwnNodes(contexts.getContexts())) {
if (!node.getValue() || !node.isGroupNode()) {
continue;
}
for (Node node : this.user.getOwnGroupNodes(contexts.getContexts())) {
Group group = this.user.getPlugin().getGroupManager().getIfLoaded(node.getGroupName());
if (group != null) {
groups.add(group);
@ -70,6 +65,6 @@ public class ParentsByWeightHolder extends CachedPrimaryGroupHolder {
}
}
return bestGroup == null ? null : bestGroup.getName();
return bestGroup == null ? Optional.empty() : Optional.of(bestGroup.getName());
}
}