java-topology/tests/bench/LoadSimBenchmark.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

313 lines
18 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package bench;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
/**
* LoadSimBenchmark — simulates concurrent player connections and game-loop ticks
* against both VANILLA (unpatched) and PATCHED server algorithms.
*
* Three simulation axes:
*
* 1. World load / /reload
* N threads each trigger a full tag-graph resolution at modpack depth D.
* Models: players queued outside door while server does /reload.
* Metric: wall-clock time until all N joins complete.
*
* 2. TPS under concurrent player load
* Game loop runs at 20 TPS target (50 ms budget per tick).
* Each tick evaluates redstone contraptions for all connected players.
* VANILLA: O(W) wire membership test per evaluation (Deque.contains).
* PATCHED: O(1) wire membership test (HashSet companion).
* Metric: achieved TPS and tick overrun rate at increasing player counts.
*
* 3. Join throughput and latency
* Measures p50 / p95 / p99 join latency and sustained joins/sec.
*
* Modpack profile (Create + AE2 + Mekanism + Thermal):
* - Tag depth: 12 (diamond inheritance chains across mods)
* - Total cross-mod tags: ~800 entries resolved at load time
* - Wires per player: uncalibrated — treat §2/§3 as exploratory
*
* NOTE: §1 (world load) is algorithm-isolation micro-benchmark, not real server wall-clock.
* Real server /reload: vanilla 19,255 ms → patched 3,087 ms (6.2×, bench-server.sh).
*
* §2/§3 (redstone TPS) is EXPLORATORY. minecraft-0003 (ExperimentalRedstoneWireEvaluator)
* is confirmed but WIRES_PER_PLAYER is not sourced from real measurements.
* Do not cite TPS numbers from §2/§3 as confirmed defect impact.
*/
public class LoadSimBenchmark {
// ── Modpack profile ───────────────────────────────────────────────────────
static final int TAG_DEPTH = 12;
static final int TAG_GRAPH_REPS = 20; // 20 independent tag namespaces per modpack
// WIRES_PER_PLAYER: exploratory — not sourced from real server measurement.
// minecraft-0003 defect is confirmed but this constant determines all TPS numbers.
static final int WIRES_PER_PLAYER = 400;
static final int TICK_BUDGET_MS = 50; // 20 TPS = 50 ms/tick
static final int TICKS_TO_SIMULATE = 200;
static final int WARMUP_TICKS = 40;
static final int[] PLAYER_COUNTS = {10, 20, 40, 60, 80, 100};
// ── Diamond tag graph ─────────────────────────────────────────────────────
static Map<String, List<String>> buildDiamondTags(int depth, String prefix) {
Map<String, List<String>> deps = new LinkedHashMap<>();
deps.put(prefix + "_base", List.of());
String prevLeft = prefix + "_base", prevRight = prefix + "_base";
for (int d = 1; d <= depth; d++) {
String left = prefix + "_L" + d;
String right = prefix + "_R" + d;
deps.put(left, List.of(prevLeft, prevRight));
deps.put(right, List.of(prevLeft, prevRight));
prevLeft = left; prevRight = right;
}
deps.put(prefix + "_root", List.of(prevLeft, prevRight));
return deps;
}
/** All tag namespaces merged — simulates a full modpack tag registry. */
static List<Map<String, List<String>>> buildModpackTags(int depth, int reps) {
List<Map<String, List<String>>> all = new ArrayList<>();
for (int i = 0; i < reps; i++) all.add(buildDiamondTags(depth, "ns" + i));
return all;
}
// ── VANILLA: isCyclic without visited set (O(2^D)) ────────────────────────
static boolean isCyclicVanilla(Multimap<String,String> m, String from, String to) {
Collection<String> d = m.get(to);
if (d.contains(from)) return true;
return d.stream().anyMatch(dep -> isCyclicVanilla(m, from, dep));
}
static void addDepVanilla(Multimap<String,String> m, String from, String to) {
if (!isCyclicVanilla(m, from, to)) m.put(from, to);
}
static int resolveVanilla(List<Map<String,List<String>>> tagSpaces) {
int total = 0;
for (Map<String,List<String>> tags : tagSpaces) {
HashMultimap<String,String> m = HashMultimap.create();
for (Map.Entry<String,List<String>> e : tags.entrySet())
for (String dep : e.getValue()) addDepVanilla(m, e.getKey(), dep);
total += m.size();
}
return total;
}
// ── PATCHED: isCyclic with visited set (O(V+E)) ───────────────────────────
static boolean isCyclicPatched(Multimap<String,String> m, String from, String to, Set<String> seen) {
if (!seen.add(to)) return false;
Collection<String> d = m.get(to);
if (d.contains(from)) return true;
return d.stream().anyMatch(dep -> isCyclicPatched(m, from, dep, seen));
}
static void addDepPatched(Multimap<String,String> m, String from, String to) {
if (!isCyclicPatched(m, from, to, new HashSet<>())) m.put(from, to);
}
static int resolvePatched(List<Map<String,List<String>>> tagSpaces) {
int total = 0;
for (Map<String,List<String>> tags : tagSpaces) {
HashMultimap<String,String> m = HashMultimap.create();
for (Map.Entry<String,List<String>> e : tags.entrySet())
for (String dep : e.getValue()) addDepPatched(m, e.getKey(), dep);
total += m.size();
}
return total;
}
// ── VANILLA: redstone wire eval — Deque membership O(W) ──────────────────
static long tickRedstoneVanilla(int players, int wiresPerPlayer) {
long ops = 0;
for (int p = 0; p < players; p++) {
ArrayDeque<Integer> wiresToProcess = new ArrayDeque<>();
ArrayDeque<Integer> wiresToTurnOff = new ArrayDeque<>();
// seed wires
for (int w = 0; w < wiresPerPlayer; w++) wiresToProcess.add(w);
while (!wiresToProcess.isEmpty()) {
int wire = wiresToProcess.poll();
if (!wiresToTurnOff.contains(wire)) { // O(W) — the defect
wiresToTurnOff.add(wire);
ops++;
// propagate to ~3 neighbours
if (wire > 0 && !wiresToTurnOff.contains(wire - 1)) wiresToProcess.add(wire - 1);
if (wire + 1 < wiresPerPlayer && !wiresToTurnOff.contains(wire + 1)) wiresToProcess.add(wire + 1);
}
}
}
return ops;
}
// ── PATCHED: redstone wire eval — HashSet companion O(1) ─────────────────
static long tickRedstonePatched(int players, int wiresPerPlayer) {
long ops = 0;
for (int p = 0; p < players; p++) {
ArrayDeque<Integer> wiresToProcess = new ArrayDeque<>();
ArrayDeque<Integer> wiresToTurnOff = new ArrayDeque<>();
Set<Integer> wiresToTurnOffSet = new HashSet<>();
for (int w = 0; w < wiresPerPlayer; w++) wiresToProcess.add(w);
while (!wiresToProcess.isEmpty()) {
int wire = wiresToProcess.poll();
if (wiresToTurnOffSet.add(wire)) { // O(1) — the fix
wiresToTurnOff.add(wire);
ops++;
if (wire > 0 && !wiresToTurnOffSet.contains(wire - 1)) wiresToProcess.add(wire - 1);
if (wire + 1 < wiresPerPlayer && !wiresToTurnOffSet.contains(wire + 1)) wiresToProcess.add(wire + 1);
}
}
}
return ops;
}
// ── Percentile helper ─────────────────────────────────────────────────────
static long pct(long[] sorted, double p) {
int i = (int) Math.ceil(p / 100.0 * sorted.length) - 1;
return sorted[Math.max(0, Math.min(sorted.length - 1, i))];
}
// ── Simulation 1: World load — concurrent joins ───────────────────────────
static void simWorldLoad(int players) throws Exception {
List<Map<String,List<String>>> modpack = buildModpackTags(TAG_DEPTH, TAG_GRAPH_REPS);
ExecutorService pool = Executors.newFixedThreadPool(players);
long[] latVanilla = new long[players];
long[] latPatched = new long[players];
CountDownLatch startGate = new CountDownLatch(1);
// --- VANILLA ---
List<Future<?>> futures = new ArrayList<>();
for (int i = 0; i < players; i++) {
final int idx = i;
futures.add(pool.submit(() -> {
try { startGate.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
long t0 = System.nanoTime();
resolveVanilla(modpack);
latVanilla[idx] = System.nanoTime() - t0;
}));
}
long wallStart = System.nanoTime();
startGate.countDown();
for (Future<?> f : futures) f.get();
long vanillaWall = System.nanoTime() - wallStart;
// --- PATCHED ---
CountDownLatch gate2 = new CountDownLatch(1);
futures.clear();
for (int i = 0; i < players; i++) {
final int idx = i;
futures.add(pool.submit(() -> {
try { gate2.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); }
long t0 = System.nanoTime();
resolvePatched(modpack);
latPatched[idx] = System.nanoTime() - t0;
}));
}
long wallStart2 = System.nanoTime();
gate2.countDown();
for (Future<?> f : futures) f.get();
long patchedWall = System.nanoTime() - wallStart2;
pool.shutdown();
Arrays.sort(latVanilla);
Arrays.sort(latPatched);
long vp50 = pct(latVanilla, 50), vp95 = pct(latVanilla, 95), vp99 = pct(latVanilla, 99);
long pp50 = pct(latPatched, 50), pp95 = pct(latPatched, 95), pp99 = pct(latPatched, 99);
System.out.printf(" %4d players | wall: %6.1f s → %5.3f s (%5.1f×) | p50 %5.0f ms → %4.0f ms | p99 %5.0f ms → %4.0f ms%n",
players,
vanillaWall / 1e9, patchedWall / 1e9, (double) vanillaWall / patchedWall,
vp50 / 1e6, pp50 / 1e6,
vp99 / 1e6, pp99 / 1e6);
}
// ── Simulation 2: TPS stability under load ────────────────────────────────
static void simTPS(int players, boolean patched) {
int overruns = 0;
long totalTickMs = 0;
long worstTickMs = 0;
for (int tick = -WARMUP_TICKS; tick < TICKS_TO_SIMULATE; tick++) {
long t0 = System.nanoTime();
if (patched) tickRedstonePatched(players, WIRES_PER_PLAYER);
else tickRedstoneVanilla(players, WIRES_PER_PLAYER);
long tickMs = (System.nanoTime() - t0) / 1_000_000;
if (tick >= 0) {
totalTickMs += tickMs;
if (tickMs > TICK_BUDGET_MS) overruns++;
if (tickMs > worstTickMs) worstTickMs = tickMs;
}
}
double avgTickMs = (double) totalTickMs / TICKS_TO_SIMULATE;
double achievedTPS = 1000.0 / Math.max(avgTickMs, 1);
double overrunPct = 100.0 * overruns / TICKS_TO_SIMULATE;
System.out.printf(" %4d players | avg tick %5.1f ms | worst %4d ms | overruns %4.0f%% | TPS ~%.1f%n",
players, avgTickMs, worstTickMs, overrunPct, Math.min(20.0, achievedTPS));
}
// ── Main ──────────────────────────────────────────────────────────────────
public static void main(String[] args) throws Exception {
System.out.println("=================================================================");
System.out.println(" LoadSimBenchmark — Minecraft Server Load Simulation");
System.out.println("=================================================================");
System.out.printf(" Modpack profile: depth-%d diamond tag graph × %d namespaces%n", TAG_DEPTH, TAG_GRAPH_REPS);
System.out.printf(" Redstone profile: %d active wires per player base%n", WIRES_PER_PLAYER);
System.out.printf(" TPS target: 20 TPS (%d ms/tick budget)%n", TICK_BUDGET_MS);
System.out.println();
// ── Section 1: World load ──────────────────────────────────────────────
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.println(" §1 World Load / /reload (all players blocked until complete)");
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.printf(" %-12s %-44s %-24s %-20s%n",
"Players", "Wall time (VANILLA → PATCHED)", "p50 join latency", "p99 join latency");
System.out.println(" " + "-".repeat(100));
// warmup
List<Map<String,List<String>>> modpack = buildModpackTags(TAG_DEPTH, TAG_GRAPH_REPS);
for (int i = 0; i < 3; i++) { resolveVanilla(modpack); resolvePatched(modpack); }
for (int n : PLAYER_COUNTS) simWorldLoad(n);
System.out.println();
// ── Section 2: TPS — VANILLA ──────────────────────────────────────────
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.println(" §2 Game Loop TPS — VANILLA [EXPLORATORY — wire count uncalibrated]");
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.printf(" %-12s %-22s %-18s %-16s %-12s%n",
"Players", "Avg tick ms", "Worst tick ms", "Overrun %", "Achieved TPS");
System.out.println(" " + "-".repeat(80));
for (int n : PLAYER_COUNTS) simTPS(n, false);
System.out.println();
// ── Section 3: TPS — PATCHED ──────────────────────────────────────────
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.println(" §3 Game Loop TPS — PATCHED [EXPLORATORY — wire count uncalibrated]");
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.printf(" %-12s %-22s %-18s %-16s %-12s%n",
"Players", "Avg tick ms", "Worst tick ms", "Overrun %", "Achieved TPS");
System.out.println(" " + "-".repeat(80));
for (int n : PLAYER_COUNTS) simTPS(n, true);
System.out.println();
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.println(" §4 Summary");
System.out.println("─────────────────────────────────────────────────────────────────");
System.out.printf(" §1 World load [algorithm isolation]:%n");
System.out.printf(" DependencySorter.isCyclic depth-%d, O(2^D) → O(V+E)%n", TAG_DEPTH);
System.out.printf(" Real server baseline: vanilla 19,255 ms → patched 3,087 ms (6.2×)%n");
System.out.printf(" §2/§3 Redstone TPS [exploratory — wire count uncalibrated]:%n");
System.out.printf(" ExperimentalRedstoneWireEvaluator, O(W) → O(1), %d wires/player assumed%n", WIRES_PER_PLAYER);
System.out.printf(" minecraft-0003 defect confirmed; TPS numbers require real measurement%n");
System.out.println(" ─────────────────────────────────────────────────────────────");
System.out.println(" Confirmed: DependencySorter fix eliminates exponential world load.");
System.out.println(" Exploratory: redstone fix may improve TPS at high wire density.");
System.out.println(" Do not cite §2/§3 TPS numbers without a real server calibration.");
System.out.println("=================================================================");
}
}