Micro-optimise some frequently iterated lists

This commit is contained in:
Luck 2021-03-01 10:38:48 +00:00
parent 89894353b6
commit bf0ac1a867
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
9 changed files with 108 additions and 54 deletions

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.bukkit.calculator;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.context.BukkitContextManager;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
@ -42,6 +40,9 @@ import me.lucko.luckperms.common.model.HolderType;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
import java.util.List;
public class BukkitCalculatorFactory implements CalculatorFactory {
private final LPBukkitPlugin plugin;
@ -51,7 +52,7 @@ public class BukkitCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
List<PermissionProcessor> processors = new ArrayList<>(7);
processors.add(new DirectProcessor());
@ -81,6 +82,6 @@ public class BukkitCalculatorFactory implements CalculatorFactory {
processors.add(OpProcessor.INSTANCE);
}
return new PermissionCalculator(this.plugin, metadata, processors.build());
return new PermissionCalculator(this.plugin, metadata, processors);
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.bungee.calculator;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.bungee.LPBungeePlugin;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.calculator.CalculatorFactory;
@ -40,6 +38,9 @@ import me.lucko.luckperms.common.config.ConfigKeys;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
import java.util.List;
public class BungeeCalculatorFactory implements CalculatorFactory {
private final LPBungeePlugin plugin;
@ -49,7 +50,7 @@ public class BungeeCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
List<PermissionProcessor> processors = new ArrayList<>(4);
processors.add(new DirectProcessor());
@ -65,6 +66,6 @@ public class BungeeCalculatorFactory implements CalculatorFactory {
processors.add(new SpongeWildcardProcessor());
}
return new PermissionCalculator(this.plugin, metadata, processors.build());
return new PermissionCalculator(this.plugin, metadata, processors);
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.common.calculator;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.calculator.processor.PermissionProcessor;
@ -37,7 +35,7 @@ import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
@ -53,7 +51,7 @@ public class PermissionCalculator implements Function<String, TristateResult> {
private final CacheMetadata metadata;
/** The processors which back this calculator */
private final ImmutableList<PermissionProcessor> processors;
private final PermissionProcessor[] processors;
/** Loading cache for permission checks */
private final LoadingMap<String, TristateResult> lookupCache = LoadingMap.of(this);
@ -61,10 +59,10 @@ public class PermissionCalculator implements Function<String, TristateResult> {
/** The object name passed to the verbose handler when checks are made */
private final String verboseCheckTarget;
public PermissionCalculator(LuckPermsPlugin plugin, CacheMetadata metadata, ImmutableList<PermissionProcessor> processors) {
public PermissionCalculator(LuckPermsPlugin plugin, CacheMetadata metadata, Collection<PermissionProcessor> processors) {
this.plugin = plugin;
this.metadata = metadata;
this.processors = processors;
this.processors = processors.toArray(new PermissionProcessor[0]);
if (this.metadata.getHolderType() == HolderType.GROUP) {
this.verboseCheckTarget = "group/" + this.metadata.getObjectName();
@ -124,10 +122,6 @@ public class PermissionCalculator implements Function<String, TristateResult> {
}
}
public List<PermissionProcessor> getProcessors() {
return this.processors;
}
public void invalidateCache() {
for (PermissionProcessor processor : this.processors) {
processor.invalidate();

View File

@ -31,6 +31,7 @@ import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.luckperms.api.context.ContextCalculator;
import net.luckperms.api.context.ContextConsumer;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.context.StaticContextCalculator;
@ -38,9 +39,9 @@ import net.luckperms.api.query.QueryOptions;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
/**
@ -54,8 +55,7 @@ public abstract class ContextManager<S, P extends S> {
private final Class<S> subjectClass;
private final Class<P> playerClass;
private final List<ContextCalculator<? super S>> calculators = new CopyOnWriteArrayList<>();
private final List<StaticContextCalculator> staticCalculators = new CopyOnWriteArrayList<>();
private final CalculatorList calculators = new CalculatorList();
// caches static context lookups
private final StaticLookupCache staticLookupCache = new StaticLookupCache();
@ -115,49 +115,47 @@ public abstract class ContextManager<S, P extends S> {
protected abstract void invalidateCache(S subject);
public void registerCalculator(ContextCalculator<? super S> calculator) {
// calculators registered first should have priority (and be checked last.)
this.calculators.add(0, calculator);
if (calculator instanceof StaticContextCalculator) {
StaticContextCalculator staticCalculator = (StaticContextCalculator) calculator;
this.staticCalculators.add(0, staticCalculator);
}
this.calculators.add(calculator);
}
public void unregisterCalculator(ContextCalculator<? super S> calculator) {
this.calculators.remove(calculator);
if (calculator instanceof StaticContextCalculator) {
this.staticCalculators.remove(calculator);
}
}
protected QueryOptions calculate(S subject) {
ImmutableContextSet.Builder accumulator = new ImmutableContextSetImpl.BuilderImpl();
for (ContextCalculator<? super S> calculator : this.calculators) {
ContextConsumer consumer = accumulator::add;
for (ContextCalculator<? super S> calculator : this.calculators.calculators()) {
try {
calculator.calculate(subject, accumulator::add);
calculator.calculate(subject, consumer);
} catch (Throwable e) {
this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating the context of subject " + subject, e);
}
}
return formQueryOptions(subject, accumulator.build());
}
private QueryOptions calculateStatic() {
ImmutableContextSet.Builder accumulator = new ImmutableContextSetImpl.BuilderImpl();
for (StaticContextCalculator calculator : this.staticCalculators) {
ContextConsumer consumer = accumulator::add;
for (StaticContextCalculator calculator : this.calculators.staticCalculators()) {
try {
calculator.calculate(accumulator::add);
calculator.calculate(consumer);
} catch (Throwable e) {
this.plugin.getLogger().warn("An exception was thrown by " + getCalculatorClass(calculator) + " whilst calculating static contexts", e);
}
}
return formQueryOptions(accumulator.build());
}
public ImmutableContextSet getPotentialContexts() {
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
for (ContextCalculator<? super S> calculator : this.calculators) {
for (ContextCalculator<? super S> calculator : this.calculators.calculators()) {
ContextSet potentialContexts;
try {
potentialContexts = calculator.estimatePotentialContexts();
@ -167,6 +165,7 @@ public abstract class ContextManager<S, P extends S> {
}
builder.addAll(potentialContexts);
}
return builder.build();
}
@ -191,4 +190,57 @@ public abstract class ContextManager<S, P extends S> {
return calculatorClass.getName();
}
private final class CalculatorList {
private final List<ContextCalculator<? super S>> calculators;
private final List<StaticContextCalculator> staticCalculators;
private volatile ContextCalculator<? super S>[] calculatorsArray;
private volatile StaticContextCalculator[] staticCalculatorsArray;
CalculatorList() {
this.calculators = new ArrayList<>();
this.staticCalculators = new ArrayList<>();
bake();
}
@SuppressWarnings("unchecked")
private void bake() {
this.calculatorsArray = this.calculators.toArray(new ContextCalculator[0]);
this.staticCalculatorsArray = this.staticCalculators.toArray(new StaticContextCalculator[0]);
}
public void add(ContextCalculator<? super S> calculator) {
synchronized (this) {
// calculators registered first should have priority (and be checked last.)
this.calculators.add(0, calculator);
if (calculator instanceof StaticContextCalculator) {
StaticContextCalculator staticCalculator = (StaticContextCalculator) calculator;
this.staticCalculators.add(0, staticCalculator);
}
bake();
}
}
public void remove(ContextCalculator<? super S> calculator) {
synchronized (this) {
this.calculators.remove(calculator);
if (calculator instanceof StaticContextCalculator) {
this.staticCalculators.remove(calculator);
}
bake();
}
}
public ContextCalculator<? super S>[] calculators() {
return this.calculatorsArray;
}
public StaticContextCalculator[] staticCalculators() {
return this.staticCalculatorsArray;
}
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.fabric;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
@ -41,6 +39,9 @@ import me.lucko.luckperms.fabric.context.FabricContextManager;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
import java.util.List;
public class FabricCalculatorFactory implements CalculatorFactory {
private final LPFabricPlugin plugin;
@ -50,7 +51,7 @@ public class FabricCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
List<PermissionProcessor> processors = new ArrayList<>(5);
processors.add(new DirectProcessor());
@ -71,6 +72,6 @@ public class FabricCalculatorFactory implements CalculatorFactory {
processors.add(new ServerOwnerProcessor());
}
return new PermissionCalculator(this.plugin, metadata, processors.build());
return new PermissionCalculator(this.plugin, metadata, processors);
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.nukkit.calculator;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
@ -42,6 +40,9 @@ import me.lucko.luckperms.nukkit.context.NukkitContextManager;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
import java.util.List;
public class NukkitCalculatorFactory implements CalculatorFactory {
private final LPNukkitPlugin plugin;
@ -51,7 +52,7 @@ public class NukkitCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
List<PermissionProcessor> processors = new ArrayList<>(7);
processors.add(new DirectProcessor());
@ -81,6 +82,6 @@ public class NukkitCalculatorFactory implements CalculatorFactory {
processors.add(OpProcessor.INSTANCE);
}
return new PermissionCalculator(this.plugin, metadata, processors.build());
return new PermissionCalculator(this.plugin, metadata, processors);
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.sponge.calculator;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
@ -41,6 +39,9 @@ import me.lucko.luckperms.sponge.LPSpongePlugin;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
import java.util.List;
public class SpongeCalculatorFactory implements CalculatorFactory {
private final LPSpongePlugin plugin;
@ -50,7 +51,7 @@ public class SpongeCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
List<PermissionProcessor> processors = new ArrayList<>(6);
processors.add(new DirectProcessor());
@ -75,6 +76,6 @@ public class SpongeCalculatorFactory implements CalculatorFactory {
}
}
return new PermissionCalculator(this.plugin, metadata, processors.build());
return new PermissionCalculator(this.plugin, metadata, processors);
}
}

View File

@ -46,6 +46,8 @@ import net.luckperms.api.metastacking.MetaStackDefinition;
import net.luckperms.api.node.ChatMetaType;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.IntFunction;
@ -97,7 +99,7 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
List<PermissionProcessor> processors = new ArrayList<>(4);
processors.add(new DirectProcessor());
processors.add(new SpongeWildcardProcessor());
processors.add(new WildcardProcessor());
@ -106,6 +108,6 @@ public class CalculatedSubjectCachedDataManager extends AbstractCachedDataManage
processors.add(new FixedDefaultsProcessor(this.subject.getService(), queryOptions, this.subject.getDefaults(), true));
}
return new PermissionCalculator(getPlugin(), metadata, processors.build());
return new PermissionCalculator(getPlugin(), metadata, processors);
}
}

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.velocity.calculator;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.common.cacheddata.CacheMetadata;
import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.calculator.PermissionCalculator;
@ -40,6 +38,9 @@ import me.lucko.luckperms.velocity.LPVelocityPlugin;
import net.luckperms.api.query.QueryOptions;
import java.util.ArrayList;
import java.util.List;
public class VelocityCalculatorFactory implements CalculatorFactory {
private final LPVelocityPlugin plugin;
@ -49,7 +50,7 @@ public class VelocityCalculatorFactory implements CalculatorFactory {
@Override
public PermissionCalculator build(QueryOptions queryOptions, CacheMetadata metadata) {
ImmutableList.Builder<PermissionProcessor> processors = ImmutableList.builder();
List<PermissionProcessor> processors = new ArrayList<>(4);
processors.add(new DirectProcessor());
@ -65,6 +66,6 @@ public class VelocityCalculatorFactory implements CalculatorFactory {
processors.add(new SpongeWildcardProcessor());
}
return new PermissionCalculator(this.plugin, metadata, processors.build());
return new PermissionCalculator(this.plugin, metadata, processors);
}
}