whitepaper: 352/169 — wave4 MEDIUM (hadoop/hbase/nova/neutron/openstack) + fix odl-0002 dup
This commit is contained in:
parent
9934133dcf
commit
835ae73b0f
82 changed files with 5931 additions and 6 deletions
89
defects/cmake/unit/AddSourceAlgorithm.java
Normal file
89
defects/cmake/unit/AddSourceAlgorithm.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* CWE-407 unit test: cmake-0004
|
||||
* AddSource — O(n²) std::find_if per call in Unity build loop vs O(n) set guard.
|
||||
*
|
||||
* Simulates cmTarget::AddSource called in loop over unity_files:
|
||||
* slow: scan Sources.Entries vector (find_if) for each add → O(n²)
|
||||
* fast: use HashSet shadow, skip scan if already present → O(n)
|
||||
*/
|
||||
public class AddSourceAlgorithm {
|
||||
|
||||
// Slow: O(n^2) — find_if scan per AddSource call (mirrors TargetPropertyEntryFinder)
|
||||
static long slowAddSources(List<String> unityFiles) {
|
||||
long ops = 0;
|
||||
List<String> sourcesEntries = new ArrayList<>();
|
||||
for (String src : unityFiles) {
|
||||
boolean found = false;
|
||||
for (String existing : sourcesEntries) { // O(n) scan
|
||||
ops++;
|
||||
if (existing.equals(src)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
sourcesEntries.add(src);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// Fast: HashSet shadow for O(1) check, O(n) total
|
||||
static long fastAddSources(List<String> unityFiles) {
|
||||
long ops = 0;
|
||||
Set<String> sourcePathsSet = new HashSet<>();
|
||||
List<String> sourcesEntries = new ArrayList<>();
|
||||
for (String src : unityFiles) {
|
||||
ops++;
|
||||
if (sourcePathsSet.add(src)) {
|
||||
sourcesEntries.add(src);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] sizes = {200, 500, 1000, 2000};
|
||||
int passed = 0, total = 0;
|
||||
|
||||
for (int S : sizes) {
|
||||
// S unity source files, 20% duplicates (re-added after PCH generation)
|
||||
List<String> unityFiles = new ArrayList<>(S + S / 5);
|
||||
for (int i = 0; i < S; i++) {
|
||||
unityFiles.add("/src/unity_" + i + ".cpp");
|
||||
}
|
||||
for (int i = 0; i < S / 5; i++) {
|
||||
unityFiles.add("/src/unity_" + i + ".cpp"); // duplicate
|
||||
}
|
||||
|
||||
long slowOps = slowAddSources(unityFiles);
|
||||
long fastOps = fastAddSources(unityFiles);
|
||||
double ratio = (double) slowOps / fastOps;
|
||||
|
||||
total++;
|
||||
System.out.printf("S=%4d slow=%8d fast=%6d ratio=%.1fx%n",
|
||||
S, slowOps, fastOps, ratio);
|
||||
// At S=2000: slow is O(S^2/2) ~ 2M, fast is O(S) ~ 2000 → >100x
|
||||
assert ratio > 20.0 : "Expected ratio > 20 at S=" + S + ", got " + ratio;
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Correctness: same unique list preserved
|
||||
List<String> input = Arrays.asList("a.cpp", "b.cpp", "a.cpp", "c.cpp");
|
||||
List<String> slowOut = new ArrayList<>();
|
||||
for (String s : input) {
|
||||
if (!slowOut.contains(s)) slowOut.add(s);
|
||||
}
|
||||
Set<String> fastOut = new LinkedHashSet<>();
|
||||
fastOut.addAll(input);
|
||||
assert new ArrayList<>(fastOut).equals(slowOut) :
|
||||
"Correctness: " + fastOut + " vs " + slowOut;
|
||||
passed++; total++;
|
||||
|
||||
System.out.printf("%d/%d PASS%n", passed, total);
|
||||
}
|
||||
}
|
||||
89
defects/cmake/unit/GetDirectoriesAlgorithm.java
Normal file
89
defects/cmake/unit/GetDirectoriesAlgorithm.java
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* CWE-407 unit test: cmake-0002
|
||||
* GetDirectoriesWithBacktraces — O(n*m) std::find inside loop vs O(n+m) map lookup.
|
||||
*
|
||||
* Simulates CMake's GetDirectoriesWithBacktraces():
|
||||
* slow: for each orderedDir, scan targetLinkDirs linearly → O(n*m)
|
||||
* fast: build HashMap from targetLinkDirs, then lookup → O(n+m)
|
||||
*/
|
||||
public class GetDirectoriesAlgorithm {
|
||||
|
||||
// Slow: O(n*m) — mirrors std::find inside for loop
|
||||
static long slowGetDirectories(List<String> orderedDirs, List<String> targetLinkDirs) {
|
||||
long ops = 0;
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String dir : orderedDirs) {
|
||||
boolean found = false;
|
||||
for (String t : targetLinkDirs) { // O(m) scan per element
|
||||
ops++;
|
||||
if (t.equals(dir)) {
|
||||
result.add(t + "#BT");
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) result.add(dir);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// Fast: O(n+m) — build map then lookup
|
||||
static long fastGetDirectories(List<String> orderedDirs, List<String> targetLinkDirs) {
|
||||
long ops = 0;
|
||||
Map<String, String> dirIndex = new HashMap<>(targetLinkDirs.size() * 2);
|
||||
for (String t : targetLinkDirs) {
|
||||
ops++;
|
||||
dirIndex.put(t, t + "#BT");
|
||||
}
|
||||
List<String> result = new ArrayList<>();
|
||||
for (String dir : orderedDirs) {
|
||||
ops++;
|
||||
String bt = dirIndex.get(dir);
|
||||
result.add(bt != null ? bt : dir);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] sizes = {100, 500, 1000};
|
||||
int passed = 0, total = 0;
|
||||
|
||||
for (int N : sizes) {
|
||||
// Build N ordered dirs, half of which are in targetLinkDirs
|
||||
List<String> orderedDirs = new ArrayList<>(N);
|
||||
List<String> targetLinkDirs = new ArrayList<>(N);
|
||||
for (int i = 0; i < N; i++) {
|
||||
orderedDirs.add("/usr/lib/dir" + i);
|
||||
}
|
||||
for (int i = 0; i < N; i += 2) {
|
||||
targetLinkDirs.add("/usr/lib/dir" + i); // every other dir has BT
|
||||
}
|
||||
|
||||
long slowOps = slowGetDirectories(orderedDirs, targetLinkDirs);
|
||||
long fastOps = fastGetDirectories(orderedDirs, targetLinkDirs);
|
||||
double ratio = (double) slowOps / fastOps;
|
||||
|
||||
total++;
|
||||
System.out.printf("N=%4d slow=%8d fast=%6d ratio=%.1fx%n",
|
||||
N, slowOps, fastOps, ratio);
|
||||
// At N=1000: slow ~ N*M/2 = 250000, fast ~ 3N/2 = 1500 → >100x
|
||||
assert ratio > 5.0 : "Expected slow/fast ratio > 5, got " + ratio;
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Correctness: both produce same result
|
||||
List<String> dirs = Arrays.asList("/a", "/b", "/c");
|
||||
List<String> targets = Arrays.asList("/b");
|
||||
// Just verify no crash and ops make sense
|
||||
long s = slowGetDirectories(dirs, targets);
|
||||
long f = fastGetDirectories(dirs, targets);
|
||||
assert s > 0 && f > 0;
|
||||
passed++; total++;
|
||||
|
||||
System.out.printf("%d/%d PASS%n", passed, total);
|
||||
}
|
||||
}
|
||||
86
defects/cmake/unit/RuntimeDllAlgorithm.java
Normal file
86
defects/cmake/unit/RuntimeDllAlgorithm.java
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* CWE-407 unit test: cmake-0003
|
||||
* AddRuntimeDLL — O(n²) std::find before emplace_back vs O(n) set insertion.
|
||||
*
|
||||
* Simulates CMake's AddRuntimeDLL():
|
||||
* slow: scan vector for membership before push → O(n) per call, O(n²) total
|
||||
* fast: use HashSet for membership check → O(1) per call, O(n) total
|
||||
*/
|
||||
public class RuntimeDllAlgorithm {
|
||||
|
||||
// Slow: mirrors std::find(begin, end, tgt) == end before emplace_back
|
||||
static long slowAddRuntimeDlls(List<Integer> dllIds) {
|
||||
long ops = 0;
|
||||
List<Integer> runtimeDlls = new ArrayList<>();
|
||||
for (int id : dllIds) {
|
||||
boolean found = false;
|
||||
for (int existing : runtimeDlls) { // O(n) scan
|
||||
ops++;
|
||||
if (existing == id) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) runtimeDlls.add(id);
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
// Fast: unordered_set insertion returns bool (inserted = new)
|
||||
static long fastAddRuntimeDlls(List<Integer> dllIds) {
|
||||
long ops = 0;
|
||||
Set<Integer> runtimeDllsSet = new HashSet<>();
|
||||
List<Integer> runtimeDlls = new ArrayList<>();
|
||||
for (int id : dllIds) {
|
||||
ops++;
|
||||
if (runtimeDllsSet.add(id)) {
|
||||
runtimeDlls.add(id);
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] sizes = {100, 500, 1000};
|
||||
int passed = 0, total = 0;
|
||||
|
||||
for (int N : sizes) {
|
||||
// D unique DLLs, each referenced twice (common: transitive deps)
|
||||
List<Integer> dllIds = new ArrayList<>(N * 2);
|
||||
for (int i = 0; i < N; i++) dllIds.add(i);
|
||||
for (int i = 0; i < N; i++) dllIds.add(i); // duplicates
|
||||
|
||||
long slowOps = slowAddRuntimeDlls(dllIds);
|
||||
long fastOps = fastAddRuntimeDlls(dllIds);
|
||||
double ratio = (double) slowOps / fastOps;
|
||||
|
||||
total++;
|
||||
System.out.printf("D=%4d slow=%8d fast=%6d ratio=%.1fx%n",
|
||||
N, slowOps, fastOps, ratio);
|
||||
// At D=1000: slow accumulates O(N²/2)=500k ops, fast=2N=2000
|
||||
assert ratio > 10.0 : "Expected ratio > 10, got " + ratio;
|
||||
passed++;
|
||||
}
|
||||
|
||||
// Correctness: same unique set produced
|
||||
List<Integer> input = Arrays.asList(1, 2, 1, 3, 2, 4);
|
||||
List<Integer> slowResult = new ArrayList<>();
|
||||
Set<Integer> seen = new HashSet<>();
|
||||
for (int id : input) {
|
||||
boolean found = false;
|
||||
for (int x : slowResult) if (x == id) { found = true; break; }
|
||||
if (!found) slowResult.add(id);
|
||||
}
|
||||
Set<Integer> fastResult = new HashSet<>();
|
||||
for (int id : input) fastResult.add(id);
|
||||
assert new HashSet<>(slowResult).equals(fastResult) :
|
||||
"Correctness check failed: " + slowResult + " vs " + fastResult;
|
||||
passed++; total++;
|
||||
|
||||
System.out.printf("%d/%d PASS%n", passed, total);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue