java-topology/defects/octave/unit/OctaveVecdimTest.java
russell@unturf.com db29a08762 undefect. CWE-407 — 92 sites, 42 ecosystems
B&W print-friendly diagrams + tinkerpop-0001 + wave-3 proof sections.
Squash of 94 local commits onto remote master.
2026-03-26 19:48:18 -04:00

187 lines
7.1 KiB
Java
Raw 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 unit;
import java.util.ArrayList;
import java.util.Collections;
/**
* Unit tests modelling CWE-407 defect in GNU Octave:
*
* octave-0001 — data.cc and numeric/max.cc: vecdim is already sorted by
* std::sort, but the subsequent loop uses std::find (O(|vecdim|))
* instead of std::binary_search (O(log |vecdim|)).
*
* Modelled as: outer loop over ndims=64 dimensions, inner
* ArrayList.contains() (unsorted scan, O(|vecdim|)) vs
* Collections.binarySearch() on a sorted list (O(log |vecdim|)).
*
* Pure Java stdlib, instrumented operation counts.
*/
public class OctaveVecdimTest {
/**
* Simulate defective path: ndims iterations, std::find scan per iteration.
* vecdim has n entries drawn from [0, ndims).
*/
static long vecdimDefective(int ndims, int vecdimSize) {
ArrayList<Integer> vecdim = new ArrayList<>();
// Populate sorted vecdim with every other dim (representative subset)
for (int i = 0; i < vecdimSize; i++) {
vecdim.add(i * (ndims / vecdimSize));
}
// Mimics std::sort already done — list is sorted
Collections.sort(vecdim);
long ops = 0;
for (int i = 0; i < ndims; i++) {
// O(|vecdim|) — mirrors std::find(vecdim.begin(), vecdim.end(), i)
boolean found = false;
for (int j = 0; j < vecdim.size(); j++) {
ops++;
if (vecdim.get(j).equals(i)) { found = true; break; }
// std::find does not exploit sort order; keep scanning past hits
// would continue, but we break on first match (same as std::find)
}
// remaining iterations for elements not in vecdim scan to the end
if (!found) {
// already counted full scan above — no extra ops needed
}
}
return ops;
}
/**
* Simulate defective path with full scan (no early exit) to model worst
* case where dims not in vecdim cause a full O(|vecdim|) scan.
*/
static long vecdimDefectiveWorstCase(int ndims, int vecdimSize) {
ArrayList<Integer> vecdim = new ArrayList<>();
for (int i = 0; i < vecdimSize; i++) {
vecdim.add(i * (ndims / vecdimSize));
}
Collections.sort(vecdim);
long ops = 0;
for (int i = 0; i < ndims; i++) {
// Full O(|vecdim|) scan regardless (std::find scans all when not found)
for (int j = 0; j < vecdim.size(); j++) {
ops++;
if (vecdim.get(j).equals(i)) break;
}
}
return ops;
}
/**
* Simulate fixed path: ndims iterations, Collections.binarySearch per iteration.
* Each binarySearch is O(log |vecdim|).
*/
static long vecdimFixed(int ndims, int vecdimSize) {
ArrayList<Integer> vecdim = new ArrayList<>();
for (int i = 0; i < vecdimSize; i++) {
vecdim.add(i * (ndims / vecdimSize));
}
Collections.sort(vecdim);
long ops = 0;
for (int i = 0; i < ndims; i++) {
// O(log |vecdim|) — mirrors std::binary_search(vecdim.begin(), vecdim.end(), i)
int lo = 0, hi = vecdim.size() - 1;
while (lo <= hi) {
ops++;
int mid = (lo + hi) >>> 1;
int cmp = vecdim.get(mid).compareTo(i);
if (cmp < 0) lo = mid + 1;
else if (cmp > 0) hi = mid - 1;
else break;
}
}
return ops;
}
// -----------------------------------------------------------------------
// Test methods
// -----------------------------------------------------------------------
/**
* Defective op count must grow as ndims × |vecdim|.
* Confirm: opsLarge > opsSmall × 3 when scaling ndims from 16 to 64.
*/
static void testDefectiveCountGrows() {
long opsSmall = vecdimDefectiveWorstCase(16, 8);
long opsFull = vecdimDefectiveWorstCase(64, 32);
assert opsFull > opsSmall * 3
: "octave-0001: expected super-linear growth, opsSmall=" + opsSmall
+ " opsFull=" + opsFull;
System.out.printf("PASS testDefectiveCountGrows: opsSmall=%d opsFull=%d ratio=%.1fx%n",
opsSmall, opsFull, (double) opsFull / opsSmall);
}
/**
* Fixed op count must be O(ndims × log|vecdim|).
* At ndims=64, vecdimSize=32: ops <= ndims * ceil(log2(32)+1) = 64*6 = 384.
*/
static void testFixedCountLogBound() {
int ndims = 64, vecdimSize = 32;
long ops = vecdimFixed(ndims, vecdimSize);
long bound = (long) ndims * (long) Math.ceil(Math.log(vecdimSize) / Math.log(2) + 1);
assert ops <= bound
: "octave-0001: fixed ops=" + ops + " exceeded log bound=" + bound;
System.out.printf("PASS testFixedCountLogBound: ops=%d bound=%d%n", ops, bound);
}
/**
* Speedup ratio defective/fixed must exceed 5× at ndims=64, vecdimSize=32.
*/
static void testSpeedupRatio() {
int ndims = 64, vecdimSize = 32;
long defOps = vecdimDefectiveWorstCase(ndims, vecdimSize);
long fixOps = vecdimFixed(ndims, vecdimSize);
double ratio = (double) defOps / fixOps;
assert ratio > 5.0
: "octave-0001: speedup ratio " + ratio + " not > 5x";
System.out.printf("PASS testSpeedupRatio: defective=%d fixed=%d ratio=%.1fx%n",
defOps, fixOps, ratio);
}
/**
* Correctness: defective and fixed paths agree on which dims are excluded.
* Both should exclude the same set of dims not present in vecdim.
*/
static void testCorrectnessAgreement() {
int ndims = 64, vecdimSize = 32;
ArrayList<Integer> vecdim = new ArrayList<>();
for (int i = 0; i < vecdimSize; i++) {
vecdim.add(i * (ndims / vecdimSize));
}
Collections.sort(vecdim);
ArrayList<Integer> excludedByFind = new ArrayList<>();
ArrayList<Integer> excludedByBsearch = new ArrayList<>();
for (int i = 0; i < ndims; i++) {
// std::find equivalent
if (!vecdim.contains(i)) excludedByFind.add(i);
// std::binary_search equivalent
if (Collections.binarySearch(vecdim, i) < 0) excludedByBsearch.add(i);
}
assert excludedByFind.equals(excludedByBsearch)
: "octave-0001: correctness mismatch: find=" + excludedByFind
+ " bsearch=" + excludedByBsearch;
System.out.printf("PASS testCorrectnessAgreement: %d dims excluded (identical)%n",
excludedByFind.size());
}
// -----------------------------------------------------------------------
// Main
// -----------------------------------------------------------------------
public static void main(String[] args) {
System.out.println("=== OctaveVecdimTest ===");
testDefectiveCountGrows();
testFixedCountLogBound();
testSpeedupRatio();
testCorrectnessAgreement();
System.out.println("All tests passed.");
}
}