diff --git a/Plan/src/main/java/com/djrapitops/plan/data/ServerProfile.java b/Plan/src/main/java/com/djrapitops/plan/data/ServerProfile.java index b0144671e..48cda8491 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/ServerProfile.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/ServerProfile.java @@ -8,14 +8,12 @@ import com.djrapitops.plan.data.container.GeoInfo; import com.djrapitops.plan.data.container.PlayerKill; import com.djrapitops.plan.data.container.Session; import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import com.djrapitops.plan.data.time.WorldTimes; -import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.utilities.analysis.AnalysisUtils; import com.djrapitops.plan.utilities.analysis.MathUtils; import com.djrapitops.plan.utilities.comparators.PlayerProfileLastPlayedComparator; -import com.djrapitops.plan.utilities.comparators.TPSComparator; import com.djrapitops.plan.utilities.html.tables.PlayersTableCreator; -import com.djrapitops.plugin.api.TimeAmount; import java.util.*; import java.util.function.Function; @@ -61,24 +59,7 @@ public class ServerProfile { } public static long getLowSpikeCount(List tpsData) { - int mediumThreshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber(); - - boolean wasLow = false; - long spikeCount = 0L; - - for (TPS tpsObj : tpsData) { - double tps = tpsObj.getTicksPerSecond(); - if (tps < mediumThreshold) { - if (!wasLow) { - spikeCount++; - wasLow = true; - } - } else { - wasLow = false; - } - } - - return spikeCount; + return new TPSMutator(tpsData).lowTpsSpikeCount(); } public static List getPlayerKills(List s) { @@ -106,65 +87,15 @@ public class ServerProfile { } public static long serverDownTime(List tpsData) { - long lastDate = -1; - long downTime = 0; - for (TPS tps : tpsData) { - long date = tps.getDate(); - if (lastDate == -1) { - lastDate = date; - continue; - } - - long diff = date - lastDate; - if (diff > TimeAmount.MINUTE.ms() * 3L) { - downTime += diff; - } - lastDate = date; - } - - return downTime; + return new TPSMutator(tpsData).serverDownTime(); } public static long serverIdleTime(List tpsData) { - long lastDate = -1; - int lastPlayers = 0; - long idleTime = 0; - for (TPS tps : tpsData) { - long date = tps.getDate(); - int players = tps.getPlayers(); - if (lastDate == -1) { - lastDate = date; - lastPlayers = players; - continue; - } - - long diff = date - lastDate; - if (lastPlayers == 0 && players == 0) { - idleTime += diff; - } - - lastDate = date; - lastPlayers = players; - } - - return idleTime; + return new TPSMutator(tpsData).serverIdleTime(); } public static double aboveLowThreshold(List tpsData) { - if (tpsData.isEmpty()) { - return 1; - } - - int threshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber(); - - long count = 0; - for (TPS tps : tpsData) { - if (tps.getTicksPerSecond() >= threshold) { - count++; - } - } - - return count * 1.0 / tpsData.size(); + return new TPSMutator(tpsData).percentageTPSAboveLowThreshold(); } public List getPlayers() { @@ -191,57 +122,6 @@ public class ServerProfile { this.commandUsage = commandUsage; } - public double getAverageTPS(long after, long before) { - OptionalDouble average = getTPSData(after, before) - .mapToDouble(TPS::getTicksPerSecond) - .average(); - if (average.isPresent()) { - return average.getAsDouble(); - } - return -1; - } - - public double getAverageCPU(long after, long before) { - OptionalDouble average = getTPSData(after, before) - .mapToDouble(TPS::getCPUUsage) - .filter(num -> num >= 0) - .average(); - if (average.isPresent()) { - return average.getAsDouble(); - } - return -1; - } - - public double getAverageRAM(long after, long before) { - OptionalDouble average = getTPSData(after, before) - .mapToDouble(TPS::getUsedMemory) - .average(); - if (average.isPresent()) { - return average.getAsDouble(); - } - return -1; - } - - public double getAverageEntities(long after, long before) { - OptionalDouble average = getTPSData(after, before) - .mapToDouble(TPS::getEntityCount) - .average(); - if (average.isPresent()) { - return average.getAsDouble(); - } - return -1; - } - - public double getAverageChunks(long after, long before) { - OptionalDouble average = getTPSData(after, before) - .mapToDouble(TPS::getChunksLoaded) - .average(); - if (average.isPresent()) { - return average.getAsDouble(); - } - return -1; - } - public long getNewPlayers(long after, long before) { return getPlayersWhoRegistered(after, before).count(); } @@ -356,18 +236,6 @@ public class ServerProfile { return uuids; } - public long serverDownTime(long after, long before) { - return serverDownTime(getTPSData(after, before) - .sorted(new TPSComparator()) - .collect(Collectors.toList())); - } - - public long serverIdleTime(long after, long before) { - return serverIdleTime(getTPSData(after, before) - .sorted(new TPSComparator()) - .collect(Collectors.toList())); - } - public PlayerProfile getPlayer(UUID uuid) { if (playerMap == null) { playerMap = players.stream().collect(Collectors.toMap(PlayerProfile::getUuid, Function.identity())); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java index b0a73a2dc..4de69ad79 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/containers/AnalysisContainer.java @@ -1,11 +1,14 @@ package com.djrapitops.plan.data.store.containers; import com.djrapitops.plan.PlanPlugin; +import com.djrapitops.plan.data.store.Key; import com.djrapitops.plan.data.store.keys.AnalysisKeys; import com.djrapitops.plan.data.store.keys.PlayerKeys; import com.djrapitops.plan.data.store.keys.ServerKeys; import com.djrapitops.plan.data.store.mutators.SessionsMutator; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import com.djrapitops.plan.data.store.mutators.formatting.Formatters; +import com.djrapitops.plan.data.time.WorldTimes; import com.djrapitops.plan.system.database.databases.Database; import com.djrapitops.plan.system.info.server.ServerInfo; import com.djrapitops.plan.system.info.server.ServerProperties; @@ -13,12 +16,15 @@ import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.settings.theme.Theme; import com.djrapitops.plan.system.settings.theme.ThemeVal; import com.djrapitops.plan.utilities.MiscUtils; +import com.djrapitops.plan.utilities.html.graphs.line.*; +import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie; import com.djrapitops.plan.utilities.html.structure.RecentLoginList; import com.djrapitops.plan.utilities.html.structure.SessionAccordion; import com.djrapitops.plan.utilities.html.tables.ServerSessionTable; import com.djrapitops.plugin.api.TimeAmount; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.stream.Collectors; @@ -56,10 +62,15 @@ public class AnalysisContainer extends DataContainer { putRawData(AnalysisKeys.TPS_MEDIUM, Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber()); putRawData(AnalysisKeys.TPS_HIGH, Settings.THEME_GRAPH_TPS_THRESHOLD_HIGH.getNumber()); + putSupplier(AnalysisKeys.SESSIONS_MUTATOR, () -> new SessionsMutator(serverContainer.getValue(ServerKeys.SESSIONS).orElse(new ArrayList<>()))); + putSupplier(AnalysisKeys.TPS_MUTATOR, () -> new TPSMutator(serverContainer.getValue(ServerKeys.TPS).orElse(new ArrayList<>()))); + addServerProperties(); addThemeColors(); addPlayerSuppliers(); addSessionSuppliers(); + addGraphSuppliers(); + addTPSAverageSuppliers(); } private void addServerProperties() { @@ -124,7 +135,6 @@ public class AnalysisContainer extends DataContainer { putSupplier(AnalysisKeys.SESSION_ACCORDION_HTML, () -> getUnsafe(AnalysisKeys.SESSION_ACCORDION).toHtml()); putSupplier(AnalysisKeys.SESSION_ACCORDION_FUNCTIONS, () -> getUnsafe(AnalysisKeys.SESSION_ACCORDION).toViewScript()); - putSupplier(AnalysisKeys.SESSIONS_MUTATOR, () -> new SessionsMutator(serverContainer.getValue(ServerKeys.SESSIONS).orElse(new ArrayList<>()))); putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount() .apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) ); @@ -139,5 +149,58 @@ public class AnalysisContainer extends DataContainer { putSupplier(AnalysisKeys.AVERAGE_PLAYTIME_F, () -> Formatters.timeAmount() .apply(getUnsafe(AnalysisKeys.PLAYTIME_TOTAL) / (long) getUnsafe(AnalysisKeys.PLAYERS_TOTAL)) ); + putSupplier(AnalysisKeys.AVERAGE_SESSION_LENGTH_F, () -> Formatters.timeAmount() + .apply(getUnsafe(AnalysisKeys.SESSIONS_MUTATOR).toAverageSessionLength()) + ); + } + + private void addGraphSuppliers() { + Key worldPie = new Key<>(WorldPie.class, "WORLD_PIE"); + putSupplier(worldPie, () -> new WorldPie(serverContainer.getValue(ServerKeys.WORLD_TIMES).orElse(new WorldTimes(new HashMap<>())))); + putSupplier(AnalysisKeys.WORLD_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsSeries()); + putSupplier(AnalysisKeys.GM_PIE_SERIES, () -> getUnsafe(worldPie).toHighChartsDrilldown()); + putSupplier(AnalysisKeys.PLAYERS_ONLINE_SERIES, () -> + new OnlineActivityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries() + ); + putSupplier(AnalysisKeys.TPS_SERIES, () -> new TPSGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.CPU_SERIES, () -> new CPUGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.RAM_SERIES, () -> new RamGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.ENTITY_SERIES, () -> new EntityGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + putSupplier(AnalysisKeys.CHUNK_SERIES, () -> new ChunkGraph(getUnsafe(AnalysisKeys.TPS_MUTATOR)).toHighChartsSeries()); + } + + private void addTPSAverageSuppliers() { + Key tpsMonth = new Key<>(TPSMutator.class, "TPS_MONTH"); + Key tpsWeek = new Key<>(TPSMutator.class, "TPS_WEEK"); + Key tpsDay = new Key<>(TPSMutator.class, "TPS_DAY"); + + putSupplier(tpsMonth, () -> TPSMutator.copyOf(getUnsafe(AnalysisKeys.TPS_MUTATOR)) + .filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_MONTH_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) + ); + putSupplier(tpsWeek, () -> TPSMutator.copyOf(getUnsafe(AnalysisKeys.TPS_MUTATOR)) + .filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_WEEK_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) + ); + putSupplier(tpsDay, () -> TPSMutator.copyOf(getUnsafe(AnalysisKeys.TPS_MUTATOR)) + .filterDataBetween(getUnsafe(AnalysisKeys.ANALYSIS_TIME_DAY_AGO), getUnsafe(AnalysisKeys.ANALYSIS_TIME)) + ); + + putSupplier(AnalysisKeys.TPS_SPIKE_MONTH, () -> getUnsafe(tpsMonth).lowTpsSpikeCount()); + putSupplier(AnalysisKeys.AVG_TPS_MONTH, () -> getUnsafe(tpsMonth).averageTPS()); + putSupplier(AnalysisKeys.AVG_CPU_MONTH, () -> getUnsafe(tpsMonth).averageCPU()); + putSupplier(AnalysisKeys.AVG_RAM_MONTH, () -> getUnsafe(tpsMonth).averageRAM()); + putSupplier(AnalysisKeys.AVG_ENTITY_MONTH, () -> getUnsafe(tpsMonth).averageEntities()); + putSupplier(AnalysisKeys.AVG_CHUNK_MONTH, () -> getUnsafe(tpsMonth).averageChunks()); + putSupplier(AnalysisKeys.TPS_SPIKE_WEEK, () -> getUnsafe(tpsWeek).lowTpsSpikeCount()); + putSupplier(AnalysisKeys.AVG_TPS_WEEK, () -> getUnsafe(tpsWeek).averageTPS()); + putSupplier(AnalysisKeys.AVG_CPU_WEEK, () -> getUnsafe(tpsWeek).averageCPU()); + putSupplier(AnalysisKeys.AVG_RAM_WEEK, () -> getUnsafe(tpsWeek).averageRAM()); + putSupplier(AnalysisKeys.AVG_ENTITY_WEEK, () -> getUnsafe(tpsWeek).averageEntities()); + putSupplier(AnalysisKeys.AVG_CHUNK_WEEK, () -> getUnsafe(tpsWeek).averageChunks()); + putSupplier(AnalysisKeys.TPS_SPIKE_DAY, () -> getUnsafe(tpsDay).lowTpsSpikeCount()); + putSupplier(AnalysisKeys.AVG_TPS_DAY, () -> getUnsafe(tpsDay).averageTPS()); + putSupplier(AnalysisKeys.AVG_CPU_DAY, () -> getUnsafe(tpsDay).averageCPU()); + putSupplier(AnalysisKeys.AVG_RAM_DAY, () -> getUnsafe(tpsDay).averageRAM()); + putSupplier(AnalysisKeys.AVG_ENTITY_DAY, () -> getUnsafe(tpsDay).averageEntities()); + putSupplier(AnalysisKeys.AVG_CHUNK_DAY, () -> getUnsafe(tpsDay).averageChunks()); } } \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java index e1dc994c8..bdbea77b5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/keys/AnalysisKeys.java @@ -4,6 +4,7 @@ import com.djrapitops.plan.data.store.Key; import com.djrapitops.plan.data.store.PlaceholderKey; import com.djrapitops.plan.data.store.Type; import com.djrapitops.plan.data.store.mutators.SessionsMutator; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import com.djrapitops.plan.utilities.html.structure.SessionAccordion; import java.util.Map; @@ -93,21 +94,21 @@ public class AnalysisKeys { public static final PlaceholderKey TPS_SPIKE_MONTH = new PlaceholderKey<>(Integer.class, "tpsSpikeMonth"); public static final PlaceholderKey TPS_SPIKE_WEEK = new PlaceholderKey<>(Integer.class, "tpsSpikeWeek"); public static final PlaceholderKey TPS_SPIKE_DAY = new PlaceholderKey<>(Integer.class, "tpsSpikeDay"); - public static final PlaceholderKey AVG_TPS_MONTH = new PlaceholderKey<>(Integer.class, "tpsAverageMonth"); - public static final PlaceholderKey AVG_TPS_WEEK = new PlaceholderKey<>(Integer.class, "tpsAverageWeek"); - public static final PlaceholderKey AVG_TPS_DAY = new PlaceholderKey<>(Integer.class, "tpsAverageDay"); - public static final PlaceholderKey AVG_CPU_MONTH = new PlaceholderKey<>(Integer.class, "cpuAverageMonth"); - public static final PlaceholderKey AVG_CPU_WEEK = new PlaceholderKey<>(Integer.class, "cpuAverageWeek"); - public static final PlaceholderKey AVG_CPU_DAY = new PlaceholderKey<>(Integer.class, "cpuAverageDay"); - public static final PlaceholderKey AVG_RAM_MONTH = new PlaceholderKey<>(Integer.class, "ramAverageMonth"); - public static final PlaceholderKey AVG_RAM_WEEK = new PlaceholderKey<>(Integer.class, "ramAverageWeek"); - public static final PlaceholderKey AVG_RAM_DAY = new PlaceholderKey<>(Integer.class, "ramAverageDay"); - public static final PlaceholderKey AVG_ENTITY_MONTH = new PlaceholderKey<>(Integer.class, "entityAverageMonth"); - public static final PlaceholderKey AVG_ENTITY_WEEK = new PlaceholderKey<>(Integer.class, "entityAverageWeek"); - public static final PlaceholderKey AVG_ENTITY_DAY = new PlaceholderKey<>(Integer.class, "entityAverageDay"); - public static final PlaceholderKey AVG_CHUNK_MONTH = new PlaceholderKey<>(Integer.class, "chunkAverageMonth"); - public static final PlaceholderKey AVG_CHUNK_WEEK = new PlaceholderKey<>(Integer.class, "chunkAverageWeek"); - public static final PlaceholderKey AVG_CHUNK_DAY = new PlaceholderKey<>(Integer.class, "chunkAverageDay"); + public static final PlaceholderKey AVG_TPS_MONTH = new PlaceholderKey<>(Double.class, "tpsAverageMonth"); + public static final PlaceholderKey AVG_TPS_WEEK = new PlaceholderKey<>(Double.class, "tpsAverageWeek"); + public static final PlaceholderKey AVG_TPS_DAY = new PlaceholderKey<>(Double.class, "tpsAverageDay"); + public static final PlaceholderKey AVG_CPU_MONTH = new PlaceholderKey<>(Double.class, "cpuAverageMonth"); + public static final PlaceholderKey AVG_CPU_WEEK = new PlaceholderKey<>(Double.class, "cpuAverageWeek"); + public static final PlaceholderKey AVG_CPU_DAY = new PlaceholderKey<>(Double.class, "cpuAverageDay"); + public static final PlaceholderKey AVG_RAM_MONTH = new PlaceholderKey<>(Double.class, "ramAverageMonth"); + public static final PlaceholderKey AVG_RAM_WEEK = new PlaceholderKey<>(Double.class, "ramAverageWeek"); + public static final PlaceholderKey AVG_RAM_DAY = new PlaceholderKey<>(Double.class, "ramAverageDay"); + public static final PlaceholderKey AVG_ENTITY_MONTH = new PlaceholderKey<>(Double.class, "entityAverageMonth"); + public static final PlaceholderKey AVG_ENTITY_WEEK = new PlaceholderKey<>(Double.class, "entityAverageWeek"); + public static final PlaceholderKey AVG_ENTITY_DAY = new PlaceholderKey<>(Double.class, "entityAverageDay"); + public static final PlaceholderKey AVG_CHUNK_MONTH = new PlaceholderKey<>(Double.class, "chunkAverageMonth"); + public static final PlaceholderKey AVG_CHUNK_WEEK = new PlaceholderKey<>(Double.class, "chunkAverageWeek"); + public static final PlaceholderKey AVG_CHUNK_DAY = new PlaceholderKey<>(Double.class, "chunkAverageDay"); // Data for Charts public static final PlaceholderKey WORLD_PIE_SERIES = new PlaceholderKey<>(String.class, "worldSeries"); public static final PlaceholderKey GM_PIE_SERIES = new PlaceholderKey<>(String.class, "gmSeries"); @@ -125,6 +126,7 @@ public class AnalysisKeys { public static final PlaceholderKey CALENDAR_SERIES = new PlaceholderKey<>(String.class, "calendarSeries"); // Variables used only during analysis public static final Key SESSIONS_MUTATOR = new Key<>(SessionsMutator.class, "SESSIONS_MUTATOR"); + public static final Key TPS_MUTATOR = new Key<>(TPSMutator.class, "TPS_MUTATOR"); public static final Key PLAYTIME_TOTAL = new Key<>(Long.class, "PLAYTIME_TOTAL"); public static final Key ANALYSIS_TIME = new Key<>(Long.class, "ANALYSIS_TIME"); public static final Key ANALYSIS_TIME_DAY_AGO = new Key<>(Long.class, "ANALYSIS_TIME_DAY_AGO"); diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java index 00ba7b421..776de22c9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/SessionsMutator.java @@ -28,7 +28,7 @@ public class SessionsMutator { } public static SessionsMutator copyOf(SessionsMutator mutator) { - return new SessionsMutator(mutator.sessions); + return new SessionsMutator(new ArrayList<>(mutator.sessions)); } public SessionsMutator(List sessions) { diff --git a/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java new file mode 100644 index 000000000..a3ba9ac44 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/data/store/mutators/TPSMutator.java @@ -0,0 +1,225 @@ +package com.djrapitops.plan.data.store.mutators; + +import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.containers.DataContainer; +import com.djrapitops.plan.data.store.keys.ServerKeys; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.utilities.html.graphs.line.Point; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.utilities.Verify; + +import java.util.ArrayList; +import java.util.List; +import java.util.OptionalDouble; +import java.util.stream.Collectors; + +/** + * Mutator for a list of TPS data. + *

+ * Can be used to get properties of a large number of TPS entries easily. + * + * @author Rsl1122 + */ +public class TPSMutator { + + private List tpsData; + + public TPSMutator(List tpsData) { + this.tpsData = tpsData; + } + + public static TPSMutator forContainer(DataContainer dataContainer) { + Verify.isTrue(dataContainer.supports(ServerKeys.TPS), + () -> new IllegalArgumentException("Given DataContainer does not support SESSIONS-key")); + return new TPSMutator(dataContainer.getValue(ServerKeys.TPS).orElse(new ArrayList<>())); + } + + public static TPSMutator copyOf(TPSMutator mutator) { + return new TPSMutator(new ArrayList<>(mutator.tpsData)); + } + + public TPSMutator filterDataBetween(long after, long before) { + tpsData = tpsData.stream() + .filter(tps -> tps.getDate() >= after && tps.getDate() <= before) + .collect(Collectors.toList()); + return this; + } + + public List all() { + return tpsData; + } + + public List playersOnlinePoints() { + return tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getPlayers())) + .collect(Collectors.toList()); + } + + public List tpsPoints() { + return tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond())) + .collect(Collectors.toList()); + } + + public List cpuPoints() { + return tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getCPUUsage())) + .collect(Collectors.toList()); + } + + public List ramUsagePoints() { + return tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getUsedMemory())) + .collect(Collectors.toList()); + } + + public List entityPoints() { + return tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getEntityCount())) + .collect(Collectors.toList()); + } + + public List chunkPoints() { + return tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getChunksLoaded())) + .collect(Collectors.toList()); + } + + public long serverDownTime() { + long lastDate = -1; + long downTime = 0; + for (TPS tps : tpsData) { + long date = tps.getDate(); + if (lastDate == -1) { + lastDate = date; + continue; + } + + long diff = date - lastDate; + if (diff > TimeAmount.MINUTE.ms() * 3L) { + downTime += diff; + } + lastDate = date; + } + + return downTime; + } + + public long serverIdleTime() { + long lastDate = -1; + int lastPlayers = 0; + long idleTime = 0; + for (TPS tps : tpsData) { + long date = tps.getDate(); + int players = tps.getPlayers(); + if (lastDate == -1) { + lastDate = date; + lastPlayers = players; + continue; + } + + long diff = date - lastDate; + if (lastPlayers == 0 && players == 0) { + idleTime += diff; + } + + lastDate = date; + lastPlayers = players; + } + + return idleTime; + } + + public double percentageTPSAboveLowThreshold() { + if (tpsData.isEmpty()) { + return 1; + } + + int threshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber(); + + long count = 0; + for (TPS tps : tpsData) { + if (tps.getTicksPerSecond() >= threshold) { + count++; + } + } + + return count * 1.0 / tpsData.size(); + } + + public int lowTpsSpikeCount() { + int mediumThreshold = Settings.THEME_GRAPH_TPS_THRESHOLD_MED.getNumber(); + + boolean wasLow = false; + int spikeCount = 0; + + for (TPS tpsObj : tpsData) { + double tps = tpsObj.getTicksPerSecond(); + if (tps < mediumThreshold) { + if (!wasLow) { + spikeCount++; + wasLow = true; + } + } else { + wasLow = false; + } + } + + return spikeCount; + } + + public double averageTPS() { + OptionalDouble average = tpsData.stream() + .mapToDouble(TPS::getTicksPerSecond) + .filter(num -> num >= 0) + .average(); + if (average.isPresent()) { + return average.getAsDouble(); + } + return -1; + } + + public double averageCPU() { + OptionalDouble average = tpsData.stream() + .mapToDouble(TPS::getCPUUsage) + .filter(num -> num >= 0) + .average(); + if (average.isPresent()) { + return average.getAsDouble(); + } + return -1; + } + + public double averageRAM() { + OptionalDouble average = tpsData.stream() + .mapToDouble(TPS::getUsedMemory) + .filter(num -> num >= 0) + .average(); + if (average.isPresent()) { + return average.getAsDouble(); + } + return -1; + } + + public double averageEntities() { + OptionalDouble average = tpsData.stream() + .mapToDouble(TPS::getEntityCount) + .filter(num -> num >= 0) + .average(); + if (average.isPresent()) { + return average.getAsDouble(); + } + return -1; + } + + public double averageChunks() { + OptionalDouble average = tpsData.stream() + .mapToDouble(TPS::getChunksLoaded) + .filter(num -> num >= 0) + .average(); + if (average.isPresent()) { + return average.getAsDouble(); + } + return -1; + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java index 20e3df7a4..e26a24305 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/CPUGraph.java @@ -1,9 +1,9 @@ package com.djrapitops.plan.utilities.html.graphs.line; import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import java.util.List; -import java.util.stream.Collectors; /** * Graph about CPU Usage gathered by TPSCountTimer. @@ -15,12 +15,10 @@ import java.util.stream.Collectors; public class CPUGraph extends AbstractLineGraph { public CPUGraph(List tpsData) { - super(transformToPoints(tpsData)); + this(new TPSMutator(tpsData)); } - private static List transformToPoints(List tpsData) { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getCPUUsage())) - .collect(Collectors.toList()); + public CPUGraph(TPSMutator mutator) { + super(mutator.cpuPoints()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java index 58acb3916..3ce1d5f0e 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/ChunkGraph.java @@ -1,9 +1,9 @@ package com.djrapitops.plan.utilities.html.graphs.line; import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import java.util.List; -import java.util.stream.Collectors; /** * Graph about Chunk Counts gathered by TPSCountTimer. @@ -15,12 +15,10 @@ import java.util.stream.Collectors; public class ChunkGraph extends AbstractLineGraph { public ChunkGraph(List tpsData) { - super(turnToPoints(tpsData)); + this(new TPSMutator(tpsData)); } - private static List turnToPoints(List tpsData) { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getChunksLoaded())) - .collect(Collectors.toList()); + public ChunkGraph(TPSMutator mutator) { + super(mutator.chunkPoints()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java index c89ed361a..617612b96 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/EntityGraph.java @@ -1,9 +1,9 @@ package com.djrapitops.plan.utilities.html.graphs.line; import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import java.util.List; -import java.util.stream.Collectors; /** * Graph about Entity Counts gathered by TPSCountTimer. @@ -15,12 +15,10 @@ import java.util.stream.Collectors; public class EntityGraph extends AbstractLineGraph { public EntityGraph(List tpsData) { - super(turnToPoints(tpsData)); + this(new TPSMutator(tpsData)); } - private static List turnToPoints(List tpsData) { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getEntityCount())) - .collect(Collectors.toList()); + public EntityGraph(TPSMutator mutator) { + super(mutator.entityPoints()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/OnlineActivityGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/OnlineActivityGraph.java index 04c4b2493..89fccf3d5 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/OnlineActivityGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/OnlineActivityGraph.java @@ -1,9 +1,9 @@ package com.djrapitops.plan.utilities.html.graphs.line; import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import java.util.List; -import java.util.stream.Collectors; /** * Graph about Player Counts gathered by TPSCountTimer. @@ -15,12 +15,10 @@ import java.util.stream.Collectors; public class OnlineActivityGraph extends AbstractLineGraph { public OnlineActivityGraph(List tpsData) { - super(turnToPoints(tpsData)); + this(new TPSMutator(tpsData)); } - private static List turnToPoints(List tpsData) { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getPlayers())) - .collect(Collectors.toList()); + public OnlineActivityGraph(TPSMutator mutator) { + super(mutator.playersOnlinePoints()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java index 1208132fd..40b1460d9 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/RamGraph.java @@ -1,9 +1,9 @@ package com.djrapitops.plan.utilities.html.graphs.line; import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import java.util.List; -import java.util.stream.Collectors; /** * Graph about RAM Usage gathered by TPSCountTimer. @@ -15,12 +15,10 @@ import java.util.stream.Collectors; public class RamGraph extends AbstractLineGraph { public RamGraph(List tpsData) { - super(turnToPoints(tpsData)); + this(new TPSMutator(tpsData)); } - private static List turnToPoints(List tpsData) { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getUsedMemory())) - .collect(Collectors.toList()); + public RamGraph(TPSMutator mutator) { + super(mutator.ramUsagePoints()); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java index 6c77555be..63d8270dc 100644 --- a/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java +++ b/Plan/src/main/java/com/djrapitops/plan/utilities/html/graphs/line/TPSGraph.java @@ -1,9 +1,9 @@ package com.djrapitops.plan.utilities.html.graphs.line; import com.djrapitops.plan.data.container.TPS; +import com.djrapitops.plan.data.store.mutators.TPSMutator; import java.util.List; -import java.util.stream.Collectors; /** * Graph about TPS gathered by TPSCountTimer. @@ -15,12 +15,10 @@ import java.util.stream.Collectors; public class TPSGraph extends AbstractLineGraph { public TPSGraph(List tpsData) { - super(turnToPoints(tpsData)); + this(new TPSMutator(tpsData)); } - private static List turnToPoints(List tpsData) { - return tpsData.stream() - .map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond())) - .collect(Collectors.toList()); + public TPSGraph(TPSMutator mutator) { + super(mutator.tpsPoints()); } }