Performance Improvements (#340)

* Performance Improvements

* More Optimizations

* Even More Optimizations & Cleanups

* Almost a recode I guess
This commit is contained in:
Crypto Morin
2020-07-16 09:32:22 -07:00
committed by GitHub
parent f9f59f1f96
commit 54d5757d0a
52 changed files with 876 additions and 875 deletions

View File

@@ -20,14 +20,13 @@
*/
package me.clip.placeholderapi;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import me.clip.placeholderapi.events.ExpansionRegisterEvent;
import me.clip.placeholderapi.events.ExpansionUnregisterEvent;
import me.clip.placeholderapi.expansion.Cacheable;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import me.clip.placeholderapi.expansion.Relational;
import me.clip.placeholderapi.util.Msg;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
@@ -35,18 +34,17 @@ import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static me.clip.placeholderapi.util.Msg.color;
public class PlaceholderAPI {
private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
protected static final Map<String, PlaceholderHook> PLACEHOLDERS = new ConcurrentHashMap<>();
private static final Pattern PERCENT_PLACEHOLDER_PATTERN = Pattern.compile("[%]([^%]+)[%]");
private static final Pattern BRACKET_PLACEHOLDER_PATTERN = Pattern.compile("[{]([^{}]+)[}]");
private static final Pattern RELATIONAL_PLACEHOLDER_PATTERN = Pattern.compile("[%](rel_)([^%]+)[%]");
private static final Map<String, PlaceholderHook> placeholders = new HashMap<>();
private PlaceholderAPI() {
}
@@ -58,9 +56,7 @@ public class PlaceholderAPI {
* @return true if identifier is already registered
*/
public static boolean isRegistered(String identifier) {
return getRegisteredIdentifiers().stream()
.filter(id -> id.equalsIgnoreCase(identifier))
.findFirst().orElse(null) != null;
return PLACEHOLDERS.containsKey(identifier.toLowerCase(Locale.ENGLISH));
}
/**
@@ -73,15 +69,11 @@ public class PlaceholderAPI {
* registered for the specified identifier
*/
public static boolean registerPlaceholderHook(String identifier, PlaceholderHook placeholderHook) {
Validate.notNull(identifier, "Identifier can not be null");
Validate.notNull(placeholderHook, "Placeholderhook can not be null");
if (isRegistered(identifier)) {
return false;
}
placeholders.put(identifier.toLowerCase(), placeholderHook);
Validate.notEmpty(identifier, "Placeholder identifier cannot be null or empty");
Objects.requireNonNull(placeholderHook, "Placeholder hook cannot be null");
if (isRegistered(identifier)) return false;
PLACEHOLDERS.put(identifier.toLowerCase(Locale.ENGLISH), placeholderHook);
return true;
}
@@ -93,8 +85,8 @@ public class PlaceholderAPI {
* placeholder hook registered for the identifier specified
*/
public static boolean unregisterPlaceholderHook(String identifier) {
Validate.notNull(identifier, "Identifier can not be null");
return placeholders.remove(identifier.toLowerCase()) != null;
Validate.notEmpty(identifier, "Identifier cannot be null");
return PLACEHOLDERS.remove(identifier.toLowerCase(Locale.ENGLISH)) != null;
}
/**
@@ -103,7 +95,7 @@ public class PlaceholderAPI {
* @return All registered placeholder identifiers
*/
public static Set<String> getRegisteredIdentifiers() {
return ImmutableSet.copyOf(placeholders.keySet());
return ImmutableSet.copyOf(PLACEHOLDERS.keySet());
}
/**
@@ -112,15 +104,16 @@ public class PlaceholderAPI {
* @return Copy of the internal placeholder map
*/
public static Map<String, PlaceholderHook> getPlaceholders() {
return ImmutableMap.copyOf(placeholders);
return ImmutableMap.copyOf(PLACEHOLDERS);
}
public static Set<PlaceholderExpansion> getExpansions() {
Set<PlaceholderExpansion> set = getPlaceholders().values().stream()
.filter(PlaceholderExpansion.class::isInstance).map(PlaceholderExpansion.class::cast)
.collect(Collectors.toCollection(HashSet::new));
Set<PlaceholderExpansion> expansions = new HashSet<>();
for (PlaceholderHook expansion : PLACEHOLDERS.values()) {
if (expansion.isExpansion()) expansions.add((PlaceholderExpansion) expansion);
}
return ImmutableSet.copyOf(set);
return ImmutableSet.copyOf(expansions);
}
/**
@@ -130,7 +123,7 @@ public class PlaceholderAPI {
* @return true if String contains any registered placeholder identifiers, false otherwise
*/
public static boolean containsPlaceholders(String text) {
return text != null && PLACEHOLDER_PATTERN.matcher(text).find();
return !Strings.isNullOrEmpty(text) && PERCENT_PLACEHOLDER_PATTERN.matcher(text).find();
}
/**
@@ -140,7 +133,7 @@ public class PlaceholderAPI {
* @return true if String contains any registered placeholder identifiers, false otherwise
*/
public static boolean containsBracketPlaceholders(String text) {
return text != null && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find();
return !Strings.isNullOrEmpty(text) && BRACKET_PLACEHOLDER_PATTERN.matcher(text).find();
}
/**
@@ -177,7 +170,7 @@ public class PlaceholderAPI {
* @return String containing all translated placeholders
*/
public static List<String> setPlaceholders(OfflinePlayer player, List<String> text) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true);
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true);
}
/**
@@ -190,7 +183,7 @@ public class PlaceholderAPI {
* @return String containing all translated placeholders
*/
public static List<String> setPlaceholders(OfflinePlayer player, List<String> text, boolean colorize) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize);
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize);
}
/**
@@ -219,13 +212,13 @@ public class PlaceholderAPI {
* @return String containing all translated placeholders
*/
public static List<String> setPlaceholders(OfflinePlayer player, List<String> text, Pattern pattern, boolean colorize) {
if (text == null) {
return null;
}
if (text == null) return null;
List<String> lines = new ArrayList<>();
return text.stream()
.map(line -> setPlaceholders(player, line, pattern, colorize))
.collect(Collectors.toList());
for (String line : text) {
lines.add(setPlaceholders(player, line, pattern, colorize));
}
return lines;
}
/**
@@ -262,7 +255,7 @@ public class PlaceholderAPI {
* @return String containing all translated placeholders
*/
public static String setPlaceholders(OfflinePlayer player, String text) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN);
return PlaceholderReplacer.evaluatePlaceholders(player, text, PlaceholderReplacer.Closure.PERCENT, false);
}
/**
@@ -275,7 +268,7 @@ public class PlaceholderAPI {
* @return The text containing the parsed placeholders
*/
public static String setPlaceholders(OfflinePlayer player, String text, boolean colorize) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize);
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize);
}
/**
@@ -304,43 +297,51 @@ public class PlaceholderAPI {
* @return The text containing the parsed placeholders
*/
public static String setPlaceholders(OfflinePlayer player, String text, Pattern pattern, boolean colorize) {
if (text == null) {
return null;
}
if (placeholders.isEmpty()) {
return colorize ? color(text) : text;
}
final Matcher matcher = pattern.matcher(text);
final Map<String, PlaceholderHook> hooks = getPlaceholders();
if (text == null) return null;
if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text;
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
final String format = matcher.group(1);
final int index = format.indexOf("_");
String format = matcher.group(1);
int index = format.indexOf('_');
if (index <= 0 || index >= format.length()) continue;
if (index <= 0 || index >= format.length()) {
continue;
}
// We don't need to use getPlaceholders() because we know what we're doing and we won't modify the map.
// And instead of looking for the element twice using contains() and get() we only get it and check if it's null.
String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH);
PlaceholderHook handler = PLACEHOLDERS.get(identifier);
final String identifier = format.substring(0, index).toLowerCase();
final String params = format.substring(index + 1);
final PlaceholderHook hook = hooks.get(identifier);
if (handler != null) {
String params = format.substring(index + 1);
String value = handler.onRequest(player, params);
if (hook == null) {
continue;
}
final String value = hook.onRequest(player, params);
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
}
}
}
return colorize ? color(text) : text;
}
/**
* Optimized version of {@link #setPlaceholders(OfflinePlayer, String, Pattern, boolean)}
*
* @param player player to parse the placeholders against.
* @param text the text to translate.
* @param closure the closing points of a placeholder. %, {, [ etc...
* @param colorize if we should colorize this text using the common & symbol.
* @return the translated text.
*/
public static String setPlaceholders(OfflinePlayer player, String text, PlaceholderReplacer.Closure closure, boolean colorize) {
if (text == null) return null;
if (text.isEmpty()) return "";
if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text;
// We don't want to dirty our class.
return PlaceholderReplacer.evaluatePlaceholders(player, text, closure, colorize);
}
/**
* Translate placeholders in the provided List based on the relation of the two provided players.
* <br>The pattern of a valid placeholder is {@literal %rel_<identifier>_<param>%}.
@@ -365,13 +366,12 @@ public class PlaceholderAPI {
* @return The text containing the parsed relational placeholders
*/
public static List<String> setRelationalPlaceholders(Player one, Player two, List<String> text, boolean colorize) {
if (text == null) {
return null;
if (text == null) return null;
List<String> lines = new ArrayList<>();
for (String line : text) {
lines.add(setRelationalPlaceholders(one, two, line, colorize));
}
return text.stream()
.map(line -> setRelationalPlaceholders(one, two, line, colorize))
.collect(Collectors.toList());
return lines;
}
/**
@@ -397,43 +397,31 @@ public class PlaceholderAPI {
* @param colorize If color codes (&[0-1a-fk-o]) should be translated
* @return The text containing the parsed relational placeholders
*/
@SuppressWarnings("DuplicatedCode")
public static String setRelationalPlaceholders(Player one, Player two, String text, boolean colorize) {
if (text == null) {
return null;
}
if (placeholders.isEmpty()) {
return colorize ? Msg.color(text) : text;
}
final Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text);
final Map<String, PlaceholderHook> hooks = getPlaceholders();
if (text == null) return null;
if (PLACEHOLDERS.isEmpty()) return colorize ? color(text) : text;
Matcher matcher = RELATIONAL_PLACEHOLDER_PATTERN.matcher(text);
while (matcher.find()) {
final String format = matcher.group(2);
final int index = format.indexOf("_");
String format = matcher.group(2);
int index = format.indexOf('_');
if (index <= 0 || index >= format.length()) continue;
if (index <= 0 || index >= format.length()) {
continue;
}
String identifier = format.substring(0, index).toLowerCase(Locale.ENGLISH);
PlaceholderHook handler = PLACEHOLDERS.get(identifier);
String identifier = format.substring(0, index).toLowerCase();
String params = format.substring(index + 1);
final PlaceholderHook hook = hooks.get(identifier);
if (handler.isRelational()) {
Relational relational = (Relational) handler;
String params = format.substring(index + 1);
String value = relational.onPlaceholderRequest(one, two, params);
if (!(hook instanceof Relational)) {
continue;
}
final String value = ((Relational) hook).onPlaceholderRequest(one, two, params);
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
if (value != null) {
text = text.replaceAll(Pattern.quote(matcher.group()), Matcher.quoteReplacement(value));
}
}
}
return colorize ? Msg.color(text) : text;
return colorize ? color(text) : text;
}
/**
@@ -441,43 +429,34 @@ public class PlaceholderAPI {
*/
protected static void unregisterAll() {
unregisterAllProvidedExpansions();
placeholders.clear();
PLACEHOLDERS.clear();
}
/**
* Unregister all expansions provided by PlaceholderAPI
*/
public static void unregisterAllProvidedExpansions() {
final Set<PlaceholderHook> set = new HashSet<>(placeholders.values());
if (PLACEHOLDERS.isEmpty()) return;
for (PlaceholderHook hook : set) {
if (hook instanceof PlaceholderExpansion) {
final PlaceholderExpansion expansion = (PlaceholderExpansion) hook;
if (!expansion.persist()) {
unregisterExpansion(expansion);
}
}
if (hook instanceof Cacheable) {
((Cacheable) hook).clear();
for (PlaceholderHook handler : PLACEHOLDERS.values()) {
if (handler.isExpansion()) {
PlaceholderExpansion expansion = (PlaceholderExpansion) handler;
if (!expansion.persist()) unregisterExpansion(expansion);
}
}
}
public static boolean registerExpansion(PlaceholderExpansion ex) {
ExpansionRegisterEvent ev = new ExpansionRegisterEvent(ex);
Bukkit.getPluginManager().callEvent(ev);
if (ev.isCancelled()) {
return false;
}
public static boolean registerExpansion(PlaceholderExpansion expansion) {
ExpansionRegisterEvent event = new ExpansionRegisterEvent(expansion);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) return false;
return registerPlaceholderHook(ex.getIdentifier(), ex);
return registerPlaceholderHook(expansion.getIdentifier(), expansion);
}
public static boolean unregisterExpansion(PlaceholderExpansion ex) {
if (unregisterPlaceholderHook(ex.getIdentifier())) {
Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(ex));
public static boolean unregisterExpansion(PlaceholderExpansion expansion) {
if (unregisterPlaceholderHook(expansion.getIdentifier())) {
Bukkit.getPluginManager().callEvent(new ExpansionUnregisterEvent(expansion));
return true;
}
@@ -490,7 +469,7 @@ public class PlaceholderAPI {
* @return The pattern for {@literal %<identifier>_<params>%}
*/
public static Pattern getPlaceholderPattern() {
return PLACEHOLDER_PATTERN;
return PERCENT_PLACEHOLDER_PATTERN;
}
/**
@@ -532,19 +511,19 @@ public class PlaceholderAPI {
}
public static String setPlaceholders(Player player, String text) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true);
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true);
}
public static String setPlaceholders(Player player, String text, boolean colorize) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize);
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize);
}
public static List<String> setPlaceholders(Player player, List<String> text) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, true);
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, true);
}
public static List<String> setPlaceholders(Player player, List<String> text, boolean colorize) {
return setPlaceholders(player, text, PLACEHOLDER_PATTERN, colorize);
return setPlaceholders(player, text, PERCENT_PLACEHOLDER_PATTERN, colorize);
}
public static String setBracketPlaceholders(Player player, String text) {