ContextSet performance improvements (#3209)

A bit experimental, should be stable enough though.
This commit is contained in:
Luck 2021-11-17 23:18:11 +00:00
parent 848fc353d4
commit c9d4c7dac7
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
75 changed files with 523 additions and 287 deletions

View File

@ -119,7 +119,7 @@ public interface ImmutableContextSet extends ContextSet {
}
/**
* Adds of of the contexts in another {@link ContextSet} to the set.
* Adds all the contexts in another {@link ContextSet} to the set.
*
* @param contextSet the set to add from
* @return the builder

View File

@ -94,7 +94,7 @@ public interface MutableContextSet extends ContextSet {
}
/**
* Adds of of the contexts in another {@link ContextSet} to this set.
* Adds all the contexts in another {@link ContextSet} to this set.
*
* @param contextSet the set to add from
* @throws NullPointerException if the contextSet is null

View File

@ -30,8 +30,8 @@ import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.util.CaffeineFactory;
import net.luckperms.api.context.ImmutableContextSet;

View File

@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.util.EnumNamer;
import net.luckperms.api.context.Context;

View File

@ -33,7 +33,7 @@ import me.lucko.luckperms.bukkit.calculator.DefaultsProcessor;
import me.lucko.luckperms.bukkit.calculator.OpProcessor;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;

View File

@ -30,7 +30,7 @@ import com.google.common.base.Strings;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.common.cacheddata.type.MetaAccumulator;
import me.lucko.luckperms.common.cacheddata.type.MetaCache;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.node.types.Meta;

View File

@ -28,8 +28,8 @@ package me.lucko.luckperms.bungee.context;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.bungee.LPBungeePlugin;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.QueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.util.CaffeineFactory;
import net.luckperms.api.context.ImmutableContextSet;

View File

@ -27,7 +27,7 @@ package me.lucko.luckperms.bungee.context;
import me.lucko.luckperms.bungee.LPBungeePlugin;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import net.luckperms.api.context.ContextCalculator;
import net.luckperms.api.context.ContextConsumer;

View File

@ -28,7 +28,7 @@ package me.lucko.luckperms.bungee.context;
import com.imaginarycode.minecraft.redisbungee.RedisBungee;
import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import net.luckperms.api.context.ContextConsumer;
import net.luckperms.api.context.ContextSet;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.api.implementation;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.query.QueryOptionsBuilderImpl;

View File

@ -25,8 +25,8 @@
package me.lucko.luckperms.common.api.implementation;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.contextset.MutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.MutableContextSetImpl;
import net.luckperms.api.context.ContextSetFactory;
import net.luckperms.api.context.ImmutableContextSet;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.api.implementation;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.model.manager.user.UserManager;
import net.luckperms.api.context.ImmutableContextSet;

View File

@ -29,8 +29,8 @@ import com.google.common.collect.ForwardingList;
import me.lucko.luckperms.common.command.abstraction.CommandException;
import me.lucko.luckperms.common.commands.user.UserParentCommand;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.contextset.MutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.MutableContextSetImpl;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.sender.Sender;
import me.lucko.luckperms.common.util.DurationParser;

View File

@ -30,7 +30,7 @@ import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.spec.CommandSpec;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType;

View File

@ -35,7 +35,7 @@ import me.lucko.luckperms.common.command.tabcomplete.TabCompletions;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.command.utils.StorageAssistant;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;

View File

@ -30,7 +30,7 @@ import me.lucko.luckperms.common.command.abstraction.ChildCommand;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.spec.CommandSpec;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.types.Permission;

View File

@ -30,7 +30,7 @@ import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.spec.CommandSpec;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.Track;

View File

@ -30,7 +30,7 @@ import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.spec.CommandSpec;
import me.lucko.luckperms.common.command.utils.ArgumentList;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;

View File

@ -33,7 +33,7 @@ import me.lucko.luckperms.common.cacheddata.type.SimpleMetaValueSelector;
import me.lucko.luckperms.common.config.generic.KeyedConfiguration;
import me.lucko.luckperms.common.config.generic.key.ConfigKey;
import me.lucko.luckperms.common.config.generic.key.SimpleConfigKey;
import me.lucko.luckperms.common.context.WorldNameRewriter;
import me.lucko.luckperms.common.context.calculator.WorldNameRewriter;
import me.lucko.luckperms.common.graph.TraversalAlgorithm;
import me.lucko.luckperms.common.metastacking.SimpleMetaStackDefinition;
import me.lucko.luckperms.common.metastacking.StandardStackElements;

View File

@ -28,8 +28,8 @@ package me.lucko.luckperms.common.config;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.context.ContextSetJsonSerializer;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.serializer.ContextSetJsonSerializer;
import me.lucko.luckperms.common.util.gson.GsonProvider;
import net.luckperms.api.context.ImmutableContextSet;

View File

@ -23,11 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context.contextset;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.SetMultimap;
package me.lucko.luckperms.common.context;
import net.luckperms.api.context.Context;
import net.luckperms.api.context.ContextSatisfyMode;
@ -36,36 +32,11 @@ import net.luckperms.api.context.DefaultContextKeys;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.Spliterator;
public abstract class AbstractContextSet implements ContextSet {
protected abstract SetMultimap<String, String> backing();
protected abstract void copyTo(SetMultimap<String, String> other);
@Override
public boolean containsKey(@NonNull String key) {
return backing().containsKey(sanitizeKey(key));
}
@Override
public @NonNull Set<String> getValues(@NonNull String key) {
Collection<String> values = backing().asMap().get(sanitizeKey(key));
return values != null ? ImmutableSet.copyOf(values) : ImmutableSet.of();
}
@Override
public boolean contains(@NonNull String key, @NonNull String value) {
return backing().containsEntry(sanitizeKey(key), sanitizeValue(value));
}
@Override
public boolean isSatisfiedBy(@NonNull ContextSet other, @NonNull ContextSatisfyMode mode) {
if (this == other) {
@ -96,33 +67,6 @@ public abstract class AbstractContextSet implements ContextSet {
protected abstract boolean otherContainsAll(ContextSet other, ContextSatisfyMode mode);
public abstract Context[] toArray();
@Override
public @NonNull Iterator<Context> iterator() {
return Iterators.forArray(toArray());
}
@Override
public Spliterator<Context> spliterator() {
return Arrays.spliterator(toArray());
}
@Override
public boolean isEmpty() {
return backing().isEmpty();
}
@Override
public int size() {
return backing().size();
}
@Override
public int hashCode() {
return backing().hashCode();
}
static String sanitizeKey(String key) {
Objects.requireNonNull(key, "key is null");
if (!Context.isValidKey(key)) {

View File

@ -23,13 +23,15 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context.contextset;
package me.lucko.luckperms.common.context;
import me.lucko.luckperms.common.context.comparator.ContextComparator;
import net.luckperms.api.context.Context;
import org.checkerframework.checker.nullness.qual.NonNull;
public final class ContextImpl implements Context {
public final class ContextImpl implements Context, Comparable<Context> {
private final String key;
private final String value;
@ -48,6 +50,11 @@ public final class ContextImpl implements Context {
return this.value;
}
@Override
public int compareTo(@NonNull Context o) {
return ContextComparator.INSTANCE.compare(this, o);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Context)) return false;

View File

@ -23,16 +23,15 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context.contextset;
package me.lucko.luckperms.common.context;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import me.lucko.luckperms.common.context.ContextSetComparator;
import me.lucko.luckperms.common.context.comparator.ContextComparator;
import net.luckperms.api.context.Context;
import net.luckperms.api.context.ContextSatisfyMode;
@ -44,12 +43,14 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Spliterator;
public final class ImmutableContextSetImpl extends AbstractContextSet implements ImmutableContextSet {
public static final ImmutableContextSetImpl EMPTY = new ImmutableContextSetImpl(ImmutableSetMultimap.of());
public final class ImmutableContextSetImpl extends AbstractContextSet implements ImmutableContextSet, ContextSet {
public static final ImmutableContextSetImpl EMPTY = new ImmutableContextSetImpl(new Context[0]);
public static ImmutableContextSet of(String key, String value) {
key = sanitizeKey(key);
@ -60,35 +61,19 @@ public final class ImmutableContextSetImpl extends AbstractContextSet implements
return EMPTY;
}
return new ImmutableContextSetImpl(ImmutableSetMultimap.of(key, sanitizeValue(value)));
return new ImmutableContextSetImpl(new Context[]{new ContextImpl(key, value)});
}
private final ImmutableSetMultimap<String, String> map;
private final Context[] array;
private final int size;
private final int hashCode;
ImmutableContextSetImpl(ImmutableSetMultimap<String, String> contexts) {
this.map = contexts;
this.hashCode = this.map.hashCode();
private ImmutableSetMultimap<String, String> cachedMap;
Set<Map.Entry<String, String>> entries = this.map.entries();
this.array = new Context[entries.size()];
int i = 0;
for (Map.Entry<String, String> e : entries) {
this.array[i++] = new ContextImpl(e.getKey(), e.getValue());
}
// sort the array at construction so the comparator doesn't need to
Arrays.sort(this.array, ContextSetComparator.CONTEXT_COMPARATOR);
}
@Override
protected SetMultimap<String, String> backing() {
return this.map;
}
@Override
protected void copyTo(SetMultimap<String, String> other) {
other.putAll(this.map);
ImmutableContextSetImpl(Context[] contexts) {
this.array = contexts; // always sorted
this.size = this.array.length;
this.hashCode = Arrays.hashCode(this.array);
}
@Override
@ -102,9 +87,20 @@ public final class ImmutableContextSetImpl extends AbstractContextSet implements
return this;
}
public ImmutableSetMultimap<String, String> toMultimap() {
if (this.cachedMap == null) {
ImmutableSetMultimap.Builder<String, String> builder = ImmutableSetMultimap.builder();
for (Context entry : this.array) {
builder.put(entry.getKey(), entry.getValue());
}
this.cachedMap = builder.build();
}
return this.cachedMap;
}
@Override
public @NonNull MutableContextSet mutableCopy() {
return new MutableContextSetImpl(this.map);
return new MutableContextSetImpl(toMultimap());
}
@Override
@ -114,22 +110,21 @@ public final class ImmutableContextSetImpl extends AbstractContextSet implements
@Override
public @NonNull Map<String, Set<String>> toMap() {
return Multimaps.asMap(this.map);
return Multimaps.asMap(toMultimap());
}
@Deprecated
@Override
public @NonNull Map<String, String> toFlattenedMap() {
ImmutableMap.Builder<String, String> m = ImmutableMap.builder();
for (Map.Entry<String, String> e : this.map.entries()) {
for (Context e : this.array) {
m.put(e.getKey(), e.getValue());
}
return m.build();
}
@Override
public Context[] toArray() {
return this.array;
return this.array; // only used read-only & internally
}
@Override
@ -137,8 +132,7 @@ public final class ImmutableContextSetImpl extends AbstractContextSet implements
switch (mode) {
// Use other.contains
case ALL_VALUES_PER_KEY: {
Set<Map.Entry<String, String>> entries = this.map.entries();
for (Map.Entry<String, String> e : entries) {
for (Context e : this.array) {
if (!other.contains(e.getKey(), e.getValue())) {
return false;
}
@ -148,12 +142,26 @@ public final class ImmutableContextSetImpl extends AbstractContextSet implements
// Use other.containsAny
case AT_LEAST_ONE_VALUE_PER_KEY: {
Set<Map.Entry<String, Collection<String>>> entries = this.map.asMap().entrySet();
for (Map.Entry<String, Collection<String>> e : entries) {
if (!other.containsAny(e.getKey(), e.getValue())) {
// exploit the ordered nature to only scan through the array once.
Context[] array = this.array;
for (int i = 0, len = array.length; i < len; i++) {
Context e = array[i];
boolean otherContains = other.contains(e.getKey(), e.getValue());
if (otherContains) {
// skip forward past any other entries with the same key
while (i+1 < len && array[i+1].getKey().equals(e.getKey())) {
i++;
}
} else {
// if this is the last one of the key, return false
int next = i + 1;
if (next >= len || !array[next].getKey().equals(e.getKey())) {
return false;
}
}
}
return true;
}
default:
@ -171,21 +179,10 @@ public final class ImmutableContextSetImpl extends AbstractContextSet implements
if (that instanceof ImmutableContextSetImpl) {
ImmutableContextSetImpl immutableThat = (ImmutableContextSetImpl) that;
if (this.hashCode != immutableThat.hashCode) return false;
return Arrays.equals(this.array, immutableThat.array);
}
final Multimap<String, String> thatBacking;
if (that instanceof AbstractContextSet) {
thatBacking = ((AbstractContextSet) that).backing();
} else {
Map<String, Set<String>> thatMap = that.toMap();
ImmutableSetMultimap.Builder<String, String> thatBuilder = ImmutableSetMultimap.builder();
for (Map.Entry<String, Set<String>> e : thatMap.entrySet()) {
thatBuilder.putAll(e.getKey(), e.getValue());
}
thatBacking = thatBuilder.build();
}
return backing().equals(thatBacking);
return this.size() == that.size() && otherContainsAll(that, ContextSatisfyMode.ALL_VALUES_PER_KEY);
}
@Override
@ -195,57 +192,116 @@ public final class ImmutableContextSetImpl extends AbstractContextSet implements
@Override
public String toString() {
return "ImmutableContextSet(contexts=" + this.map + ")";
return "ImmutableContextSet(" + Arrays.toString(this.array) + ")";
}
@Override
public boolean containsKey(@NonNull String key) {
Objects.requireNonNull(key, "key");
return Arrays.binarySearch(this.array, new ContextImpl(key, null), ContextComparator.ONLY_KEY) >= 0;
}
@Override
public @NonNull Set<String> getValues(@NonNull String key) {
Collection<String> values = toMap().get(sanitizeKey(key));
return values != null ? ImmutableSet.copyOf(values) : ImmutableSet.of();
}
@Override
public boolean contains(@NonNull Context entry) {
Objects.requireNonNull(entry, "entry");
return Arrays.binarySearch(this.array, entry) >= 0;
}
@Override
public boolean contains(@NonNull String key, @NonNull String value) {
Objects.requireNonNull(key, "key");
Objects.requireNonNull(value, "value");
return contains(new ContextImpl(key, value));
}
@Override
public @NonNull Iterator<Context> iterator() {
return Iterators.forArray(this.array);
}
@Override
public Spliterator<Context> spliterator() {
return Arrays.spliterator(this.array);
}
@Override
public boolean isEmpty() {
return this.size == 0;
}
@Override
public int size() {
return this.size;
}
public static final class BuilderImpl implements ImmutableContextSet.Builder {
private ImmutableSetMultimap.Builder<String, String> builder;
private static final int INITIAL_SIZE = 16;
private Context[] builder = EMPTY.array;
private int size = 0;
public BuilderImpl() {
}
private synchronized ImmutableSetMultimap.Builder<String, String> builder() {
if (this.builder == null) {
this.builder = ImmutableSetMultimap.builder();
}
return this.builder;
}
private void put(String key, String value) {
// special case for server=global and world=global
if (isGlobalServerWorldEntry(key, value)) {
ContextImpl context = new ContextImpl(key, value);
int pos = Arrays.binarySearch(this.builder, 0, this.size, context);
if (pos >= 0) {
return;
}
builder().put(key, value);
int insertPos = -pos - 1;
Context[] dest;
if (this.builder.length == this.size) {
// grow
dest = new Context[Math.max(this.builder.length * 2, INITIAL_SIZE)];
System.arraycopy(this.builder, 0, dest, 0, insertPos);
} else {
dest = this.builder;
}
System.arraycopy(this.builder, insertPos, dest, insertPos + 1, this.size - insertPos); // shift
dest[insertPos] = context; // insert
this.size++;
this.builder = dest;
}
@Override
public @NonNull BuilderImpl add(@NonNull String key, @NonNull String value) {
put(sanitizeKey(key), sanitizeValue(value));
key = sanitizeKey(key);
value = sanitizeValue(value);
// special case for server=global and world=global
if (isGlobalServerWorldEntry(key, value)) {
return this;
}
put(key, value);
return this;
}
@Override
public @NonNull BuilderImpl addAll(@NonNull ContextSet contextSet) {
Objects.requireNonNull(contextSet, "contextSet");
if (contextSet instanceof AbstractContextSet) {
AbstractContextSet other = (AbstractContextSet) contextSet;
if (!other.isEmpty()) {
builder().putAll(other.backing());
}
} else {
addAll(contextSet.toSet());
}
return this;
}
@Override
public @NonNull ImmutableContextSet build() {
if (this.builder == null) {
if (this.builder.length == 0) {
return EMPTY;
} else {
return new ImmutableContextSetImpl(this.builder.build());
return new ImmutableContextSetImpl(Arrays.copyOf(this.builder, this.size));
}
}
}

View File

@ -23,13 +23,12 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context.contextset;
package me.lucko.luckperms.common.context;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Iterators;
import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
@ -41,12 +40,15 @@ import net.luckperms.api.context.MutableContextSet;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.Spliterator;
public final class MutableContextSetImpl extends AbstractContextSet implements MutableContextSet {
public final class MutableContextSetImpl extends AbstractContextSet implements MutableContextSet, ContextSet {
private final SetMultimap<String, String> map;
public MutableContextSetImpl() {
@ -57,18 +59,6 @@ public final class MutableContextSetImpl extends AbstractContextSet implements M
this.map = Multimaps.synchronizedSetMultimap(HashMultimap.create(other));
}
@Override
protected SetMultimap<String, String> backing() {
return this.map;
}
@Override
protected void copyTo(SetMultimap<String, String> other) {
synchronized (this.map) {
other.putAll(this.map);
}
}
@Override
public boolean isImmutable() {
return false;
@ -80,9 +70,10 @@ public final class MutableContextSetImpl extends AbstractContextSet implements M
if (this.map.isEmpty()) {
return ImmutableContextSetImpl.EMPTY;
}
synchronized (this.map) {
return new ImmutableContextSetImpl(ImmutableSetMultimap.copyOf(this.map));
}
Context[] arr = toArray();
Arrays.sort(arr);
return new ImmutableContextSetImpl(arr);
}
@Override
@ -129,11 +120,10 @@ public final class MutableContextSetImpl extends AbstractContextSet implements M
return builder.build();
}
@Override
public Context[] toArray() {
Set<Map.Entry<String, String>> entries = this.map.entries();
Context[] array;
synchronized (this.map) {
Set<Map.Entry<String, String>> entries = this.map.entries();
array = new Context[entries.size()];
int i = 0;
for (Map.Entry<String, String> e : entries) {
@ -143,6 +133,42 @@ public final class MutableContextSetImpl extends AbstractContextSet implements M
return array;
}
@Override
public boolean containsKey(@NonNull String key) {
return this.map.containsKey(sanitizeKey(key));
}
@Override
public @NonNull Set<String> getValues(@NonNull String key) {
Collection<String> values = this.map.asMap().get(sanitizeKey(key));
return values != null ? ImmutableSet.copyOf(values) : ImmutableSet.of();
}
@Override
public boolean contains(@NonNull String key, @NonNull String value) {
return this.map.containsEntry(sanitizeKey(key), sanitizeValue(value));
}
@Override
public @NonNull Iterator<Context> iterator() {
return Iterators.forArray(toArray());
}
@Override
public Spliterator<Context> spliterator() {
return Arrays.spliterator(toArray());
}
@Override
public boolean isEmpty() {
return this.map.isEmpty();
}
@Override
public int size() {
return this.map.size();
}
@Override
public void add(@NonNull String key, @NonNull String value) {
key = sanitizeKey(key);
@ -159,13 +185,8 @@ public final class MutableContextSetImpl extends AbstractContextSet implements M
@Override
public void addAll(@NonNull ContextSet contextSet) {
Objects.requireNonNull(contextSet, "contextSet");
if (contextSet instanceof AbstractContextSet) {
AbstractContextSet other = (AbstractContextSet) contextSet;
other.copyTo(this.map);
} else {
addAll(contextSet.toSet());
}
}
@Override
public void remove(@NonNull String key, @NonNull String value) {
@ -221,23 +242,16 @@ public final class MutableContextSetImpl extends AbstractContextSet implements M
if (!(o instanceof ContextSet)) return false;
final ContextSet that = (ContextSet) o;
final Multimap<String, String> thatBacking;
if (that instanceof AbstractContextSet) {
thatBacking = ((AbstractContextSet) that).backing();
} else {
Map<String, Set<String>> thatMap = that.toMap();
ImmutableSetMultimap.Builder<String, String> thatBuilder = ImmutableSetMultimap.builder();
for (Map.Entry<String, Set<String>> e : thatMap.entrySet()) {
thatBuilder.putAll(e.getKey(), e.getValue());
}
thatBacking = thatBuilder.build();
return this.size() == that.size() && otherContainsAll(that, ContextSatisfyMode.ALL_VALUES_PER_KEY);
}
return backing().equals(thatBacking);
@Override
public int hashCode() {
return this.map.hashCode();
}
@Override
public String toString() {
return "MutableContextSet(contexts=" + this.map + ")";
return "MutableContextSet(" + this.map + ")";
}
}

View File

@ -23,11 +23,11 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.calculator;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import net.luckperms.api.context.ContextConsumer;
import net.luckperms.api.context.ContextSet;

View File

@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.calculator;
import net.luckperms.api.context.ContextCalculator;

View File

@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.calculator;
import me.lucko.luckperms.common.config.ConfigKeys;

View File

@ -0,0 +1,75 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.context.comparator;
import net.luckperms.api.context.Context;
import java.util.Comparator;
public class ContextComparator implements Comparator<Context> {
public static final ContextComparator INSTANCE = new ContextComparator(false);
public static final ContextComparator ONLY_KEY = new ContextComparator(true);
private final boolean onlyKeys;
public ContextComparator(boolean onlyKeys) {
this.onlyKeys = onlyKeys;
}
@Override
public int compare(Context o1, Context o2) {
if (o1 == o2) {
return 0;
}
int i = compareStringsFast(o1.getKey(), o2.getKey());
if (i != 0) {
return i;
}
if (this.onlyKeys) {
return 0;
}
return compareStringsFast(o1.getValue(), o2.getValue());
}
public int compare(Context o1, String o2Key, String o2Value) {
int i = compareStringsFast(o1.getKey(), o2Key);
if (i != 0) {
return i;
}
return compareStringsFast(o1.getValue(), o2Value);
}
@SuppressWarnings("StringEquality")
private static int compareStringsFast(String o1, String o2) {
return o1 == o2 ? 0 : o1.compareTo(o2);
}
}

View File

@ -23,9 +23,9 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.comparator;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import net.luckperms.api.context.Context;
import net.luckperms.api.context.DefaultContextKeys;
@ -90,7 +90,7 @@ public class ContextSetComparator implements Comparator<ImmutableContextSet> {
Context ent1 = o1Array[i];
Context ent2 = o2Array[i];
result = compareContexts(ent1, ent2);
result = ContextComparator.INSTANCE.compare(ent1, ent2);
if (result != 0) {
return result;
}
@ -99,29 +99,10 @@ public class ContextSetComparator implements Comparator<ImmutableContextSet> {
throw new AssertionError("sets are equal? " + o1 + " - " + o2);
}
public static final Comparator<Context> CONTEXT_COMPARATOR = ContextSetComparator::compareContexts;
private static Context[] toArray(ImmutableContextSet set) {
Context[] array = set.toSet().toArray(new Context[0]);
Arrays.sort(array, CONTEXT_COMPARATOR);
Arrays.sort(array, ContextComparator.INSTANCE);
return array;
}
private static int compareContexts(Context o1, Context o2) {
if (o1 == o2) {
return 0;
}
int i = compareStringsFast(o1.getKey(), o2.getKey());
if (i != 0) {
return i;
}
return compareStringsFast(o1.getValue(), o2.getValue());
}
@SuppressWarnings("StringEquality")
private static int compareStringsFast(String o1, String o2) {
return o1 == o2 ? 0 : o1.compareTo(o2);
}
}

View File

@ -23,11 +23,12 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.manager;
import me.lucko.luckperms.common.cache.ExpiringCache;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.calculator.ForwardingContextCalculator;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.luckperms.api.context.ContextCalculator;

View File

@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.manager;
import me.lucko.luckperms.common.cache.ExpiringCache;

View File

@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.manager;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.query.QueryOptions;

View File

@ -23,12 +23,12 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.serializer;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.contextset.MutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.MutableContextSetImpl;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.MutableContextSet;

View File

@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
package me.lucko.luckperms.common.context.serializer;
import com.google.common.base.Preconditions;
import com.google.gson.Gson;
@ -32,8 +32,8 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.contextset.MutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.MutableContextSetImpl;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.MutableContextSet;

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.common.model.manager.user;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.model.manager.AbstractManager;
import me.lucko.luckperms.common.model.manager.group.GroupManager;

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.common.model.nodemap;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.ContextSetComparator;
import me.lucko.luckperms.common.context.comparator.ContextSetComparator;
import me.lucko.luckperms.common.model.InheritanceOrigin;
import me.lucko.luckperms.common.model.PermissionHolder;
import me.lucko.luckperms.common.model.nodemap.MutateResult.ChangeType;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.node;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.ImmutableContextSet;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.node.comparator;
import me.lucko.luckperms.common.context.ContextSetComparator;
import me.lucko.luckperms.common.context.comparator.ContextSetComparator;
import net.luckperms.api.context.ImmutableContextSet;
import net.luckperms.api.node.Node;

View File

@ -29,7 +29,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.context.ContextSetJsonSerializer;
import me.lucko.luckperms.common.context.serializer.ContextSetJsonSerializer;
import me.lucko.luckperms.common.node.factory.NodeBuilders;
import net.luckperms.api.node.Node;

View File

@ -32,7 +32,7 @@ import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.config.generic.adapter.ConfigurationAdapter;
import me.lucko.luckperms.common.context.ConfigurationContextCalculator;
import me.lucko.luckperms.common.context.calculator.ConfigurationContextCalculator;
import me.lucko.luckperms.common.dependencies.Dependency;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.event.AbstractEventBus;

View File

@ -31,7 +31,7 @@ import me.lucko.luckperms.common.calculator.CalculatorFactory;
import me.lucko.luckperms.common.command.CommandManager;
import me.lucko.luckperms.common.command.abstraction.Command;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.event.EventDispatcher;
import me.lucko.luckperms.common.extension.SimpleExtensionManager;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.query;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import net.luckperms.api.context.ContextSet;
import net.luckperms.api.context.ImmutableContextSet;

View File

@ -28,7 +28,7 @@ package me.lucko.luckperms.common.query;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import net.luckperms.api.context.ContextSatisfyMode;
import net.luckperms.api.context.ContextSet;

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.common.sender;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import net.kyori.adventure.text.Component;

View File

@ -29,8 +29,8 @@ import com.google.common.collect.Iterables;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.context.ContextSetConfigurateSerializer;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.serializer.ContextSetConfigurateSerializer;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType;
import me.lucko.luckperms.common.model.Track;

View File

@ -40,7 +40,7 @@ import com.mongodb.client.model.ReplaceOptions;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.actionlog.LoggedAction;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.context.contextset.MutableContextSetImpl;
import me.lucko.luckperms.common.context.MutableContextSetImpl;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.HolderType;

View File

@ -34,7 +34,7 @@ import me.lucko.luckperms.common.actionlog.LoggedAction;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.bulkupdate.BulkUpdateStatistics;
import me.lucko.luckperms.common.bulkupdate.PreparedStatementBuilder;
import me.lucko.luckperms.common.context.ContextSetJsonSerializer;
import me.lucko.luckperms.common.context.serializer.ContextSetJsonSerializer;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track;
import me.lucko.luckperms.common.model.User;

View File

@ -29,8 +29,8 @@ import com.google.common.base.Preconditions;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.ContextSetJsonSerializer;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.serializer.ContextSetJsonSerializer;
import me.lucko.luckperms.common.http.AbstractHttpClient;
import me.lucko.luckperms.common.http.UnsuccessfulRequestException;
import me.lucko.luckperms.common.locale.Message;

View File

@ -33,7 +33,7 @@ import me.lucko.luckperms.common.actionlog.LoggedAction;
import me.lucko.luckperms.common.command.access.ArgumentPermissions;
import me.lucko.luckperms.common.command.access.CommandPermission;
import me.lucko.luckperms.common.command.utils.StorageAssistant;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.PermissionHolder;

View File

@ -0,0 +1,158 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.context;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import net.luckperms.api.context.Context;
import net.luckperms.api.context.ContextSatisfyMode;
import net.luckperms.api.context.ImmutableContextSet;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.function.Consumer;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class ContextSetTest {
@Test
public void testImmutableBuilder() {
List<Consumer<ImmutableContextSet.Builder>> tests = ImmutableList.of(
builder -> {
builder.add("test", "a");
builder.add("test", "b");
builder.add("test", "c");
},
builder -> {
builder.add("test", "c");
builder.add("test", "b");
builder.add("test", "a");
},
builder -> {
builder.add("test", "b");
builder.add("test", "a");
builder.add("test", "c");
},
builder -> {
builder.add("test", "b");
builder.add("test", "c");
builder.add("test", "a");
},
builder -> {
builder.add("test", "a");
builder.add("test", "a");
builder.add("test", "b");
builder.add("test", "c");
}
);
for (Consumer<ImmutableContextSet.Builder> action : tests) {
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
action.accept(builder);
ImmutableContextSet set = builder.build();
ImmutableSet<Context> expected = ImmutableSet.of(
new ContextImpl("test", "a"),
new ContextImpl("test", "b"),
new ContextImpl("test", "c")
);
assertEquals(expected, set.toSet());
assertEquals(3, set.size());
assertTrue(set.contains("test", "a"));
assertTrue(set.contains("test", "b"));
assertTrue(set.contains("test", "c"));
}
}
@Test
public void testImmutableContains() {
ImmutableContextSet set = new ImmutableContextSetImpl.BuilderImpl()
.add("test", "a")
.add("test", "a")
.add("test", "b")
.add("test", "c")
.build();
assertTrue(set.contains("test", "a"));
assertFalse(set.contains("test", "z"));
assertFalse(set.contains("aaa", "a"));
assertTrue(set.containsKey("test"));
assertFalse(set.containsKey("aaa"));
}
@Test
public void testImmutableContainsAll() {
ImmutableContextSetImpl set = (ImmutableContextSetImpl) new ImmutableContextSetImpl.BuilderImpl()
.add("test", "a")
.add("test", "b")
.add("test", "c")
.add("other", "a")
.add("other", "b")
.build();
List<Consumer<ImmutableContextSet.Builder>> trueTests = ImmutableList.of(
builder -> builder.add("test", "a").add("other", "a"),
builder -> builder.add("test", "b").add("other", "a"),
builder -> builder.add("test", "c").add("other", "a"),
builder -> builder.add("test", "c").add("other", "b")
);
for (Consumer<ImmutableContextSet.Builder> test : trueTests) {
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
test.accept(builder);
assertTrue(set.otherContainsAll(
builder.build(),
ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
);
}
List<Consumer<ImmutableContextSet.Builder>> falseTests = ImmutableList.of(
builder -> builder.add("test", "a").add("other", "z"),
builder -> builder.add("test", "b").add("other", "z"),
builder -> builder.add("test", "b"),
builder -> builder.add("test", "c"),
builder -> {}
);
for (Consumer<ImmutableContextSet.Builder> test : falseTests) {
ImmutableContextSet.Builder builder = new ImmutableContextSetImpl.BuilderImpl();
test.accept(builder);
assertFalse(set.otherContainsAll(
builder.build(),
ContextSatisfyMode.AT_LEAST_ONE_VALUE_PER_KEY)
);
}
}
}

View File

@ -26,8 +26,8 @@
package me.lucko.luckperms.fabric.context;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.fabric.model.MixinUser;

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.fabric.context;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.util.EnumNamer;
import me.lucko.luckperms.fabric.LPFabricPlugin;
import me.lucko.luckperms.fabric.event.PlayerChangeWorldCallback;

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.fabric.mixin;
import me.lucko.luckperms.common.cacheddata.type.PermissionCache;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.fabric.model;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.fabric.context.FabricContextManager;

View File

@ -29,8 +29,8 @@ import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.util.CaffeineFactory;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.nukkit.context;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;
import net.luckperms.api.context.Context;

View File

@ -30,7 +30,7 @@ import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.common.calculator.result.TristateResult;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;
import me.lucko.luckperms.nukkit.LPNukkitPlugin;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.sponge.service.proxy.api6;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.sponge.service.proxy.api6;
import me.lucko.luckperms.common.context.QueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.util.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.CompatibilityUtil;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.sponge.service.proxy.api7;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.sponge.service.proxy.api7;
import me.lucko.luckperms.common.context.QueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.sponge.service.CompatibilityUtil;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;

View File

@ -27,8 +27,8 @@ package me.lucko.luckperms.sponge.service;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.context.contextset.ContextImpl;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ContextImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.sponge.service.context.ForwardingContextSet;
import me.lucko.luckperms.sponge.service.context.ForwardingImmutableContextSet;

View File

@ -28,7 +28,7 @@ package me.lucko.luckperms.sponge.service.model;
import com.google.common.collect.ImmutableCollection;
import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.sponge.service.reference.SubjectReferenceFactory;

View File

@ -27,9 +27,9 @@ package me.lucko.luckperms.sponge.context;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.QueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.util.CaffeineFactory;
import me.lucko.luckperms.sponge.LPSpongePlugin;

View File

@ -26,7 +26,7 @@
package me.lucko.luckperms.sponge.context;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import net.luckperms.api.context.Context;

View File

@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.model.manager.group.AbstractGroupManager;
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;
import me.lucko.luckperms.common.storage.misc.DataConstraints;

View File

@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.model.manager.user.AbstractUserManager;
import me.lucko.luckperms.common.model.manager.user.UserHousekeeper;
import me.lucko.luckperms.common.node.matcher.StandardNodeMatchers;

View File

@ -29,7 +29,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.sponge.LPSpongePlugin;
import me.lucko.luckperms.sponge.model.manager.SpongeGroupManager;

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.sponge.service.model;
import me.lucko.luckperms.common.context.ForwardingContextCalculator;
import me.lucko.luckperms.common.context.calculator.ForwardingContextCalculator;
import net.luckperms.api.context.ContextConsumer;

View File

@ -30,7 +30,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.ContextSetComparator;
import me.lucko.luckperms.common.context.comparator.ContextSetComparator;
import me.lucko.luckperms.sponge.service.ProxyFactory;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubject;

View File

@ -31,7 +31,7 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.common.cache.LoadingMap;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.common.util.ImmutableCollectors;
import me.lucko.luckperms.common.util.Predicates;
import me.lucko.luckperms.sponge.service.LuckPermsService;

View File

@ -32,8 +32,8 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import me.lucko.luckperms.common.context.ContextSetComparator;
import me.lucko.luckperms.common.context.ContextSetJsonSerializer;
import me.lucko.luckperms.common.context.comparator.ContextSetComparator;
import me.lucko.luckperms.common.context.serializer.ContextSetJsonSerializer;
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
import me.lucko.luckperms.sponge.service.model.LPSubjectData;
import me.lucko.luckperms.sponge.service.model.LPSubjectReference;

View File

@ -28,9 +28,9 @@ package me.lucko.luckperms.velocity.context;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.velocitypowered.api.proxy.Player;
import me.lucko.luckperms.common.context.ContextManager;
import me.lucko.luckperms.common.context.QueryOptionsCache;
import me.lucko.luckperms.common.context.QueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.ContextManager;
import me.lucko.luckperms.common.context.manager.QueryOptionsCache;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.util.CaffeineFactory;
import me.lucko.luckperms.velocity.LPVelocityPlugin;

View File

@ -33,7 +33,7 @@ import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.context.contextset.ImmutableContextSetImpl;
import me.lucko.luckperms.common.context.ImmutableContextSetImpl;
import me.lucko.luckperms.velocity.LPVelocityPlugin;
import net.luckperms.api.context.ContextCalculator;

View File

@ -32,7 +32,7 @@ import com.velocitypowered.api.permission.PermissionSubject;
import com.velocitypowered.api.permission.Tristate;
import com.velocitypowered.api.proxy.Player;
import me.lucko.luckperms.common.context.QueryOptionsSupplier;
import me.lucko.luckperms.common.context.manager.QueryOptionsSupplier;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.verbose.event.PermissionCheckEvent;