TPS Graph & Collection fixed

Finished implementing 
This commit is contained in:
Rsl1122 2017-06-26 16:10:29 +03:00
parent c17c1c5171
commit 47391ece51
10 changed files with 1388 additions and 1304 deletions
Plan/src
main
test/java/main/java/com/djrapitops/plan/database

@ -37,7 +37,7 @@ import main.java.com.djrapitops.plan.api.API;
import main.java.com.djrapitops.plan.command.PlanCommand;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
import main.java.com.djrapitops.plan.data.cache.*;
import main.java.com.djrapitops.plan.data.handling.TPSCountTimer;
import main.java.com.djrapitops.plan.data.listeners.TPSCountTimer;
import main.java.com.djrapitops.plan.data.listeners.*;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.database.databases.*;

@ -40,6 +40,8 @@ public class AnalysisData {
private String punchCardData;
private String[] sessionDistributionData;
private String[] playtimeDistributionData;
private String[] tpsData;
private double averageTPS;
private int newPlayersMonth;
private int newPlayersWeek;
@ -92,6 +94,7 @@ public class AnalysisData {
uniqueJoinsDay = 0;
uniqueJoinsWeek = 0;
uniqueJoinsMonth = 0;
averageTPS = 0;
sortablePlayersTable = Html.ERROR_NOT_SET + "";
commandUseTableHtml = Html.ERROR_NOT_SET + "";
recentPlayers = Html.ERROR_NOT_SET + "";
@ -101,6 +104,7 @@ public class AnalysisData {
punchCardData = "[]";
sessionDistributionData = new String[]{"[]", "[]"};
playtimeDistributionData = new String[]{"[]", "[]"};
tpsData = new String[]{"[]", "[]", "[]"};
playersDataArray = new String[]{"[0]", "[\"No data\"]", "[0]", "[\"No data\"]", "[0]", "[\"No data\"]"};
additionalDataReplaceMap = new HashMap<>();
}
@ -1039,4 +1043,20 @@ public class AnalysisData {
public void setUniqueJoinsMonth(int uniqueJoinsMonth) {
this.uniqueJoinsMonth = uniqueJoinsMonth;
}
public String[] getTpsData() {
return tpsData;
}
public void setTpsData(String[] tpsData) {
this.tpsData = tpsData;
}
public double getAverageTPS() {
return averageTPS;
}
public void setAverageTPS(double averageTPS) {
this.averageTPS = averageTPS;
}
}

@ -366,10 +366,10 @@ public class DataCacheHandler extends LocationCache {
private List<TPS> calculateAverageTpsForEachMinute() {
final List<TPS> averages = new ArrayList<>();
ArrayList<List<TPS>> copy = new ArrayList<>(unsavedTPSHistory);
if (copy.isEmpty()) {
if (unsavedTPSHistory.isEmpty()) {
return new ArrayList<>();
}
List<List<TPS>> copy = new ArrayList<>(unsavedTPSHistory);;
for (List<TPS> history : copy) {
final long lastdate = history.get(history.size() - 1).getDate();
final double averageTPS = MathUtils.averageDouble(history.stream().map(t -> t.getTps()));
@ -571,6 +571,7 @@ public class DataCacheHandler extends LocationCache {
}
public void addTPSLastMinute(List<TPS> history) {
unsavedTPSHistory.add(history);
// Copy the contents to avoid reference, thus making the whole calculation pointless.
unsavedTPSHistory.add(new ArrayList<>(history));
}
}

@ -1,4 +1,4 @@
package main.java.com.djrapitops.plan.data.handling;
package main.java.com.djrapitops.plan.data.listeners;
import com.djrapitops.javaplugin.task.RslBukkitRunnable;
import java.util.ArrayList;
@ -6,6 +6,7 @@ import java.util.List;
import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
/**
* Class responsible for calculating TPS every second.
@ -14,14 +15,14 @@ import main.java.com.djrapitops.plan.data.cache.DataCacheHandler;
*/
public class TPSCountTimer extends RslBukkitRunnable<Plan> {
private long lastCheck;
private long lastCheckNano;
private final Plan plugin;
private final DataCacheHandler handler;
private final List<TPS> history;
public TPSCountTimer(Plan plugin) {
super("TPSCountTimer");
lastCheck = -1;
lastCheckNano = -1;
this.handler = plugin.getHandler();
this.plugin = plugin;
history = new ArrayList<>();
@ -29,10 +30,11 @@ public class TPSCountTimer extends RslBukkitRunnable<Plan> {
@Override
public void run() {
long now = System.nanoTime();
long diff = now - lastCheck;
lastCheck = now;
if (diff > now) { // First run's diff = now + 1, no calc possible.
long nanotime = System.nanoTime();
long now = MiscUtils.getTime();
long diff = nanotime - lastCheckNano;
lastCheckNano = nanotime;
if (diff > nanotime) { // First run's diff = nanotime + 1, no calc possible.
return;
}
TPS tps = calculateTPS(diff, now);
@ -43,7 +45,7 @@ public class TPSCountTimer extends RslBukkitRunnable<Plan> {
}
}
public TPS calculateTPS(long diff, long tpsDate) {
public TPS calculateTPS(long diff, long now) {
long expectedDiff = 1000000000L; // 1 000 000 000 ns / 1 s
long difference = diff - expectedDiff;
if (difference < 1000000) { // If less than 1 millisecond it is forgiven.
@ -51,7 +53,7 @@ public class TPSCountTimer extends RslBukkitRunnable<Plan> {
}
double tpsN = 20 - ((difference / expectedDiff) * 20);
int playersOnline = plugin.getServer().getOnlinePlayers().size();
TPS tps = new TPS(tpsDate / 1000000L, tpsN, playersOnline);
TPS tps = new TPS(now, tpsN, playersOnline);
return tps;
}
}

@ -128,7 +128,7 @@ public class TPSTable extends Table {
try {
statement = prepareStatement("DELETE FROM " + tableName + " WHERE (" + columnDate + "<?)");
// More than 8 days ago.
statement.setLong(1, MiscUtils.getTime()-((691200) * 1000));
statement.setLong(1, MiscUtils.getTime()-((691200L) * 1000L));
statement.execute();
} finally {
close(statement);

@ -3,7 +3,9 @@ package main.java.com.djrapitops.plan.ui.graphs;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import main.java.com.djrapitops.plan.Log;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.utilities.Benchmark;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import main.java.com.djrapitops.plan.utilities.comparators.TPSComparator;
@ -14,12 +16,15 @@ import main.java.com.djrapitops.plan.utilities.comparators.TPSComparator;
*/
public class TPSGraphCreator {
public static String[] generateDataArray(List<TPS> tpsData, long scale) {
Benchmark.start("TPSGraph generate array: "+tpsData.size());
long now = MiscUtils.getTime();
List<TPS> filtered = filterTPS(tpsData, now-scale);
Log.debug("TPSGraph, filtered: "+filtered.size());
Collections.sort(filtered, new TPSComparator());
List<Long> dates = filtered.stream().map(t -> t.getDate()).collect(Collectors.toList());
List<Double> tps = filtered.stream().map(t -> t.getTps()).collect(Collectors.toList());
List<Integer> players = filtered.stream().map(t -> t.getPlayers()).collect(Collectors.toList());
Benchmark.stop("TPSGraph generate array: "+tpsData.size());
return new String[]{dates.toString(), tps.toString(), players.toString()};
}

@ -133,6 +133,11 @@ public class PlaceholderUtils {
replaceMap.put("%graphmaxplayers%", Settings.GRAPH_PLAYERS_USEMAXPLAYERS_SCALE.isTrue() ? plugin.getVariable().getMaxPlayers()+"" : "2");
replaceMap.put("%refreshlong%", data.getRefreshDate()+"");
replaceMap.put("%servername%", Settings.SERVER_NAME.toString());
String[] tpsData = data.getTpsData();
replaceMap.put("%tpsdatalabels%", tpsData[0]);
replaceMap.put("%tpsdatatps%", tpsData[1]);
replaceMap.put("%tpsdataplayersonline%", tpsData[2]);
replaceMap.put("%averagetps%", data.getAverageTPS()+"");
Benchmark.stop("Replace Placeholders Anaysis");
return replaceMap;
}

@ -2,6 +2,7 @@ package main.java.com.djrapitops.plan.utilities.analysis;
import com.djrapitops.javaplugin.task.RslBukkitRunnable;
import com.djrapitops.javaplugin.task.RslTask;
import java.util.ArrayList;
import main.java.com.djrapitops.plan.data.additional.HookHandler;
import java.util.Date;
import java.util.HashMap;
@ -18,6 +19,7 @@ import main.java.com.djrapitops.plan.data.DemographicsData;
import main.java.com.djrapitops.plan.data.KillData;
import main.java.com.djrapitops.plan.data.RawAnalysisData;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.additional.AnalysisType;
import main.java.com.djrapitops.plan.data.additional.PluginData;
@ -30,6 +32,7 @@ import main.java.com.djrapitops.plan.ui.RecentPlayersButtonsCreator;
import main.java.com.djrapitops.plan.ui.graphs.PlayerActivityGraphCreator;
import main.java.com.djrapitops.plan.ui.graphs.PunchCardGraphCreator;
import main.java.com.djrapitops.plan.ui.graphs.SessionLengthDistributionGraphCreator;
import main.java.com.djrapitops.plan.ui.graphs.TPSGraphCreator;
import main.java.com.djrapitops.plan.ui.tables.SortableCommandUseTableCreator;
import main.java.com.djrapitops.plan.ui.tables.SortablePlayersTableCreator;
import main.java.com.djrapitops.plan.utilities.Benchmark;
@ -107,16 +110,24 @@ public class Analysis {
Log.info(Phrase.ANALYSIS_FAIL_NO_DATA + "");
return false;
}
return analyzeData(rawData, analysisCache);
List<TPS> tpsData = new ArrayList<>();
try {
tpsData = db.getTpsTable().getTPSData();
Log.debug("TPS Data Size: "+tpsData.size());
} catch (Exception ex) {
Log.toLog(this.getClass().getName(), ex);
}
return analyzeData(rawData, tpsData, analysisCache);
}
/**
*
* @param rawData
* @param tpsData
* @param analysisCache
* @return
*/
public boolean analyzeData(List<UserData> rawData, AnalysisCacheHandler analysisCache) {
public boolean analyzeData(List<UserData> rawData, List<TPS> tpsData, AnalysisCacheHandler analysisCache) {
try {
plugin.processStatus().setStatus("Analysis", "Analysis Phase");
Benchmark.start("Analysis Phase");
@ -135,12 +146,14 @@ public class Analysis {
}
});
Map<String, Integer> commandUse = handler.getCommandUse();
AnalysisData analysisData = new AnalysisData();
Benchmark.stop("Analysis Create Empty dataset");
log(Phrase.ANALYSIS_BEGIN_ANALYSIS.parse(rawData.size() + "", Benchmark.stop("Analysis Fetch Phase") + ""));
String playersTable = SortablePlayersTableCreator.createSortablePlayersTable(rawData);
analysisData.setSortablePlayersTable(playersTable);
analysisData.setTpsData(TPSGraphCreator.generateDataArray(tpsData, now));
analysisData.setAverageTPS(MathUtils.averageDouble(tpsData.stream().map(t -> t.getTps())));
RawAnalysisData sorted = fillDataset(commandUse, rawData, now);

File diff suppressed because it is too large Load Diff

@ -17,6 +17,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@ -24,11 +25,13 @@ import main.java.com.djrapitops.plan.Plan;
import main.java.com.djrapitops.plan.data.DemographicsData;
import main.java.com.djrapitops.plan.data.KillData;
import main.java.com.djrapitops.plan.data.SessionData;
import main.java.com.djrapitops.plan.data.TPS;
import main.java.com.djrapitops.plan.data.UserData;
import main.java.com.djrapitops.plan.data.cache.DBCallableProcessor;
import main.java.com.djrapitops.plan.database.Database;
import main.java.com.djrapitops.plan.database.databases.MySQLDB;
import main.java.com.djrapitops.plan.database.databases.SQLiteDB;
import main.java.com.djrapitops.plan.database.tables.TPSTable;
import main.java.com.djrapitops.plan.utilities.ManageUtils;
import main.java.com.djrapitops.plan.utilities.MiscUtils;
import org.bukkit.Bukkit;
@ -82,10 +85,10 @@ public class DatabaseTest {
public void startConnectionPingTask(Plan plugin) {
}
@Override
public void convertBukkitDataToDB() {
}
};
File f = new File(plan.getDataFolder(), "Errors.txt");
@ -174,9 +177,10 @@ public class DatabaseTest {
public void startConnectionPingTask(Plan plugin) {
}
@Override
public void convertBukkitDataToDB() {
}
}.getConfigName());
}
@ -191,9 +195,10 @@ public class DatabaseTest {
public void startConnectionPingTask(Plan plugin) {
}
@Override
public void convertBukkitDataToDB() {
}
}.getName());
}
@ -310,7 +315,7 @@ public class DatabaseTest {
db.saveMultipleUserData(list);
data.addPlayerKill(new KillData(MockUtils.getPlayer2UUID(), 2, "DiamondSword", 75843759L));
data.setLocation(null);
data2.setLocation(null);
data2.setLocation(null);
DBCallableProcessor process = new DBCallableProcessor() {
@Override
public void process(UserData d) {
@ -362,9 +367,10 @@ public class DatabaseTest {
public void startConnectionPingTask(Plan plugin) {
}
@Override
public void convertBukkitDataToDB() {
}
};
backup.init();
@ -399,9 +405,10 @@ public class DatabaseTest {
public void startConnectionPingTask(Plan plugin) {
}
@Override
public void convertBukkitDataToDB() {
}
};
backup.init();
@ -415,5 +422,38 @@ public class DatabaseTest {
assertTrue("Doesn't contain /tp", commandUse.containsKey("/tp"));
assertTrue("Doesn't contain /pla", commandUse.containsKey("/pla"));
assertTrue("Doesn't contain /help", commandUse.containsKey("/help"));
}
}
@Test
public void testTPSSaving() throws SQLException {
db.init();
TPSTable tpsTable = db.getTpsTable();
List<TPS> expected = new ArrayList<>();
Random r = new Random();
expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000)));
expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000)));
expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000)));
expected.add(new TPS(r.nextLong(), r.nextDouble(), r.nextInt(100000000)));
tpsTable.saveTPSData(expected);
assertEquals(expected, tpsTable.getTPSData());
}
@Test
public void testTPSClean() throws SQLException {
db.init();
TPSTable tpsTable = db.getTpsTable();
List<TPS> expected = new ArrayList<>();
Random r = new Random();
long now = System.currentTimeMillis();
expected.add(new TPS(now, r.nextDouble(), r.nextInt(100000000)));
expected.add(new TPS(now-1000L, r.nextDouble(), r.nextInt(100000000)));
expected.add(new TPS(now-3000L, r.nextDouble(), r.nextInt(100000000)));
expected.add(new TPS(now-(690000L * 1000L), r.nextDouble(), r.nextInt(100000000)));
TPS tooOldTPS = new TPS(now-(691400L * 1000L), r.nextDouble(), r.nextInt(100000000));
expected.add(tooOldTPS);
tpsTable.saveTPSData(expected);
tpsTable.clean();
expected.remove(tooOldTPS);
assertEquals(expected, tpsTable.getTPSData());
}
}