wave6a/6b: elasticsearch/opensearch/solr/llvm-0004-5/linux-0005-6/gcc-0002/tokio/actix-web + love2d/raylib new defects
This commit is contained in:
parent
a4b0cf4edd
commit
3eebda37e1
38 changed files with 3651 additions and 0 deletions
147
defects/llvm/unit/LlvmDomConditionCacheTest.java
Normal file
147
defects/llvm/unit/LlvmDomConditionCacheTest.java
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit test for llvm-0004: DomConditionCache::registerBranch O(B^2) defect.
|
||||
*
|
||||
* Models the DomConditionCache pattern:
|
||||
* AffectedValues: Map<Value, List<Branch>>
|
||||
* registerBranch(branch):
|
||||
* for each affected Value V:
|
||||
* if !AV[V].contains(branch): // O(|AV[V]|) — the defect
|
||||
* AV[V].add(branch)
|
||||
*
|
||||
* Slow path: is_contained() = List.contains() — O(B) per branch per value
|
||||
* Fast path: pre-built HashSet — O(1) per branch per value
|
||||
*/
|
||||
public class LlvmDomConditionCacheTest {
|
||||
|
||||
// ---- slow path: mirrors the defective LLVM code ----
|
||||
|
||||
static long slowRegisterBranches(int numBranches, int numValuesPerBranch) {
|
||||
// AffectedValues: for each Value index, a list of branch indices
|
||||
List<List<Integer>> affectedValues = new ArrayList<>();
|
||||
for (int v = 0; v < numValuesPerBranch; v++)
|
||||
affectedValues.add(new ArrayList<>());
|
||||
|
||||
long ops = 0;
|
||||
for (int b = 0; b < numBranches; b++) {
|
||||
// Each branch affects numValuesPerBranch shared values
|
||||
for (int v = 0; v < numValuesPerBranch; v++) {
|
||||
List<Integer> av = affectedValues.get(v);
|
||||
// O(|av|) scan — the defect
|
||||
ops++;
|
||||
boolean found = false;
|
||||
for (int existing : av) { // linear scan
|
||||
ops++;
|
||||
if (existing == b) { found = true; break; }
|
||||
}
|
||||
if (!found) av.add(b);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// ---- fast path: pre-built set for O(1) membership ----
|
||||
|
||||
static long fastRegisterBranches(int numBranches, int numValuesPerBranch) {
|
||||
List<Set<Integer>> affectedSets = new ArrayList<>();
|
||||
for (int v = 0; v < numValuesPerBranch; v++)
|
||||
affectedSets.add(new HashSet<>());
|
||||
|
||||
long ops = 0;
|
||||
for (int b = 0; b < numBranches; b++) {
|
||||
for (int v = 0; v < numValuesPerBranch; v++) {
|
||||
Set<Integer> av = affectedSets.get(v);
|
||||
ops++; // O(1) hash lookup
|
||||
av.add(b);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// ---- correctness: both paths produce same AV lists ----
|
||||
|
||||
static boolean correctnessCheck(int branches, int valuesPerBranch) {
|
||||
List<List<Integer>> slowAV = new ArrayList<>();
|
||||
for (int v = 0; v < valuesPerBranch; v++)
|
||||
slowAV.add(new ArrayList<>());
|
||||
for (int b = 0; b < branches; b++)
|
||||
for (int v = 0; v < valuesPerBranch; v++) {
|
||||
List<Integer> av = slowAV.get(v);
|
||||
if (!av.contains(b)) av.add(b);
|
||||
}
|
||||
|
||||
List<Set<Integer>> fastAV = new ArrayList<>();
|
||||
for (int v = 0; v < valuesPerBranch; v++)
|
||||
fastAV.add(new HashSet<>());
|
||||
for (int b = 0; b < branches; b++)
|
||||
for (int v = 0; v < valuesPerBranch; v++)
|
||||
fastAV.get(v).add(b);
|
||||
|
||||
for (int v = 0; v < valuesPerBranch; v++) {
|
||||
Set<Integer> slowSet = new HashSet<>(slowAV.get(v));
|
||||
if (!slowSet.equals(fastAV.get(v))) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int pass = 0, total = 0;
|
||||
|
||||
// Test 1: correctness small
|
||||
total++;
|
||||
if (correctnessCheck(10, 3)) { pass++; System.out.println("PASS test1: correctness (10 branches, 3 values)"); }
|
||||
else System.out.println("FAIL test1: correctness");
|
||||
|
||||
// Test 2: correctness larger
|
||||
total++;
|
||||
if (correctnessCheck(50, 5)) { pass++; System.out.println("PASS test2: correctness (50 branches, 5 values)"); }
|
||||
else System.out.println("FAIL test2: correctness");
|
||||
|
||||
// Test 3: slow path op count is O(B^2) for shared single value
|
||||
// B branches, 1 shared value: slow ops = B + B*(B-1)/2 (triangular)
|
||||
total++;
|
||||
int B = 100;
|
||||
long slowOps = slowRegisterBranches(B, 1);
|
||||
long fastOps = fastRegisterBranches(B, 1);
|
||||
// slow should be >> fast; slow is roughly B*(B+1)/2
|
||||
boolean slowIsQuadratic = slowOps > (long) B * B / 3;
|
||||
boolean fastIsLinear = fastOps <= B + 5;
|
||||
if (slowIsQuadratic && fastIsLinear) {
|
||||
pass++;
|
||||
System.out.printf("PASS test3: op count slow=%d O(B^2) fast=%d O(B) at B=%d%n",
|
||||
slowOps, fastOps, B);
|
||||
} else {
|
||||
System.out.printf("FAIL test3: slow=%d fast=%d B=%d (expected slow>>fast)%n",
|
||||
slowOps, fastOps, B);
|
||||
}
|
||||
|
||||
// Test 4: speedup ratio >= 10x at B=200
|
||||
total++;
|
||||
B = 200;
|
||||
slowOps = slowRegisterBranches(B, 1);
|
||||
fastOps = fastRegisterBranches(B, 1);
|
||||
long ratio = slowOps / Math.max(fastOps, 1);
|
||||
if (ratio >= 10) {
|
||||
pass++;
|
||||
System.out.printf("PASS test4: speedup %dx at B=%d (slow=%d fast=%d)%n",
|
||||
ratio, B, slowOps, fastOps);
|
||||
} else {
|
||||
System.out.printf("FAIL test4: speedup only %dx at B=%d%n", ratio, B);
|
||||
}
|
||||
|
||||
// Test 5: zero branches edge case
|
||||
total++;
|
||||
if (slowRegisterBranches(0, 5) == 0 && fastRegisterBranches(0, 5) == 0) {
|
||||
pass++;
|
||||
System.out.println("PASS test5: empty input");
|
||||
} else {
|
||||
System.out.println("FAIL test5: empty input");
|
||||
}
|
||||
|
||||
System.out.printf("%n%d/%d PASS%n", pass, total);
|
||||
if (pass != total) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue