wave8c: 452/202 — envoy/cilium, graph-dbs, elixir/nim, k8s/maven + PDF

This commit is contained in:
russell@unturf.com 2026-03-27 16:38:25 -04:00
parent c4330be5b0
commit 3c0b3edc79
49 changed files with 3820 additions and 8 deletions

View file

@ -0,0 +1,135 @@
package unit;
import java.util.*;
/**
* ElixirMixTopoSortAlgorithm CWE-407 test for elixir-0001
*
* Models Mix.Dep.Converger.topological_sort/1:
* slow: Enum.map(apps, fn app -> Enum.find(deps, ...) end) O(N²)
* fast: Map.new(deps, ...) then Enum.map(apps, dep_index[app]) O(N)
*
* Test: for N deps, slow path does N*N list scans; fast path does N map lookups.
*/
public class ElixirMixTopoSortAlgorithm {
// Simulate a Mix.Dep struct just an app name (atom) and an index
static class MixDep {
final String app;
MixDep(String app) { this.app = app; }
}
// --- SLOW: O(N²) ---
// Enum.map(apps, fn app -> Enum.find(deps, fn dep -> dep.app == app end) end)
static class SlowTopoSort {
long comparisons = 0;
List<MixDep> sort(List<String> apps, List<MixDep> deps) {
List<MixDep> result = new ArrayList<>(apps.size());
for (String app : apps) {
// Enum.find linear scan
MixDep found = null;
for (MixDep dep : deps) {
comparisons++;
if (dep.app.equals(app)) {
found = dep;
break;
}
}
result.add(found);
}
return result;
}
}
// --- FAST: O(N) ---
// dep_index = Map.new(deps, fn dep -> {dep.app, dep} end)
// Enum.map(apps, fn app -> dep_index[app] end)
static class FastTopoSort {
long lookups = 0;
List<MixDep> sort(List<String> apps, List<MixDep> deps) {
// Build index: O(N)
Map<String, MixDep> index = new HashMap<>(deps.size() * 2);
for (MixDep dep : deps) {
index.put(dep.app, dep);
}
// Map lookup: O(1) each
List<MixDep> result = new ArrayList<>(apps.size());
for (String app : apps) {
lookups++;
result.add(index.get(app));
}
return result;
}
}
static List<MixDep> makeDeps(int n) {
List<MixDep> deps = new ArrayList<>(n);
for (int i = 0; i < n; i++) deps.add(new MixDep("dep_" + i));
return deps;
}
static List<String> makeApps(List<MixDep> deps) {
// Simulate topsort returning atoms in some order
List<String> apps = new ArrayList<>(deps.size());
for (MixDep d : deps) apps.add(d.app);
Collections.shuffle(apps, new Random(42));
return apps;
}
public static void main(String[] args) {
int[] sizes = {50, 100, 200, 400};
System.out.println("ElixirMixTopoSortAlgorithm — elixir-0001");
System.out.println(" Pattern: Enum.map + Enum.find(deps) — O(N²) vs Map index — O(N)");
System.out.println();
int passed = 0;
int total = 0;
for (int n : sizes) {
List<MixDep> deps = makeDeps(n);
List<String> apps = makeApps(deps);
SlowTopoSort slow = new SlowTopoSort();
FastTopoSort fast = new FastTopoSort();
List<MixDep> slowResult = slow.sort(apps, deps);
List<MixDep> fastResult = fast.sort(apps, deps);
// Verify both produce same order
boolean same = true;
for (int i = 0; i < apps.size(); i++) {
if (!slowResult.get(i).app.equals(fastResult.get(i).app)) {
same = false;
break;
}
}
// slow should do ~N*N comparisons (worst case); fast should do exactly N lookups
long slowCmp = slow.comparisons;
long fastLkp = fast.lookups;
// For random order, average Enum.find scan is N/2 per element ~N²/2 total
// Fast is always N lookups
boolean slowIsQuadratic = slowCmp >= (long) n * n / 4;
boolean fastIsLinear = fastLkp == n;
total += 3;
if (same) { System.out.println("PASS N=" + n + ": results match"); passed++; }
else { System.out.println("FAIL N=" + n + ": result mismatch"); }
if (slowIsQuadratic) { System.out.println("PASS N=" + n + ": slow O(N²) comparisons=" + slowCmp + " >= N²/4=" + (n * n / 4)); passed++; }
else { System.out.println("FAIL N=" + n + ": slow not quadratic, comparisons=" + slowCmp); }
if (fastIsLinear) { System.out.println("PASS N=" + n + ": fast O(N) lookups=" + fastLkp + " == N=" + n); passed++; }
else { System.out.println("FAIL N=" + n + ": fast not linear, lookups=" + fastLkp); }
}
System.out.println();
System.out.println(passed + "/" + total + " PASS");
if (passed != total) {
throw new AssertionError(passed + "/" + total + " tests passed");
}
}
}