Try to reduce contention in PermissionHolder

This commit is contained in:
Luck 2016-11-05 17:49:52 +00:00
parent 5361b1e87b
commit f72819a664
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B

View File

@ -89,14 +89,14 @@ public abstract class PermissionHolder {
TreeSet<LocalizedNode> combined = new TreeSet<>(PriorityComparator.reverse()); TreeSet<LocalizedNode> combined = new TreeSet<>(PriorityComparator.reverse());
Set<Node> enduring = getNodes(); Set<Node> enduring = getNodes();
if (!enduring.isEmpty()) { if (!enduring.isEmpty()) {
combined.addAll(getNodes().stream() combined.addAll(enduring.stream()
.map(n -> makeLocal(n, getObjectName())) .map(n -> makeLocal(n, getObjectName()))
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
} }
Set<Node> tran = getTransientNodes(); Set<Node> tran = getTransientNodes();
if (!tran.isEmpty()) { if (!tran.isEmpty()) {
combined.addAll(getTransientNodes().stream() combined.addAll(tran.stream()
.map(n -> makeLocal(n, getObjectName())) .map(n -> makeLocal(n, getObjectName()))
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
@ -123,14 +123,14 @@ public abstract class PermissionHolder {
TreeSet<LocalizedNode> combined = new TreeSet<>(PriorityComparator.reverse()); TreeSet<LocalizedNode> combined = new TreeSet<>(PriorityComparator.reverse());
Set<Node> enduring = getNodes(); Set<Node> enduring = getNodes();
if (!enduring.isEmpty()) { if (!enduring.isEmpty()) {
combined.addAll(getNodes().stream() combined.addAll(enduring.stream()
.map(n -> makeLocal(n, getObjectName())) .map(n -> makeLocal(n, getObjectName()))
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
} }
Set<Node> tran = getTransientNodes(); Set<Node> tran = getTransientNodes();
if (!tran.isEmpty()) { if (!tran.isEmpty()) {
combined.addAll(getTransientNodes().stream() combined.addAll(transientNodes.stream()
.map(n -> makeLocal(n, getObjectName())) .map(n -> makeLocal(n, getObjectName()))
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
@ -190,46 +190,53 @@ public abstract class PermissionHolder {
*/ */
public boolean auditTemporaryPermissions() { public boolean auditTemporaryPermissions() {
boolean work = false; boolean work = false;
Set<Node> removed = new HashSet<>();
synchronized (nodes) { synchronized (nodes) {
boolean w = false;
Iterator<Node> it = nodes.iterator(); Iterator<Node> it = nodes.iterator();
while (it.hasNext()) { while (it.hasNext()) {
Node entry = it.next(); Node entry = it.next();
if (entry.hasExpired()) { if (entry.hasExpired()) {
plugin.getApiProvider().fireEventAsync(new PermissionNodeExpireEvent(new PermissionHolderLink(this), entry)); removed.add(entry);
w = true; work = true;
it.remove(); it.remove();
} }
} }
}
if (w) { if (work) {
invalidateCache(true); invalidateCache(true);
work = true; work = false;
}
} }
synchronized (transientNodes) { synchronized (transientNodes) {
boolean w = false;
Iterator<Node> it = transientNodes.iterator(); Iterator<Node> it = transientNodes.iterator();
while (it.hasNext()) { while (it.hasNext()) {
Node entry = it.next(); Node entry = it.next();
if (entry.hasExpired()) { if (entry.hasExpired()) {
plugin.getApiProvider().fireEventAsync(new PermissionNodeExpireEvent(new PermissionHolderLink(this), entry)); removed.add(entry);
w = true; work = true;
it.remove(); it.remove();
} }
} }
if (w) {
invalidateCache(false);
work = true;
}
} }
return work; if (work) {
invalidateCache(false);
}
if (removed.isEmpty()) {
return false;
}
PermissionHolderLink link = new PermissionHolderLink(this);
for (Node r : removed) {
plugin.getApiProvider().fireEventAsync(new PermissionNodeExpireEvent(link, r));
}
return true;
} }
/** /**
@ -378,8 +385,8 @@ public abstract class PermissionHolder {
nodes.clear(); nodes.clear();
nodes.addAll(set); nodes.addAll(set);
invalidateCache(true);
} }
invalidateCache(true);
} }
public void setTransientNodes(Set<Node> set) { public void setTransientNodes(Set<Node> set) {
@ -390,28 +397,26 @@ public abstract class PermissionHolder {
transientNodes.clear(); transientNodes.clear();
transientNodes.addAll(set); transientNodes.addAll(set);
invalidateCache(false);
} }
invalidateCache(false);
} }
@Deprecated @Deprecated
public void setNodes(Map<String, Boolean> nodes) { public void setNodes(Map<String, Boolean> nodes) {
synchronized (this.nodes) { Set<Node> set = nodes.entrySet().stream()
this.nodes.clear(); .map(e -> makeNode(e.getKey(), e.getValue()))
this.nodes.addAll(nodes.entrySet().stream() .collect(Collectors.toSet());
.map(e -> makeNode(e.getKey(), e.getValue()))
.collect(Collectors.toList()) setNodes(set);
);
invalidateCache(true);
}
} }
public void addNodeUnchecked(Node node) { public void addNodeUnchecked(Node node) {
synchronized (nodes) { synchronized (nodes) {
if (nodes.add(node)) { if (!nodes.add(node)) {
invalidateCache(true); return;
} }
} }
invalidateCache(true);
} }
/** /**
@ -518,8 +523,8 @@ public abstract class PermissionHolder {
synchronized (nodes) { synchronized (nodes) {
nodes.add(node); nodes.add(node);
invalidateCache(true);
} }
invalidateCache(true);
plugin.getApiProvider().fireEventAsync(new PermissionNodeSetEvent(new PermissionHolderLink(this), node)); plugin.getApiProvider().fireEventAsync(new PermissionNodeSetEvent(new PermissionHolderLink(this), node));
} }
@ -536,8 +541,8 @@ public abstract class PermissionHolder {
synchronized (transientNodes) { synchronized (transientNodes) {
transientNodes.add(node); transientNodes.add(node);
invalidateCache(false);
} }
invalidateCache(false);
plugin.getApiProvider().fireEventAsync(new PermissionNodeSetEvent(new PermissionHolderLink(this), node)); plugin.getApiProvider().fireEventAsync(new PermissionNodeSetEvent(new PermissionHolderLink(this), node));
} }
@ -578,8 +583,8 @@ public abstract class PermissionHolder {
synchronized (nodes) { synchronized (nodes) {
nodes.removeIf(e -> e.almostEquals(node)); nodes.removeIf(e -> e.almostEquals(node));
invalidateCache(true);
} }
invalidateCache(true);
if (node.isGroupNode()) { if (node.isGroupNode()) {
plugin.getApiProvider().fireEventAsync(new GroupRemoveEvent(new PermissionHolderLink(this), plugin.getApiProvider().fireEventAsync(new GroupRemoveEvent(new PermissionHolderLink(this),
@ -601,8 +606,8 @@ public abstract class PermissionHolder {
synchronized (transientNodes) { synchronized (transientNodes) {
transientNodes.removeIf(e -> e.almostEquals(node)); transientNodes.removeIf(e -> e.almostEquals(node));
invalidateCache(false);
} }
invalidateCache(false);
if (node.isGroupNode()) { if (node.isGroupNode()) {
plugin.getApiProvider().fireEventAsync(new GroupRemoveEvent(new PermissionHolderLink(this), plugin.getApiProvider().fireEventAsync(new GroupRemoveEvent(new PermissionHolderLink(this),
@ -732,19 +737,19 @@ public abstract class PermissionHolder {
public void clearNodes() { public void clearNodes() {
synchronized (nodes) { synchronized (nodes) {
nodes.clear(); nodes.clear();
invalidateCache(true);
} }
invalidateCache(true);
} }
public void clearNodes(String server) { public void clearNodes(String server) {
String finalServer = Optional.ofNullable(server).orElse("global"); String finalServer = Optional.ofNullable(server).orElse("global");
synchronized (nodes) { synchronized (nodes) {
boolean b = nodes.removeIf(n -> n.getServer().orElse("global").equalsIgnoreCase(finalServer)); if (!nodes.removeIf(n -> n.getServer().orElse("global").equalsIgnoreCase(finalServer))) {
if (b) { return;
invalidateCache(true);
} }
} }
invalidateCache(true);
} }
public void clearNodes(String server, String world) { public void clearNodes(String server, String world) {
@ -755,10 +760,11 @@ public abstract class PermissionHolder {
boolean b = nodes.removeIf(n -> boolean b = nodes.removeIf(n ->
n.getServer().orElse("global").equalsIgnoreCase(finalServer) && n.getServer().orElse("global").equalsIgnoreCase(finalServer) &&
n.getWorld().orElse("null").equalsIgnoreCase(finalWorld)); n.getWorld().orElse("null").equalsIgnoreCase(finalWorld));
if (b) { if (!b) {
invalidateCache(true); return;
} }
} }
invalidateCache(true);
} }
public void clearParents(String server, String world) { public void clearParents(String server, String world) {
@ -771,19 +777,20 @@ public abstract class PermissionHolder {
n.getServer().orElse("global").equalsIgnoreCase(finalServer) && n.getServer().orElse("global").equalsIgnoreCase(finalServer) &&
n.getWorld().orElse("null").equalsIgnoreCase(finalWorld) n.getWorld().orElse("null").equalsIgnoreCase(finalWorld)
); );
if (b) { if (!b) {
invalidateCache(true); return;
} }
} }
invalidateCache(true);
} }
public void clearMeta() { public void clearMeta() {
synchronized (nodes) { synchronized (nodes) {
boolean b = nodes.removeIf(n -> n.isMeta() || n.isPrefix() || n.isSuffix()); if (!nodes.removeIf(n -> n.isMeta() || n.isPrefix() || n.isSuffix())) {
if (b) { return;
invalidateCache(true);
} }
} }
invalidateCache(true);
} }
public void clearMeta(String server) { public void clearMeta(String server) {
@ -794,10 +801,11 @@ public abstract class PermissionHolder {
(n.isMeta() || n.isPrefix() || n.isSuffix()) && (n.isMeta() || n.isPrefix() || n.isSuffix()) &&
n.getServer().orElse("global").equalsIgnoreCase(finalServer) n.getServer().orElse("global").equalsIgnoreCase(finalServer)
); );
if (b) { if (!b) {
invalidateCache(true); return;
} }
} }
invalidateCache(true);
} }
public void clearMeta(String server, String world) { public void clearMeta(String server, String world) {
@ -811,10 +819,11 @@ public abstract class PermissionHolder {
n.getWorld().orElse("null").equalsIgnoreCase(finalWorld) n.getWorld().orElse("null").equalsIgnoreCase(finalWorld)
) )
); );
if (b) { if (!b) {
invalidateCache(true); return;
} }
} }
invalidateCache(true);
} }
public void clearMetaKeys(String key, String server, String world, boolean temp) { public void clearMetaKeys(String key, String server, String world, boolean temp) {
@ -827,17 +836,18 @@ public abstract class PermissionHolder {
n.getServer().orElse("global").equalsIgnoreCase(finalServer) && n.getServer().orElse("global").equalsIgnoreCase(finalServer) &&
n.getWorld().orElse("null").equalsIgnoreCase(finalWorld) n.getWorld().orElse("null").equalsIgnoreCase(finalWorld)
); );
if (b) { if (!b) {
invalidateCache(true); return;
} }
} }
invalidateCache(true);
} }
public void clearTransientNodes() { public void clearTransientNodes() {
synchronized (transientNodes) { synchronized (transientNodes) {
transientNodes.clear(); transientNodes.clear();
invalidateCache(false);
} }
invalidateCache(false);
} }
/** /**