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

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.common.primarygroup; package me.lucko.luckperms.common.primarygroup;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.inheritance.InheritanceGraph; import me.lucko.luckperms.common.inheritance.InheritanceGraph;
@ -34,43 +32,39 @@ import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder; import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.User; 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) { public AllParentsByWeightHolder(User user) {
super(user); super(user);
} }
@Nonnull
@Override @Override
protected String calculateValue() { protected Optional<String> calculateValue(Contexts contexts) {
Contexts contexts = this.user.getPlugin().getContextForUser(this.user).orElse(null);
if (contexts == null) {
contexts = this.user.getPlugin().getContextManager().getStaticContexts();
}
InheritanceGraph graph = this.user.getPlugin().getInheritanceHandler().getGraph(contexts); InheritanceGraph graph = this.user.getPlugin().getInheritanceHandler().getGraph(contexts);
// fully traverse the graph, obtain a list of permission holders the user inherits from // 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; Group bestGroup = null;
if (!traversal.isEmpty()) { int best = 0;
int best = 0; for (PermissionHolder holder : traversal) {
for (PermissionHolder holder : traversal) { if (!(holder instanceof Group)) {
if (!(holder instanceof Group)) { continue;
continue; }
} Group g = ((Group) holder);
Group g = ((Group) holder);
int weight = g.getWeight().orElse(0); int weight = g.getWeight().orElse(0);
if (bestGroup == null || g.getWeight().orElse(0) > best) { if (bestGroup == null || g.getWeight().orElse(0) > best) {
bestGroup = g; bestGroup = g;
best = weight; 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; 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.model.User;
import me.lucko.luckperms.common.node.factory.NodeFactory; 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; import javax.annotation.Nonnull;
/** /**
* Abstract implementation of {@link PrimaryGroupHolder} which caches all lookups. * Abstract implementation of {@link PrimaryGroupHolder} which caches all lookups.
*/ */
public abstract class CachedPrimaryGroupHolder extends StoredHolder { public abstract class ContextualHolder extends StoredHolder {
// cache lookups // cache lookups
private final Cache<String> cache = new Cache<String>() { private final LoadingCache<Contexts, Optional<String>> cache = Caffeine.newBuilder()
@Nonnull .expireAfterAccess(1, TimeUnit.MINUTES)
@Override .build(this::calculateValue);
protected String supply() {
return calculateValue();
}
};
public CachedPrimaryGroupHolder(User user) { public ContextualHolder(User user) {
super(user); super(user);
} }
protected abstract String calculateValue(); @Nonnull
protected abstract Optional<String> calculateValue(Contexts contexts);
public void invalidate() { public void invalidateCache() {
this.cache.invalidate();; this.cache.invalidateAll();
} }
@Override @Override
public final String getValue() { public final String getValue() {
String s = this.cache.get(); Contexts contexts = this.user.getPlugin().getContextForUser(this.user).orElse(null);
return s != null ? s : getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME); 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 me.lucko.luckperms.common.model.User;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set; import java.util.Set;
public class ParentsByWeightHolder extends CachedPrimaryGroupHolder { import javax.annotation.Nonnull;
public class ParentsByWeightHolder extends ContextualHolder {
public ParentsByWeightHolder(User user) { public ParentsByWeightHolder(User user) {
super(user); super(user);
} }
@Nonnull
@Override @Override
protected String calculateValue() { protected Optional<String> calculateValue(Contexts contexts) {
Contexts contexts = this.user.getPlugin().getContextForUser(this.user).orElse(null);
if (contexts == null) {
contexts = this.user.getPlugin().getContextManager().getStaticContexts();
}
Set<Group> groups = new LinkedHashSet<>(); Set<Group> groups = new LinkedHashSet<>();
for (Node node : this.user.getOwnNodes(contexts.getContexts())) { for (Node node : this.user.getOwnGroupNodes(contexts.getContexts())) {
if (!node.getValue() || !node.isGroupNode()) {
continue;
}
Group group = this.user.getPlugin().getGroupManager().getIfLoaded(node.getGroupName()); Group group = this.user.getPlugin().getGroupManager().getIfLoaded(node.getGroupName());
if (group != null) { if (group != null) {
groups.add(group); 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());
} }
} }