mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-10-30 23:39:33 +01:00
Store all accumulated meta values in MetaCache
This commit is contained in:
parent
8766e3b408
commit
e50fa17f7c
@ -25,6 +25,8 @@
|
||||
|
||||
package me.lucko.luckperms.api.caching;
|
||||
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
|
||||
|
||||
import java.util.Map;
|
||||
@ -38,7 +40,24 @@ import java.util.SortedMap;
|
||||
public interface MetaData {
|
||||
|
||||
/**
|
||||
* Gets an immutable copy of the meta this user has
|
||||
* Gets an immutable copy of the meta this user has.
|
||||
*
|
||||
* <p>A list multimap is used because when inherited values are included, each key can be
|
||||
* mapped to multiple values.</p>
|
||||
*
|
||||
* <p>The first value to be accumulated (and used to represent the key in {@link #getMeta()} is at index 0
|
||||
* in the list. Any additional values are stored in order of accumulation.</p>
|
||||
*
|
||||
* @return an immutable multimap of meta
|
||||
* @since 3.3
|
||||
*/
|
||||
ListMultimap<String, String> getMetaMultimap();
|
||||
|
||||
/**
|
||||
* Gets an immutable copy of the meta this user has.
|
||||
*
|
||||
* <p>This map is formed by taking the entries in {@link #getMetaMultimap()}, and mapping each key
|
||||
* to the value at index 0 in the corresponding list.</p>
|
||||
*
|
||||
* @return an immutable map of meta
|
||||
*/
|
||||
|
@ -30,6 +30,9 @@ import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.ToString;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
@ -38,7 +41,6 @@ import me.lucko.luckperms.common.metastacking.MetaStack;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
@ -57,7 +59,7 @@ public class MetaAccumulator {
|
||||
}
|
||||
|
||||
@Getter(AccessLevel.NONE)
|
||||
private final Map<String, String> meta;
|
||||
private final ListMultimap<String, String> meta;
|
||||
private final SortedMap<Integer, String> prefixes;
|
||||
private final SortedMap<Integer, String> suffixes;
|
||||
private int weight = 0;
|
||||
@ -66,7 +68,7 @@ public class MetaAccumulator {
|
||||
private final MetaStack suffixStack;
|
||||
|
||||
public MetaAccumulator(@NonNull MetaStack prefixStack, @NonNull MetaStack suffixStack) {
|
||||
this.meta = new HashMap<>();
|
||||
this.meta = ArrayListMultimap.create();
|
||||
this.prefixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
this.suffixes = new TreeMap<>(Comparator.reverseOrder());
|
||||
this.prefixStack = prefixStack;
|
||||
@ -76,9 +78,7 @@ public class MetaAccumulator {
|
||||
public void accumulateNode(LocalizedNode n) {
|
||||
if (n.isMeta()) {
|
||||
Map.Entry<String, String> entry = n.getMeta();
|
||||
if (!meta.containsKey(entry.getKey())) {
|
||||
meta.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
meta.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
if (n.isPrefix()) {
|
||||
@ -106,7 +106,7 @@ public class MetaAccumulator {
|
||||
|
||||
// We can assume that if this method is being called, this holder is effectively finalized. (it's not going to accumulate more nodes)
|
||||
// Therefore, it should be ok to set the weight meta key, if not already present.
|
||||
public Map<String, String> getMeta() {
|
||||
public ListMultimap<String, String> getMeta() {
|
||||
if (!this.meta.containsKey("weight") && this.weight != 0) {
|
||||
this.meta.put("weight", String.valueOf(this.weight));
|
||||
}
|
||||
|
@ -25,16 +25,20 @@
|
||||
|
||||
package me.lucko.luckperms.common.caching;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSortedMap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
import me.lucko.luckperms.api.caching.MetaData;
|
||||
import me.lucko.luckperms.api.metastacking.MetaStackDefinition;
|
||||
import me.lucko.luckperms.common.metastacking.MetaStack;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
import java.util.concurrent.locks.ReadWriteLock;
|
||||
@ -43,29 +47,38 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
/**
|
||||
* Holds a user's cached meta for a given context
|
||||
*/
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
public class MetaCache implements MetaData {
|
||||
@Getter(AccessLevel.NONE)
|
||||
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
@Getter
|
||||
private ListMultimap<String, String> metaMultimap = ImmutableListMultimap.of();
|
||||
private Map<String, String> meta = ImmutableMap.of();
|
||||
|
||||
@Getter
|
||||
private SortedMap<Integer, String> prefixes = ImmutableSortedMap.of();
|
||||
|
||||
@Getter
|
||||
private SortedMap<Integer, String> suffixes = ImmutableSortedMap.of();
|
||||
|
||||
@Getter
|
||||
private MetaStack prefixStack = null;
|
||||
|
||||
@Getter
|
||||
private MetaStack suffixStack = null;
|
||||
|
||||
public void loadMeta(MetaAccumulator meta) {
|
||||
lock.writeLock().lock();
|
||||
try {
|
||||
this.meta = ImmutableMap.copyOf(meta.getMeta());
|
||||
this.metaMultimap = ImmutableListMultimap.copyOf(meta.getMeta());
|
||||
|
||||
//noinspection unchecked
|
||||
Map<String, List<String>> metaMap = (Map) this.metaMultimap.asMap();
|
||||
ImmutableMap.Builder<String, String> metaMapBuilder = ImmutableMap.builder();
|
||||
|
||||
for (Map.Entry<String, List<String>> e : metaMap.entrySet()) {
|
||||
if (e.getValue().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// take the value which was accumulated first
|
||||
metaMapBuilder.put(e.getKey(), e.getValue().get(0));
|
||||
}
|
||||
this.meta = metaMapBuilder.build();
|
||||
|
||||
this.prefixes = ImmutableSortedMap.copyOfSorted(meta.getPrefixes());
|
||||
this.suffixes = ImmutableSortedMap.copyOfSorted(meta.getSuffixes());
|
||||
this.prefixStack = meta.getPrefixStack();
|
||||
|
@ -30,6 +30,7 @@ import lombok.Getter;
|
||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
import me.lucko.luckperms.api.ChatMetaType;
|
||||
import me.lucko.luckperms.api.LocalizedNode;
|
||||
@ -54,6 +55,7 @@ import org.spongepowered.api.service.permission.PermissionService;
|
||||
|
||||
import co.aikar.timings.Timing;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@ -238,8 +240,9 @@ public class SpongeGroup extends Group {
|
||||
|
||||
private Optional<String> getMeta(ImmutableContextSet contexts, String key) {
|
||||
MetaAccumulator metaAccumulator = parent.accumulateMeta(null, null, ExtractedContexts.generate(plugin.getService().calculateContexts(contexts)));
|
||||
Map<String, String> meta = metaAccumulator.getMeta();
|
||||
return Optional.ofNullable(meta.get(key));
|
||||
ListMultimap<String, String> meta = metaAccumulator.getMeta();
|
||||
List<String> ret = meta.get(key);
|
||||
return ret.isEmpty() ? Optional.empty() : Optional.of(ret.get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user