Cache calls querying parent groups in bridge subjects - closes #69
This commit is contained in:
parent
d9d01e09aa
commit
4857969ca4
@ -116,6 +116,9 @@ public abstract class PermissionHolder {
|
|||||||
@Getter
|
@Getter
|
||||||
private final Lock ioLock = new ReentrantLock();
|
private final Lock ioLock = new ReentrantLock();
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Set<Runnable> stateListeners = ConcurrentHashMap.newKeySet();
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CACHES - cache the result of a number of methods in this class, until they are invalidated.
|
* CACHES - cache the result of a number of methods in this class, until they are invalidated.
|
||||||
@ -178,6 +181,15 @@ public abstract class PermissionHolder {
|
|||||||
getAllNodesFilteredCache.invalidateAll();
|
getAllNodesFilteredCache.invalidateAll();
|
||||||
exportNodesCache.invalidateAll();
|
exportNodesCache.invalidateAll();
|
||||||
|
|
||||||
|
// Invalidate listeners
|
||||||
|
for (Runnable r : stateListeners) {
|
||||||
|
try {
|
||||||
|
r.run();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get previous references
|
// Get previous references
|
||||||
Set<HolderReference> refs = plugin.getCachedStateManager().getInheritances(toReference());
|
Set<HolderReference> refs = plugin.getCachedStateManager().getInheritances(toReference());
|
||||||
|
|
||||||
|
@ -24,6 +24,9 @@ package me.lucko.luckperms.sponge.model;
|
|||||||
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import com.google.common.cache.CacheBuilder;
|
||||||
|
import com.google.common.cache.CacheLoader;
|
||||||
|
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;
|
||||||
@ -73,11 +76,48 @@ public class SpongeGroup extends Group {
|
|||||||
@Getter
|
@Getter
|
||||||
private final LuckPermsSubjectData transientSubjectData;
|
private final LuckPermsSubjectData transientSubjectData;
|
||||||
|
|
||||||
|
private final LoadingCache<ContextSet, NodeTree> permissionCache = CacheBuilder.newBuilder()
|
||||||
|
.build(new CacheLoader<ContextSet, NodeTree>() {
|
||||||
|
@Override
|
||||||
|
public NodeTree load(ContextSet contexts) {
|
||||||
|
// TODO move this away from NodeTree
|
||||||
|
Map<String, Boolean> permissions = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
||||||
|
.map(LocalizedNode::getNode)
|
||||||
|
.collect(Collectors.toMap(Node::getPermission, Node::getValue));
|
||||||
|
|
||||||
|
return NodeTree.of(permissions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
private final LoadingCache<ContextSet, Set<SubjectReference>> parentCache = CacheBuilder.newBuilder()
|
||||||
|
.build(new CacheLoader<ContextSet, Set<SubjectReference>>() {
|
||||||
|
@Override
|
||||||
|
public Set<SubjectReference> load(ContextSet contexts) {
|
||||||
|
Set<SubjectReference> subjects = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
||||||
|
.map(LocalizedNode::getNode)
|
||||||
|
.filter(Node::isGroupNode)
|
||||||
|
.map(Node::getGroupName)
|
||||||
|
.map(s -> plugin.getService().getGroupSubjects().get(s))
|
||||||
|
.map(LPSubject::toReference)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
subjects.addAll(plugin.getService().getGroupSubjects().getDefaultSubject().resolve(getService()).getParents(contexts));
|
||||||
|
subjects.addAll(plugin.getService().getDefaults().getParents(contexts));
|
||||||
|
|
||||||
|
return ImmutableSet.copyOf(subjects);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
private GroupSubject(LPSpongePlugin plugin, SpongeGroup parent) {
|
private GroupSubject(LPSpongePlugin plugin, SpongeGroup parent) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.subjectData = new LuckPermsSubjectData(true, plugin.getService(), parent, this);
|
this.subjectData = new LuckPermsSubjectData(true, plugin.getService(), parent, this);
|
||||||
this.transientSubjectData = new LuckPermsSubjectData(false, plugin.getService(), parent, this);
|
this.transientSubjectData = new LuckPermsSubjectData(false, plugin.getService(), parent, this);
|
||||||
|
|
||||||
|
parent.getStateListeners().add(() -> {
|
||||||
|
permissionCache.invalidateAll();
|
||||||
|
parentCache.invalidateAll();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -108,12 +148,8 @@ 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)) {
|
||||||
// TODO move this away from NodeTree
|
NodeTree nt = permissionCache.getUnchecked(contexts);
|
||||||
Map<String, Boolean> permissions = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
Tristate t = Util.convertTristate(nt.get(permission));
|
||||||
.map(LocalizedNode::getNode)
|
|
||||||
.collect(Collectors.toMap(Node::getPermission, Node::getValue));
|
|
||||||
|
|
||||||
Tristate t = Util.convertTristate(NodeTree.of(permissions).get(permission));
|
|
||||||
if (t != Tristate.UNDEFINED) {
|
if (t != Tristate.UNDEFINED) {
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
@ -138,18 +174,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)) {
|
||||||
Set<SubjectReference> subjects = parent.getAllNodesFiltered(ExtractedContexts.generate(plugin.getService().calculateContexts(contexts))).stream()
|
return parentCache.getUnchecked(contexts);
|
||||||
.map(LocalizedNode::getNode)
|
|
||||||
.filter(Node::isGroupNode)
|
|
||||||
.map(Node::getGroupName)
|
|
||||||
.map(s -> plugin.getService().getGroupSubjects().get(s))
|
|
||||||
.map(LPSubject::toReference)
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
|
|
||||||
subjects.addAll(plugin.getService().getGroupSubjects().getDefaultSubject().resolve(getService()).getParents(contexts));
|
|
||||||
subjects.addAll(plugin.getService().getDefaults().getParents(contexts));
|
|
||||||
|
|
||||||
return ImmutableSet.copyOf(subjects);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user