bazel-0003 + kicad-0002: build toolchain feature check + PCB zone filler O(Z²×L²); count 601→603
This commit is contained in:
parent
1d6a8b8ccd
commit
212d313185
292 changed files with 924 additions and 7 deletions
151
defects/bazel/unit/BazelFeatureSelectionAlgorithmTest.java
Normal file
151
defects/bazel/unit/BazelFeatureSelectionAlgorithmTest.java
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Models Bazel FeatureSelection.run() provides-conflict check.
|
||||
*
|
||||
* SLOW: O(P×S×L) — ImmutableList.contains() O(L) per selectable in P×S nested loops.
|
||||
* FAST: O(P×S) — HashSet built once from enabledList; O(1) per lookup.
|
||||
*
|
||||
* CWE-407: src/main/java/com/google/devtools/build/lib/rules/cpp/FeatureSelection.java:159
|
||||
*/
|
||||
public class BazelFeatureSelectionAlgorithmTest {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Slow — ImmutableList.contains() O(L) per lookup
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static class SlowFeatureSelection {
|
||||
long cmpOps = 0;
|
||||
|
||||
boolean listContains(List<String> list, String val) {
|
||||
for (String s : list) {
|
||||
cmpOps++;
|
||||
if (s.equals(val)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* O(P × S × L): for each provide × selectable, check enabledList membership.
|
||||
* Returns count of conflict checks performed.
|
||||
*/
|
||||
int run(List<String> enabledList,
|
||||
Map<String, List<String>> providesMap) {
|
||||
int conflicts = 0;
|
||||
for (Map.Entry<String, List<String>> entry : providesMap.entrySet()) {
|
||||
for (String selectable : entry.getValue()) {
|
||||
if (listContains(enabledList, selectable)) {
|
||||
conflicts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return conflicts;
|
||||
}
|
||||
|
||||
long ops(List<String> enabledList, Map<String, List<String>> providesMap) {
|
||||
cmpOps = 0;
|
||||
run(enabledList, providesMap);
|
||||
return cmpOps;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Fast — HashSet built once before loop
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static class FastFeatureSelection {
|
||||
long cmpOps = 0;
|
||||
|
||||
int run(List<String> enabledList,
|
||||
Map<String, List<String>> providesMap) {
|
||||
Set<String> enabledSet = new HashSet<>(enabledList);
|
||||
cmpOps += enabledList.size(); // build cost
|
||||
int conflicts = 0;
|
||||
for (Map.Entry<String, List<String>> entry : providesMap.entrySet()) {
|
||||
for (String selectable : entry.getValue()) {
|
||||
cmpOps++;
|
||||
if (enabledSet.contains(selectable)) {
|
||||
conflicts++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return conflicts;
|
||||
}
|
||||
|
||||
long ops(List<String> enabledList, Map<String, List<String>> providesMap) {
|
||||
cmpOps = 0;
|
||||
run(enabledList, providesMap);
|
||||
return cmpOps;
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Build test data
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
static List<String> makeEnabledList(int l) {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (int i = 0; i < l; i++) list.add("feature_" + i);
|
||||
return list;
|
||||
}
|
||||
|
||||
static Map<String, List<String>> makeProvidesMap(int p, int s, int overlapStart) {
|
||||
Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
for (int i = 0; i < p; i++) {
|
||||
List<String> sels = new ArrayList<>();
|
||||
for (int j = 0; j < s; j++) {
|
||||
// Some selectables are in enabledList (conflicts), some not
|
||||
sels.add("feature_" + (overlapStart + i * s + j));
|
||||
}
|
||||
map.put("provide_" + i, sels);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SlowFeatureSelection slow = new SlowFeatureSelection();
|
||||
FastFeatureSelection fast = new FastFeatureSelection();
|
||||
|
||||
int passed = 0, total = 0;
|
||||
|
||||
System.out.println("=== bazel-0003: FeatureSelection ImmutableList.contains O(P×S×L) ===");
|
||||
|
||||
// (L, P, S) configurations matching realistic Bazel C++ toolchain sizes
|
||||
int[][] configs = {
|
||||
{50, 7, 6}, // small toolchain
|
||||
{80, 7, 6}, // realistic (agent's estimate)
|
||||
{150, 10, 8}, // large toolchain
|
||||
{300, 15, 10} // extreme
|
||||
};
|
||||
for (int[] cfg : configs) {
|
||||
int l = cfg[0], p = cfg[1], s = cfg[2];
|
||||
List<String> enabled = makeEnabledList(l);
|
||||
Map<String, List<String>> provides = makeProvidesMap(p, s, 0);
|
||||
|
||||
long sv = slow.ops(enabled, provides);
|
||||
long fv = fast.ops(enabled, provides);
|
||||
double ratio = (double) sv / Math.max(fv, 1);
|
||||
|
||||
total++;
|
||||
boolean ok = sv > fv && ratio >= 5.0;
|
||||
System.out.printf("L=%3d P=%2d S=%2d slow=%7d fast=%5d ratio=%6.1fx %s%n",
|
||||
l, p, s, sv, fv, ratio, ok ? "PASS" : "FAIL");
|
||||
if (ok) passed++;
|
||||
}
|
||||
|
||||
// Correctness: both count same conflicts
|
||||
List<String> enabled = makeEnabledList(80);
|
||||
Map<String, List<String>> provides = makeProvidesMap(7, 6, 0);
|
||||
int sc = slow.run(enabled, provides);
|
||||
int fc = fast.run(enabled, provides);
|
||||
total++;
|
||||
boolean correct = sc == fc;
|
||||
System.out.printf("conflict count matches (%d): %s%n", sc, correct ? "PASS" : "FAIL");
|
||||
if (correct) passed++;
|
||||
|
||||
System.out.printf("%n%d/%d PASS%n", passed, total);
|
||||
if (passed < total) System.exit(1);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue