578/240 — rustc-0004/vertx-0001/asterisk-0003/bitcoin-0001/actix-web-0003/hazelcast-0001+0002/rabbitmq-0005/nginx-0003/haproxy-0003/envoy-0003/istio-0003
This commit is contained in:
parent
dde5ec97fb
commit
e4ee168b1e
50 changed files with 4775 additions and 5 deletions
129
defects/binutils/unit/BinutilsUniqueSectionAlgorithm.java
Normal file
129
defects/binutils/unit/BinutilsUniqueSectionAlgorithm.java
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
package unit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Unit test for binutils-0001: ldlang.c unique_section_p O(S×U) linked-list scan.
|
||||
*
|
||||
* Models the defect: for each input section, walk the full unique_section_list
|
||||
* linked list to check membership. Fix: use a HashSet for O(1) lookup.
|
||||
*/
|
||||
public class BinutilsUniqueSectionAlgorithm {
|
||||
|
||||
// --- SLOW: linked-list membership (models ldlang.c unique_section_p) ---
|
||||
|
||||
static class UniqueNode {
|
||||
String name;
|
||||
UniqueNode next;
|
||||
UniqueNode(String n, UniqueNode nxt) { this.name = n; this.next = nxt; }
|
||||
}
|
||||
|
||||
static class SlowResult {
|
||||
long ops;
|
||||
int matches;
|
||||
SlowResult(long ops, int matches) { this.ops = ops; this.matches = matches; }
|
||||
}
|
||||
|
||||
/** O(S*U): for each section scan the full unique_section_list. */
|
||||
static SlowResult slowUniqueSectionP(List<String> sections, UniqueNode listHead) {
|
||||
long ops = 0;
|
||||
int matches = 0;
|
||||
for (String sec : sections) {
|
||||
for (UniqueNode n = listHead; n != null; n = n.next) {
|
||||
ops++;
|
||||
if (n.name.equals(sec)) {
|
||||
matches++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new SlowResult(ops, matches);
|
||||
}
|
||||
|
||||
// --- FAST: hash set membership ---
|
||||
|
||||
static class FastResult {
|
||||
long ops;
|
||||
int matches;
|
||||
FastResult(long ops, int matches) { this.ops = ops; this.matches = matches; }
|
||||
}
|
||||
|
||||
/** O(S): for each section do a hash lookup. */
|
||||
static FastResult fastUniqueSectionP(List<String> sections, Set<String> uniqueSet) {
|
||||
long ops = 0;
|
||||
int matches = 0;
|
||||
for (String sec : sections) {
|
||||
ops++;
|
||||
if (uniqueSet.contains(sec)) {
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
return new FastResult(ops, matches);
|
||||
}
|
||||
|
||||
// --- Test cases ---
|
||||
|
||||
static boolean runTest(String label, int S, int U, int matchFraction) {
|
||||
// Build unique section list: U entries (patterns like ".text.func_NNN")
|
||||
List<String> uniqueNames = new ArrayList<>();
|
||||
for (int i = 0; i < U; i++) {
|
||||
uniqueNames.add(".text.func_" + i);
|
||||
}
|
||||
|
||||
// Build unique_section_list (linked list, head at end for worst-case scan)
|
||||
UniqueNode listHead = null;
|
||||
for (String name : uniqueNames) {
|
||||
listHead = new UniqueNode(name, listHead);
|
||||
}
|
||||
|
||||
// Build hash set version
|
||||
Set<String> uniqueSet = new HashSet<>(uniqueNames);
|
||||
|
||||
// Build S input sections: every (matchFraction)th section matches a unique name
|
||||
List<String> sections = new ArrayList<>();
|
||||
for (int i = 0; i < S; i++) {
|
||||
if (i % matchFraction == 0) {
|
||||
// match a unique name (worst case: last in list → full scan)
|
||||
sections.add(".text.func_" + (i % U));
|
||||
} else {
|
||||
// no match → full scan of entire list
|
||||
sections.add(".rodata.var_" + i);
|
||||
}
|
||||
}
|
||||
|
||||
SlowResult slow = slowUniqueSectionP(sections, listHead);
|
||||
FastResult fast = fastUniqueSectionP(sections, uniqueSet);
|
||||
|
||||
// Verify correctness
|
||||
if (slow.matches != fast.matches) {
|
||||
System.out.printf(" FAIL %s: match count mismatch slow=%d fast=%d%n",
|
||||
label, slow.matches, fast.matches);
|
||||
return false;
|
||||
}
|
||||
|
||||
double ratio = (double) slow.ops / fast.ops;
|
||||
boolean pass = ratio >= 5.0;
|
||||
System.out.printf(" %s %s: S=%d U=%d | SLOW=%d ops FAST=%d ops ratio=%.1fx%n",
|
||||
pass ? "PASS" : "FAIL", label, S, U, slow.ops, fast.ops, ratio);
|
||||
return pass;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int pass = 0, total = 0;
|
||||
|
||||
// Test 1: S=1000, U=100, every 5th section matches (worst-case non-matching: full list scan)
|
||||
total++; if (runTest("S=1000,U=100,match=1/5", 1000, 100, 5)) pass++;
|
||||
|
||||
// Test 2: S=5000, U=500, mostly non-matching (full list scan per section)
|
||||
total++; if (runTest("S=5000,U=500,nomatch", 5000, 500, 999)) pass++;
|
||||
|
||||
// Test 3: S=2000, U=200, all matching (scan until found, avg U/2 each)
|
||||
total++; if (runTest("S=2000,U=200,all-match", 2000, 200, 1)) pass++;
|
||||
|
||||
// Test 4: S=10000, U=1000 (representative embedded RTOS link)
|
||||
total++; if (runTest("S=10000,U=1000,embed", 10000, 1000, 7)) pass++;
|
||||
|
||||
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