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
160
defects/wasmer/unit/RulesetLinearScanTest.java
Normal file
160
defects/wasmer/unit/RulesetLinearScanTest.java
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* wasmer-0001: Ruleset Vec<Rule> O(n) linear scan on every network operation.
|
||||
*
|
||||
* Models the Ruleset.allows_socket() hot path:
|
||||
* slow: rules stored as flat List, every check scans all rules (O(n))
|
||||
* fast: rules partitioned by type at insert time; socket check only scans
|
||||
* ip_rules, domain check only scans dns_rules (O(n_ip) / O(n_dns))
|
||||
*
|
||||
* Benchmark: N rules total = N/2 IP + N/2 DNS.
|
||||
* slow: allows_socket scans all N rules per call.
|
||||
* fast: allows_socket scans N/2 IP rules per call.
|
||||
* With M=N calls: slow=O(N^2), fast=O((N/2)*N) => 2x minimum.
|
||||
* At high DNS:IP ratio (e.g. 90% DNS), speedup approaches 10x.
|
||||
*/
|
||||
public class RulesetLinearScanTest {
|
||||
|
||||
// Rule types
|
||||
enum RuleKind { IP, DNS, NEG_IP, NEG_DNS }
|
||||
|
||||
static class Rule {
|
||||
final RuleKind kind;
|
||||
final int id; // synthetic payload to prevent JIT elimination
|
||||
Rule(RuleKind kind, int id) { this.kind = kind; this.id = id; }
|
||||
|
||||
boolean allowsSocket(int addr) {
|
||||
// Simulate per-rule check cost: kind-dispatch + comparison
|
||||
return kind == RuleKind.IP && id == addr;
|
||||
}
|
||||
boolean blocksSocket(int addr) {
|
||||
return kind == RuleKind.NEG_IP && id == addr;
|
||||
}
|
||||
boolean allowsDomain(String domain) {
|
||||
return kind == RuleKind.DNS && domain.hashCode() == id;
|
||||
}
|
||||
boolean blocksDomain(String domain) {
|
||||
return kind == RuleKind.NEG_DNS && domain.hashCode() == id;
|
||||
}
|
||||
}
|
||||
|
||||
/** SLOW: flat Vec<Rule> — scans all N rules per allows_socket call */
|
||||
static class SlowRuleset {
|
||||
final List<Rule> rules = new ArrayList<>();
|
||||
|
||||
void addRule(Rule r) { rules.add(r); }
|
||||
|
||||
boolean allowsSocket(int addr) {
|
||||
// Two full scans (blocks check + allows check)
|
||||
for (Rule r : rules) { if (r.blocksSocket(addr)) return false; }
|
||||
for (Rule r : rules) { if (r.allowsSocket(addr)) return true; }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** FAST: partitioned — socket check only scans ip_rules */
|
||||
static class FastRuleset {
|
||||
final List<Rule> ip_rules = new ArrayList<>();
|
||||
final List<Rule> dns_rules = new ArrayList<>();
|
||||
|
||||
void addRule(Rule r) {
|
||||
switch (r.kind) {
|
||||
case DNS: dns_rules.add(r); break;
|
||||
case NEG_DNS: dns_rules.add(r); break;
|
||||
default: ip_rules.add(r); break;
|
||||
}
|
||||
}
|
||||
|
||||
boolean allowsSocket(int addr) {
|
||||
// Only scans ip_rules — DNS rules never visited
|
||||
for (Rule r : ip_rules) { if (r.blocksSocket(addr)) return false; }
|
||||
for (Rule r : ip_rules) { if (r.allowsSocket(addr)) return true; }
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Benchmark helper.
|
||||
* @param ruleset slow or fast instance (via interface)
|
||||
* @param addFn lambda to add a rule
|
||||
* @param checkFn lambda to perform one allows_socket check
|
||||
* @param N number of rules
|
||||
* @param M number of check calls
|
||||
* @return exact operation count (comparisons performed)
|
||||
*/
|
||||
static long bench(boolean slow, int N, int M, int dnsRatio) {
|
||||
// dnsRatio: percentage of rules that are DNS (0-100)
|
||||
// slow path scans all N per call; fast path scans N*(1-dnsRatio/100) per call
|
||||
|
||||
// Build rulesets
|
||||
SlowRuleset slowRs = slow ? new SlowRuleset() : null;
|
||||
FastRuleset fastRs = slow ? null : new FastRuleset();
|
||||
|
||||
int ipCount = N - (N * dnsRatio / 100);
|
||||
int dnsCount = N * dnsRatio / 100;
|
||||
|
||||
for (int i = 0; i < ipCount; i++) {
|
||||
Rule r = new Rule(RuleKind.IP, i + 10000);
|
||||
if (slow) slowRs.addRule(r); else fastRs.addRule(r);
|
||||
}
|
||||
for (int i = 0; i < dnsCount; i++) {
|
||||
Rule r = new Rule(RuleKind.DNS, i + 20000);
|
||||
if (slow) slowRs.addRule(r); else fastRs.addRule(r);
|
||||
}
|
||||
|
||||
// Run M checks — addr never matches any rule (worst case full scan)
|
||||
int addr = 99999;
|
||||
long ops = 0;
|
||||
for (int i = 0; i < M; i++) {
|
||||
if (slow) {
|
||||
ops += slowRs.rules.size(); // blocks scan
|
||||
slowRs.allowsSocket(addr);
|
||||
ops += slowRs.rules.size(); // allows scan
|
||||
} else {
|
||||
ops += fastRs.ip_rules.size(); // blocks scan (ip only)
|
||||
fastRs.allowsSocket(addr);
|
||||
ops += fastRs.ip_rules.size(); // allows scan (ip only)
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
}
|
||||
|
||||
static void test(String name, int N, int M, int dnsRatio, int minSpeedup) {
|
||||
long sOps = bench(true, N, M, dnsRatio);
|
||||
long fOps = bench(false, N, M, dnsRatio);
|
||||
|
||||
double speedup = (double) sOps / fOps;
|
||||
boolean pass = sOps >= fOps * minSpeedup;
|
||||
|
||||
System.out.printf("%-40s slow=%,d fast=%,d speedup=%.1fx %s%n",
|
||||
name, sOps, fOps, speedup, pass ? "PASS" : "FAIL");
|
||||
|
||||
assert pass : String.format(
|
||||
"%s: expected speedup >=%dx, got %.1fx (slow=%d, fast=%d)",
|
||||
name, minSpeedup, speedup, sOps, fOps);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println("wasmer-0001: Ruleset linear scan");
|
||||
System.out.println("=================================");
|
||||
|
||||
// 50% DNS rules: fast path scans half as many rules => 2x minimum
|
||||
test("N=100 M=100 dns=50% minSpeedup=2x", 100, 100, 50, 2);
|
||||
test("N=500 M=500 dns=50% minSpeedup=2x", 500, 500, 50, 2);
|
||||
|
||||
// 80% DNS rules: fast path scans 20% of rules => 5x minimum
|
||||
test("N=100 M=100 dns=80% minSpeedup=5x", 100, 100, 80, 5);
|
||||
test("N=500 M=500 dns=80% minSpeedup=5x", 500, 500, 80, 5);
|
||||
|
||||
// 90% DNS rules: fast path scans 10% of rules => 10x minimum (HIGH severity threshold)
|
||||
test("N=200 M=200 dns=90% minSpeedup=10x", 200, 200, 90, 10);
|
||||
test("N=1000 M=100 dns=90% minSpeedup=10x", 1000, 100, 90, 10);
|
||||
|
||||
System.out.println("=================================");
|
||||
System.out.println("ALL PASS");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue