java-topology/defects/ray-project/test/RayProjectTest.java
russell@unturf.com 13a4de8613 transformers-0001/ray-project-0001/dask-project-0001/dask-project-0002: 4 CWE-407 defects across 3 ML/data targets
transformers-0001: tokenization_python convert_ids_to_tokens O(T×S) property-rebuild-per-token MEDIUM 3.1x
ray-project-0001: dag_node _get_toplevel_child_nodes O(A²) list dedup MEDIUM 1.5x
dask-project-0001: parquet filter_partitions disjunction O(P×O) list dedup MEDIUM-HIGH 65x
dask-project-0002: methods describe_aggregate O(C²) column name dedup LOW-MEDIUM 12.7x
2026-03-31 07:48:07 -04:00

95 lines
3.3 KiB
Java

import java.util.*;
/**
* Unit test for ray-project-0001: dag_node.py _get_toplevel_child_nodes O(A²) dedup
*
* CWE-407 — Algorithmic Complexity
*
* DAGNode._get_toplevel_child_nodes() uses `if a not in children` on a list
* for deduplication, making it O(A²) where A = number of DAG arguments.
* Fix: maintain a parallel set for O(1) membership.
*/
public class RayProjectTest {
/** Simulates a DAGNode with an ID for identity comparison */
static class FakeDAGNode {
final int nodeId;
FakeDAGNode(int id) { this.nodeId = id; }
@Override
public boolean equals(Object o) {
return o instanceof FakeDAGNode && ((FakeDAGNode) o).nodeId == this.nodeId;
}
@Override
public int hashCode() { return nodeId; }
}
/** DEFECTIVE: linear scan on list for dedup — O(A²) */
static List<FakeDAGNode> getChildrenDefective(List<FakeDAGNode> args) {
List<FakeDAGNode> children = new ArrayList<>();
for (FakeDAGNode a : args) {
if (!children.contains(a)) {
children.add(a);
}
}
return children;
}
/** FIXED: set-based dedup — O(A) */
static List<FakeDAGNode> getChildrenFixed(List<FakeDAGNode> args) {
List<FakeDAGNode> children = new ArrayList<>();
Set<Integer> childrenIds = new HashSet<>();
for (FakeDAGNode a : args) {
if (childrenIds.add(System.identityHashCode(a))) {
children.add(a);
}
}
return children;
}
public static void main(String[] args) {
// Create A=500 unique DAG nodes, with ~50% duplicates
int A = 500;
List<FakeDAGNode> nodes = new ArrayList<>();
for (int i = 0; i < A; i++) nodes.add(new FakeDAGNode(i));
// Build args list with duplicates
List<FakeDAGNode> argsList = new ArrayList<>();
Random rng = new Random(42);
for (int i = 0; i < A * 2; i++) {
argsList.add(nodes.get(rng.nextInt(A)));
}
// Correctness
List<FakeDAGNode> resultDefective = getChildrenDefective(argsList);
List<FakeDAGNode> resultFixed = getChildrenFixed(argsList);
assert resultDefective.size() == resultFixed.size() : "FAIL: sizes differ";
// Warmup
for (int w = 0; w < 5; w++) {
getChildrenDefective(argsList);
getChildrenFixed(argsList);
}
// Benchmark
int iterations = 500;
long t0 = System.nanoTime();
for (int i = 0; i < iterations; i++) {
getChildrenDefective(argsList);
}
long defectiveNs = System.nanoTime() - t0;
t0 = System.nanoTime();
for (int i = 0; i < iterations; i++) {
getChildrenFixed(argsList);
}
long fixedNs = System.nanoTime() - t0;
double ratio = (double) defectiveNs / fixedNs;
System.out.printf("ray-project-0001 (_get_toplevel_child_nodes O(A²) → O(A))%n");
System.out.printf(" A=%d args (with duplicates), %d iterations%n", A * 2, iterations);
System.out.printf(" defective: %,d ns%n", defectiveNs);
System.out.printf(" fixed: %,d ns%n", fixedNs);
System.out.printf(" ratio: %.1fx%n", ratio);
System.out.printf(" PASS (ratio=%.1f)%n", ratio);
}
}