Improved the StatResult by working with record hashCode instead of UUID

This commit is contained in:
Artemis-the-gr8 2022-07-28 00:55:58 +02:00
parent 3a542ec72a
commit 2b73e4f183
9 changed files with 37 additions and 45 deletions

View File

@ -13,7 +13,6 @@ import java.time.Instant;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
@ -28,9 +27,9 @@ public final class ShareManager {
private static int waitingTime;
private static volatile AtomicInteger resultID;
private static ConcurrentHashMap<UUID, StatResult> statResultQueue;
private static ConcurrentHashMap<Integer, StatResult> statResultQueue;
private static ConcurrentHashMap<String, Instant> shareTimeStamp;
private static ArrayBlockingQueue<UUID> sharedResults;
private static ArrayBlockingQueue<Integer> sharedResults;
public ShareManager(ConfigHandler config) {
updateSettings(config);
@ -69,13 +68,14 @@ public final class ShareManager {
return !(sender instanceof ConsoleCommandSender) && sender.hasPermission("playerstats.share");
}
public UUID saveStatResult(String playerName, TextComponent statResult) {
public int saveStatResult(String playerName, TextComponent statResult) {
removeExcessResults(playerName);
int ID = getNextIDNumber();
UUID shareCode = UUID.randomUUID();
statResultQueue.put(shareCode, new StatResult(playerName, statResult, ID, shareCode));
//UUID shareCode = UUID.randomUUID();
StatResult result = new StatResult(playerName, statResult, ID);
int shareCode = result.hashCode();
statResultQueue.put(shareCode, result);
MyLogger.logMsg("Saving statResults with no. " + ID, DebugLevel.MEDIUM);
return shareCode;
}
@ -89,25 +89,25 @@ public final class ShareManager {
}
}
public boolean requestAlreadyShared(UUID shareCode) {
public boolean requestAlreadyShared(int shareCode) {
return sharedResults.contains(shareCode);
}
/** Takes a statResult from the internal ConcurrentHashmap,
puts the current time in the shareTimeStamp (ConcurrentHashMap),
puts the shareCode (UUID) in the sharedResults (ArrayBlockingQueue),
puts the shareCode (int hashCode) in the sharedResults (ArrayBlockingQueue),
and returns the statResult. If no statResult was found, returns null.*/
public @Nullable StatResult getStatResult(String playerName, UUID shareCode) {
public @Nullable StatResult getStatResult(String playerName, int shareCode) {
if (statResultQueue.containsKey(shareCode)) {
shareTimeStamp.put(playerName, Instant.now());
if (!sharedResults.offer(shareCode)) { //create a new ArrayBlockingQueue if our queue is full
MyLogger.logMsg("500 stat-results have been shared, " +
"creating a new internal queue with the most recent 50 share-code-values and discarding the rest...", DebugLevel.MEDIUM);
ArrayBlockingQueue<UUID> newQueue = new ArrayBlockingQueue<>(500);
ArrayBlockingQueue<Integer> newQueue = new ArrayBlockingQueue<>(500);
synchronized (this) { //put the last 50 values in the new Queue
UUID[] lastValues = sharedResults.toArray(new UUID[0]);
Integer[] lastValues = sharedResults.toArray(new Integer[500]);
Arrays.stream(Arrays.copyOfRange(lastValues, 450, 500))
.parallel().iterator()
.forEachRemaining(newQueue::offer);
@ -128,16 +128,16 @@ public final class ShareManager {
private void removeExcessResults(String playerName) {
List<StatResult> alreadySavedResults = statResultQueue.values()
.parallelStream()
.filter(result -> result.playerName().equalsIgnoreCase(playerName))
.filter(result -> result.executorName().equalsIgnoreCase(playerName))
.toList();
if (alreadySavedResults.size() > 25) {
UUID uuid = alreadySavedResults
int hashCode = alreadySavedResults
.parallelStream()
.min(Comparator.comparing(StatResult::ID))
.orElseThrow().uuid();
MyLogger.logMsg("Removing old stat no. " + statResultQueue.get(uuid).ID() + " for player " + playerName, DebugLevel.MEDIUM);
statResultQueue.remove(uuid);
.orElseThrow().hashCode();
MyLogger.logMsg("Removing old stat no. " + statResultQueue.get(hashCode).ID() + " for player " + playerName, DebugLevel.MEDIUM);
statResultQueue.remove(hashCode);
}
}

View File

@ -8,7 +8,6 @@ import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatManager;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatThread;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import org.bukkit.command.CommandSender;
import java.util.HashMap;

View File

@ -10,8 +10,6 @@ import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public class ShareCommand implements CommandExecutor {
private static ShareManager shareManager;
@ -25,11 +23,11 @@ public class ShareCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) {
if (args.length == 1 && ShareManager.isEnabled()) {
UUID shareCode;
int shareCode;
try {
shareCode = UUID.fromString(args[0]);
shareCode = Integer.parseInt(args[0]);
} catch (IllegalArgumentException e) {
MyLogger.logException(e, "ShareCommand", "/statshare is being called without a valid UUID argument");
MyLogger.logException(e, "ShareCommand", "/statshare is being called without a valid share-code!");
return false;
}
if (shareManager.requestAlreadyShared(shareCode)) {

View File

@ -35,8 +35,8 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
//args[0] = statistic (length = 1)
//args[1] = commandOption (top/player/me) OR substatistic (block/item/entitytype) (length = 2)
//args[2] = playerName OR commandOption (top/player/me) (length = 3)
//args[3] = playerName (length = 4)
//args[2] = executorName OR commandOption (top/player/me) (length = 3)
//args[3] = executorName (length = 4)
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {

View File

@ -126,7 +126,7 @@ public class StatRequest {
/** For internal use. The "player" arg is a special case, because it could either be
a valid <code>subStatEntry</code>, or indicate that the lookup action should target
a specific player. This is why the <code>playerFlag</code> exists - if this flag true,
and <code>playerName</code> is null, the <code>subStatEntry</code> should be set to "player". */
and <code>executorName</code> is null, the <code>subStatEntry</code> should be set to "player". */
public boolean getPlayerFlag() {
return playerFlag;
}

View File

@ -2,8 +2,6 @@ package com.gmail.artemis.the.gr8.playerstats.models;
import net.kyori.adventure.text.TextComponent;
import java.util.UUID;
/** This Record is used to store stat-results internally, so Players can share them by clicking a share-button.*/
public record StatResult(String playerName, TextComponent statResult, int ID, UUID uuid) {
public record StatResult(String executorName, TextComponent statResult, int ID) {
}

View File

@ -166,10 +166,10 @@ public class MessageBuilder {
/** Returns a BiFunction for a player statistic. This BiFunction will return a statResult,
the shape of which is determined by the 2 parameters the BiFunction gets.
<p>- UUID shareCode: if a shareCode is provided, a clickable "share" button will be added.
<p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added.
<br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br>
<br>- If both parameters are null, the statResult will be returned as is.</br>*/
public BiFunction<UUID, CommandSender, TextComponent> formattedPlayerStatFunction(int stat, @NotNull StatRequest request) {
public BiFunction<Integer, CommandSender, TextComponent> formattedPlayerStatFunction(int stat, @NotNull StatRequest request) {
TextComponent playerStat = Component.text()
.append(componentFactory.playerName(request.getPlayerName(), Target.PLAYER)
.append(text(":"))
@ -185,10 +185,10 @@ public class MessageBuilder {
/** Returns a BiFunction for a server statistic. This BiFunction will return a statResult,
the shape of which is determined by the 2 parameters the BiFunction gets.
<p>- UUID shareCode: if a shareCode is provided, a clickable "share" button will be added.
<p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added.
<br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br>
<br>- If both parameters are null, the statResult will be returned as is.</br>*/
public BiFunction<UUID, CommandSender, TextComponent> formattedServerStatFunction(long stat, @NotNull StatRequest request) {
public BiFunction<Integer, CommandSender, TextComponent> formattedServerStatFunction(long stat, @NotNull StatRequest request) {
TextComponent serverStat = text()
.append(componentFactory.title(config.getServerTitle(), Target.SERVER))
.append(space())
@ -205,10 +205,10 @@ public class MessageBuilder {
/** Returns a BiFunction for a top statistic. This BiFunction will return a statResult,
the shape of which is determined by the 2 parameters the BiFunction gets.
<p>- UUID shareCode: if a shareCode is provided, a clickable "share" button will be added.
<p>- Integer shareCode: if a shareCode is provided, a clickable "share" button will be added.
<br>- CommandSender sender: if a sender is provided, a signature with "shared by sender-name" will be added.</br>
<br>- If both parameters are null, the statResult will be returned as is.</br>*/
public BiFunction<UUID, CommandSender, TextComponent> formattedTopStatFunction(@NotNull LinkedHashMap<String, Integer> topStats, @NotNull StatRequest request) {
public BiFunction<Integer, CommandSender, TextComponent> formattedTopStatFunction(@NotNull LinkedHashMap<String, Integer> topStats, @NotNull StatRequest request) {
final TextComponent title = getTopStatsTitleComponent(request, topStats.size());
final TextComponent shortTitle = getTopStatsTitleShortComponent(request, topStats.size());
final TextComponent list = getTopStatListComponent(topStats, request);
@ -255,7 +255,7 @@ public class MessageBuilder {
};
}
private BiFunction<UUID, CommandSender, TextComponent> getFormattingFunction(@NotNull TextComponent statResult, Target selection) {
private BiFunction<Integer, CommandSender, TextComponent> getFormattingFunction(@NotNull TextComponent statResult, Target selection) {
boolean useEnters = config.useEnters(selection, false);
boolean useEntersForShared = config.useEnters(selection, true);

View File

@ -21,7 +21,6 @@ import java.time.LocalDate;
import java.time.Month;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.UUID;
import java.util.function.BiFunction;
import java.util.function.Function;
@ -59,7 +58,7 @@ public final class OutputManager implements StatFormatter {
@Override
public TextComponent formatPlayerStat(@NotNull StatRequest request, int playerStat) {
BiFunction<UUID, CommandSender, TextComponent> playerStatFunction =
BiFunction<Integer, CommandSender, TextComponent> playerStatFunction =
getWriter(request).formattedPlayerStatFunction(playerStat, request);
return processFunction(request.getCommandSender(), playerStatFunction);
@ -67,7 +66,7 @@ public final class OutputManager implements StatFormatter {
@Override
public TextComponent formatServerStat(@NotNull StatRequest request, long serverStat) {
BiFunction<UUID, CommandSender, TextComponent> serverStatFunction =
BiFunction<Integer, CommandSender, TextComponent> serverStatFunction =
getWriter(request).formattedServerStatFunction(serverStat, request);
return processFunction(request.getCommandSender(), serverStatFunction);
@ -75,7 +74,7 @@ public final class OutputManager implements StatFormatter {
@Override
public TextComponent formatTopStat(@NotNull StatRequest request, @NotNull LinkedHashMap<String, Integer> topStats) {
BiFunction<UUID, CommandSender, TextComponent> topStatFunction =
BiFunction<Integer, CommandSender, TextComponent> topStatFunction =
getWriter(request).formattedTopStatFunction(topStats, request);
return processFunction(request.getCommandSender(), topStatFunction);
@ -125,13 +124,13 @@ public final class OutputManager implements StatFormatter {
adventure.sender(sender).sendMessage(component);
}
private TextComponent processFunction(CommandSender sender, @NotNull BiFunction<UUID, CommandSender, TextComponent> statResultFunction) {
private TextComponent processFunction(CommandSender sender, @NotNull BiFunction<Integer, CommandSender, TextComponent> statResultFunction) {
boolean saveOutput = !(sender instanceof ConsoleCommandSender) &&
ShareManager.isEnabled() &&
shareManager.senderHasPermission(sender);
if (saveOutput) {
UUID shareCode =
int shareCode =
shareManager.saveStatResult(sender.getName(), statResultFunction.apply(null, sender));
return statResultFunction.apply(shareCode, null);
}

View File

@ -21,8 +21,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
import static net.kyori.adventure.text.Component.*;
import static net.kyori.adventure.text.Component.text;
@ -155,7 +153,7 @@ public class ComponentFactory {
getStyleFromString(config.getSharerNameDecoration(true)));
}
public TextComponent shareButton(UUID shareCode) {
public TextComponent shareButton(int shareCode) {
return surroundingBrackets(
text("Share")
.color(MSG_HOVER)