A few small optimizations

This commit is contained in:
Luck 2016-10-24 18:48:39 +01:00
parent 9894e45516
commit a9b6493091
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
5 changed files with 59 additions and 52 deletions

View File

@ -71,11 +71,11 @@ public class WorldCalculator extends ContextCalculator<Player> implements Listen
private String getWorld(Player player) { private String getWorld(Player player) {
UUID internal = plugin.getUuidCache().getUUID(player.getUniqueId()); UUID internal = plugin.getUuidCache().getUUID(player.getUniqueId());
if (!worldCache.containsKey(internal)) { String world = worldCache.get(internal);
if (world == null) {
return null; return null;
} }
String world = worldCache.get(internal);
return plugin.getConfiguration().getWorldRewrites().getOrDefault(world, world); return plugin.getConfiguration().getWorldRewrites().getOrDefault(world, world);
} }

View File

@ -39,7 +39,10 @@ public class RegexProcessor implements PermissionProcessor {
@Override @Override
public Tristate hasPermission(String permission) { public Tristate hasPermission(String permission) {
for (Map.Entry<String, Boolean> e : map.entrySet()) { for (Map.Entry<String, Boolean> e : map.entrySet()) {
if (e.getKey().toLowerCase().startsWith("r=")) { if (!e.getKey().startsWith("r=") && !e.getKey().startsWith("R=")) {
continue;
}
Pattern p = Patterns.compile(e.getKey().substring(2)); Pattern p = Patterns.compile(e.getKey().substring(2));
if (p == null) { if (p == null) {
continue; continue;
@ -49,7 +52,6 @@ public class RegexProcessor implements PermissionProcessor {
return Tristate.fromBoolean(e.getValue()); return Tristate.fromBoolean(e.getValue());
} }
} }
}
return Tristate.UNDEFINED; return Tristate.UNDEFINED;
} }

View File

@ -22,16 +22,30 @@
package me.lucko.luckperms.common.constants; package me.lucko.luckperms.common.constants;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.experimental.UtilityClass; import lombok.experimental.UtilityClass;
import java.util.Map; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@UtilityClass @UtilityClass
public class Patterns { public class Patterns {
private static final Map<String, Pattern> CACHE = new ConcurrentHashMap<>(); private static final LoadingCache<String, Pattern> CACHE = CacheBuilder.newBuilder()
.build(new CacheLoader<String, Pattern>() {
@Override
public Pattern load(String s) throws Exception {
return Pattern.compile(s);
}
@Override
public ListenableFuture<Pattern> reload(String s, Pattern pattern) {
return Futures.immediateFuture(pattern);
}
});
public static final Pattern COMMAND_SEPARATOR = Pattern.compile(" (?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)"); public static final Pattern COMMAND_SEPARATOR = Pattern.compile(" (?=([^\\\"]*\\\"[^\\\"]*\\\")*[^\\\"]*$)");
public static final Pattern NON_ALPHA_NUMERIC = Pattern.compile("[\\/\\$\\.\\- ]"); public static final Pattern NON_ALPHA_NUMERIC = Pattern.compile("[\\/\\$\\.\\- ]");
@ -42,14 +56,8 @@ public class Patterns {
public static Pattern compile(String regex) { public static Pattern compile(String regex) {
try { try {
return CACHE.computeIfAbsent(regex, s -> { return CACHE.get(regex);
try { } catch (ExecutionException e) {
return Pattern.compile(regex);
} catch (PatternSyntaxException e) {
return null;
}
});
} catch (NullPointerException e) {
return null; return null;
} }
} }

View File

@ -112,11 +112,8 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
* Removes the UserData cache from this user * Removes the UserData cache from this user
*/ */
public void unregisterData() { public void unregisterData() {
if (userData != null) {
userData.invalidateCache();
userData = null; userData = null;
} }
}
/** /**
* Refresh and re-assign the users permissions * Refresh and re-assign the users permissions

View File

@ -22,9 +22,14 @@
package me.lucko.luckperms.common.utils; package me.lucko.luckperms.common.utils;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
@ -34,14 +39,23 @@ import java.util.function.Function;
* @param <T> the class this manager is "managing" * @param <T> the class this manager is "managing"
*/ */
public abstract class AbstractManager<I, T extends Identifiable<I>> implements Function<I, T> { public abstract class AbstractManager<I, T extends Identifiable<I>> implements Function<I, T> {
private final Map<I, T> objects = new HashMap<>();
private final LoadingCache<I, T> objects = CacheBuilder.newBuilder()
.removalListener((RemovalListener<I, T>) removal -> preUnload(removal.getValue()))
.build(new CacheLoader<I, T>() {
@Override
public T load(I i) {
return apply(i);
}
@Override
public ListenableFuture<T> reload(I i, T t) {
return Futures.immediateFuture(t); // Never needs to be refreshed.
}
});
public final Map<I, T> getAll() { public final Map<I, T> getAll() {
Map<I, T> map; return ImmutableMap.copyOf(objects.asMap());
synchronized (objects) {
map = ImmutableMap.copyOf(objects);
}
return map;
} }
/** /**
@ -50,9 +64,7 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements F
* @return a {@link T} object if the object is loaded or makes and returns a new object * @return a {@link T} object if the object is loaded or makes and returns a new object
*/ */
public final T getOrMake(I id) { public final T getOrMake(I id) {
synchronized (objects) { return objects.getUnchecked(id);
return objects.computeIfAbsent(id, this);
}
} }
/** /**
@ -61,9 +73,7 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements F
* @return a {@link T} object if the object is loaded, returns null if the object is not loaded * @return a {@link T} object if the object is loaded, returns null if the object is not loaded
*/ */
public final T get(I id) { public final T get(I id) {
synchronized (objects) { return objects.asMap().get(id);
return objects.get(id);
}
} }
/** /**
@ -72,9 +82,7 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements F
* @return true if the object is loaded * @return true if the object is loaded
*/ */
public final boolean isLoaded(I id) { public final boolean isLoaded(I id) {
synchronized (objects) { return objects.asMap().containsKey(id);
return objects.containsKey(id);
}
} }
/** /**
@ -83,12 +91,7 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements F
*/ */
public final void unload(T t) { public final void unload(T t) {
if (t != null) { if (t != null) {
synchronized (objects) { objects.invalidate(t);
objects.computeIfPresent(t.getId(), (i, t1) -> {
preUnload(t1);
return null;
});
}
} }
} }
@ -100,10 +103,7 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> implements F
* Unloads all objects from the manager * Unloads all objects from the manager
*/ */
public final void unloadAll() { public final void unloadAll() {
synchronized (objects) { objects.invalidateAll();
objects.values().forEach(this::preUnload);
objects.clear();
}
} }
} }