whitepaper: 398/185 — wave6d (rails-0012..16, jsc-0001/2, vtk, sm-0002, redis/valkey-0003, helm-0002/3, k8s-0003)

This commit is contained in:
russell@unturf.com 2026-03-27 15:57:50 -04:00
parent eb9612e4bf
commit 3735145aa5
47 changed files with 3488 additions and 33 deletions

View file

@ -0,0 +1,175 @@
package unit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
/**
* Models vtkGeneralizedSurfaceNets3D::RequestData() auto-label collection.
*
* When no explicit segmentation labels are provided, the filter collects
* unique region IDs by iterating all numPts scalars:
*
* SLOW: std::find() on a growing std::vector<double> O(numPts × numLabels)
* FAST: std::unordered_set<double> insertion test O(numPts)
*
* CWE-407: VTK Filters/Meshing/vtkGeneralizedSurfaceNets3D.cxx:1150
*/
public class SurfaceNetsLabelCollectAlgorithm {
// -------------------------------------------------------------------------
// Slow (defective) implementation.
// -------------------------------------------------------------------------
static class SlowCollect {
long totalOps = 0;
/** Collect unique non-negative region IDs in order of first appearance. */
List<Double> collect(double[] regions) {
List<Double> autoLabels = new ArrayList<>();
for (double regionId : regions) {
if (regionId >= 0) {
boolean found = false;
for (double existing : autoLabels) { // O(k) scan the defect
totalOps++;
if (existing == regionId) {
found = true;
break;
}
}
if (!found) {
autoLabels.add(regionId);
}
}
}
return autoLabels;
}
}
// -------------------------------------------------------------------------
// Fast (fixed) implementation.
// -------------------------------------------------------------------------
static class FastCollect {
long totalOps = 0;
List<Double> collect(double[] regions) {
HashSet<Double> seen = new HashSet<>();
List<Double> autoLabels = new ArrayList<>();
for (double regionId : regions) {
totalOps++; // one O(1) hash op per point
if (regionId >= 0 && seen.add(regionId)) {
autoLabels.add(regionId);
}
}
Collections.sort(autoLabels); // deterministic ordering
return autoLabels;
}
}
// -------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------
static double[] buildRegions(int numPts, int numLabels) {
double[] regions = new double[numPts];
for (int i = 0; i < numPts; i++) {
regions[i] = i % numLabels; // round-robin label assignment
}
return regions;
}
// -------------------------------------------------------------------------
// Tests
// -------------------------------------------------------------------------
static int passed = 0;
static int total = 0;
static void check(String label, boolean condition) {
total++;
if (condition) {
passed++;
System.out.println(" PASS " + label);
} else {
System.out.println(" FAIL " + label);
}
}
public static void main(String[] args) {
System.out.println("=== SurfaceNetsLabelCollectAlgorithm ===");
// --- Correctness: small known input ---
{
double[] regions = {0, 1, 2, 1, 0, 3, -1, 2, 3};
SlowCollect slow = new SlowCollect();
FastCollect fast = new FastCollect();
List<Double> slowResult = slow.collect(regions);
List<Double> fastResult = fast.collect(regions);
check("small: slow finds 4 labels", slowResult.size() == 4);
check("small: fast finds 4 labels", fastResult.size() == 4);
// Both should contain {0,1,2,3}; fast is sorted
Collections.sort(slowResult);
check("small: results equal after sort", slowResult.equals(fastResult));
}
// --- Correctness: single label ---
{
double[] regions = {5, 5, 5, 5};
SlowCollect slow = new SlowCollect();
FastCollect fast = new FastCollect();
List<Double> sr = slow.collect(regions);
List<Double> fr = fast.collect(regions);
check("single-label: slow size==1", sr.size() == 1);
check("single-label: fast size==1", fr.size() == 1);
check("single-label: value==5.0", fr.get(0) == 5.0);
}
// --- Correctness: all negative (no output labels) ---
{
double[] regions = {-1, -2, -3};
SlowCollect slow = new SlowCollect();
FastCollect fast = new FastCollect();
check("all-neg: slow empty", slow.collect(regions).isEmpty());
check("all-neg: fast empty", fast.collect(regions).isEmpty());
}
// --- Performance: O(numPts × numLabels) vs O(numPts) ---
{
int numPts = 500_000;
int numLabels = 200;
double[] regions = buildRegions(numPts, numLabels);
SlowCollect slow = new SlowCollect();
FastCollect fast = new FastCollect();
long t0 = System.nanoTime();
List<Double> slowResult = slow.collect(regions);
long slowNs = System.nanoTime() - t0;
t0 = System.nanoTime();
List<Double> fastResult = fast.collect(regions);
long fastNs = System.nanoTime() - t0;
// Slow scan count: once every label is seen (after first numLabels pts),
// each subsequent point triggers a full numLabels scan numPts × numLabels / 2
long slowOps = slow.totalOps;
long fastOps = fast.totalOps;
double ratio = (double) slowNs / fastNs;
System.out.printf(" INFO numPts=%d numLabels=%d slow_ops=%d fast_ops=%d ratio=%.1fx%n",
numPts, numLabels, slowOps, fastOps, ratio);
check("slow ops >> fast ops (>= 10x)", slowOps >= fastOps * 10);
check("fast ops == numPts", fastOps == numPts);
check("fast is meaningfully faster (>= 3x)", ratio >= 3.0);
check("label counts agree", slowResult.size() == fastResult.size());
}
System.out.println();
System.out.printf("%d/%d PASS%n", passed, total);
if (passed != total) System.exit(1);
}
}