Plan/Plan/common/src/main/java/com/djrapitops/plan/delivery/domain/mutators/TPSMutator.java

263 lines
7.7 KiB
Java

/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.domain.mutators;
import com.djrapitops.plan.delivery.domain.container.DataContainer;
import com.djrapitops.plan.delivery.domain.keys.ServerKeys;
import com.djrapitops.plan.delivery.rendering.json.graphs.line.Point;
import com.djrapitops.plan.gathering.domain.TPS;
import com.djrapitops.plan.utilities.comparators.TPSComparator;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* Mutator for a list of TPS data.
* <p>
* Can be used to get properties of a large number of TPS entries easily.
*
* @author Rsl1122
*/
public class TPSMutator {
private final List<TPS> tpsData;
public TPSMutator(List<TPS> tpsData) {
this.tpsData = tpsData;
}
public static TPSMutator forContainer(DataContainer container) {
return new TPSMutator(container.getValue(ServerKeys.TPS).orElse(new ArrayList<>()));
}
public static TPSMutator copyOf(TPSMutator mutator) {
return new TPSMutator(new ArrayList<>(mutator.tpsData));
}
public TPSMutator filterBy(Predicate<TPS> filter) {
return new TPSMutator(tpsData.stream()
.filter(filter)
.collect(Collectors.toList()));
}
public TPSMutator filterDataBetween(long after, long before) {
return filterBy(tps -> tps.getDate() >= after && tps.getDate() <= before);
}
public TPSMutator filterTPSBetween(int above, int below) {
return filterBy(tps -> tps.getTicksPerSecond() > above && tps.getTicksPerSecond() < below);
}
public List<TPS> all() {
return tpsData;
}
public List<Point> playersOnlinePoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getPlayers()))
.collect(Collectors.toList());
}
public List<Point> tpsPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond()))
.collect(Collectors.toList());
}
public List<Point> cpuPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getCPUUsage()))
.filter(point -> point.getY() != -1)
.collect(Collectors.toList());
}
public List<Point> ramUsagePoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getUsedMemory()))
.collect(Collectors.toList());
}
public List<Point> entityPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getEntityCount()))
.collect(Collectors.toList());
}
public List<Point> chunkPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getChunksLoaded()))
.collect(Collectors.toList());
}
public List<Point> freeDiskPoints() {
return tpsData.stream()
.map(tps -> new Point(tps.getDate(), tps.getFreeDiskSpace()))
.filter(point -> point.getY() != -1)
.collect(Collectors.toList());
}
public long serverDownTime() {
long lastDate = -1;
long downTime = 0;
tpsData.sort(new TPSComparator());
for (TPS tps : tpsData) {
long date = tps.getDate();
if (lastDate == -1) {
lastDate = date;
continue;
}
long diff = date - lastDate;
if (diff > TimeUnit.MINUTES.toMillis(3L)) {
downTime += diff;
}
lastDate = date;
}
return downTime;
}
public long serverOccupiedTime() {
long lastDate = -1;
long activeTime = 0;
tpsData.sort(new TPSComparator());
for (TPS tps : tpsData) {
long date = tps.getDate();
if (lastDate == -1) {
lastDate = date;
continue;
}
int players = tps.getPlayers();
long diff = date - lastDate;
if (players > 0 && diff <= TimeUnit.MINUTES.toMillis(3L)) {
activeTime += diff;
}
lastDate = date;
}
return activeTime;
}
public double percentageTPSAboveThreshold(int threshold) {
if (tpsData.isEmpty()) {
return 1;
}
long count = 0;
for (TPS tps : tpsData) {
if (tps.getTicksPerSecond() >= threshold) {
count++;
}
}
return count * 1.0 / tpsData.size();
}
public int lowTpsSpikeCount(int threshold) {
boolean wasLow = false;
int spikeCount = 0;
for (TPS tpsObj : tpsData) {
double tps = tpsObj.getTicksPerSecond();
if (tps < threshold) {
if (!wasLow) {
spikeCount++;
wasLow = true;
}
} else {
wasLow = false;
}
}
return spikeCount;
}
public double averageTPS() {
return tpsData.stream()
.mapToDouble(TPS::getTicksPerSecond)
.filter(num -> num >= 0)
.average().orElse(-1);
}
public double averageCPU() {
return tpsData.stream()
.mapToDouble(TPS::getCPUUsage)
.filter(num -> num >= 0)
.average().orElse(-1);
}
public double averageRAM() {
return tpsData.stream()
.mapToDouble(TPS::getUsedMemory)
.filter(num -> num >= 0)
.average().orElse(-1);
}
public double averageEntities() {
return tpsData.stream()
.mapToDouble(TPS::getEntityCount)
.filter(num -> num >= 0)
.average().orElse(-1);
}
public double averageChunks() {
return tpsData.stream()
.mapToDouble(TPS::getChunksLoaded)
.filter(num -> num >= 0)
.average().orElse(-1);
}
public double averageFreeDisk() {
return tpsData.stream()
.mapToDouble(TPS::getFreeDiskSpace)
.filter(num -> num >= 0)
.average().orElse(-1);
}
public long maxFreeDisk() {
return tpsData.stream()
.mapToLong(TPS::getFreeDiskSpace)
.filter(num -> num >= 0)
.max().orElse(-1);
}
public long minFreeDisk() {
return tpsData.stream()
.mapToLong(TPS::getFreeDiskSpace)
.filter(num -> num >= 0)
.min().orElse(-1);
}
public double averagePlayersOnline() {
return tpsData.stream()
.mapToDouble(TPS::getPlayers)
.average().orElse(-1);
}
public Optional<TPS> getLast() {
if (tpsData.isEmpty()) return Optional.empty();
// else
tpsData.sort(new TPSComparator());
return Optional.of(tpsData.get(tpsData.size() - 1));
}
}