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:
russell@unturf.com 2026-03-27 21:25:37 -04:00
parent dde5ec97fb
commit e4ee168b1e
50 changed files with 4775 additions and 5 deletions

View file

@ -0,0 +1,165 @@
package unit;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* rmq-0005: rabbit_mgmt_wm_definitions export_binding O(B×Q) → O(B+Q)
*
* Simulates the binding export scan in rabbit_mgmt_wm_definitions.erl.
* SLOW: export_binding uses List.contains({name,vhost}) for each of B bindings.
* FAST: pre-build a HashSet<String> of queue keys, then O(1) lookup per binding.
*/
public class ExportBindingAlgorithm {
// Simulated binding entry: destination name and vhost
static final class BindingEntry {
final String dest;
final String vhost;
final boolean isQueue; // dest_type == queue
BindingEntry(String dest, String vhost, boolean isQueue) {
this.dest = dest;
this.vhost = vhost;
this.isQueue = isQueue;
}
}
// Simulated queue-name tuple: {name, vhost}
static final class QueueKey {
final String name;
final String vhost;
QueueKey(String name, String vhost) {
this.name = name;
this.vhost = vhost;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof QueueKey)) return false;
QueueKey q = (QueueKey) o;
return name.equals(q.name) && vhost.equals(q.vhost);
}
@Override
public int hashCode() {
return 31 * name.hashCode() + vhost.hashCode();
}
}
// SLOW: O(B×Q) — lists:member({Dest,VHost}, QNames) inside list comprehension
static long slowOps = 0;
static boolean exportBindingSlow(BindingEntry b, List<QueueKey> qnames) {
if (!b.isQueue) return true; // exchange binding, always export
for (QueueKey q : qnames) {
slowOps++;
if (q.name.equals(b.dest) && q.vhost.equals(b.vhost)) {
return true;
}
}
return false;
}
static List<BindingEntry> slowExport(List<BindingEntry> bindings, List<QueueKey> qnames) {
List<BindingEntry> result = new ArrayList<>();
for (BindingEntry b : bindings) {
if (exportBindingSlow(b, qnames)) {
result.add(b);
}
}
return result;
}
// FAST: O(B+Q) — pre-build HashSet, then O(1) per binding
static long fastOps = 0;
static Set<String> buildQNamesSet(List<QueueKey> qnames) {
Set<String> s = new HashSet<>(qnames.size() * 2);
for (QueueKey q : qnames) {
fastOps++; // one insertion per queue
s.add(q.name + "\0" + q.vhost);
}
return s;
}
static boolean exportBindingFast(BindingEntry b, Set<String> qnamesSet) {
if (!b.isQueue) return true;
fastOps++;
return qnamesSet.contains(b.dest + "\0" + b.vhost);
}
static List<BindingEntry> fastExport(List<BindingEntry> bindings, List<QueueKey> qnames) {
Set<String> qnamesSet = buildQNamesSet(qnames);
List<BindingEntry> result = new ArrayList<>();
for (BindingEntry b : bindings) {
if (exportBindingFast(b, qnamesSet)) {
result.add(b);
}
}
return result;
}
public static void main(String[] args) {
// Build test data: Q queues, B bindings (all queue-type, all matching)
int Q = 1000; // queue count
int B = 5000; // binding count
List<QueueKey> qnames = new ArrayList<>(Q);
for (int i = 0; i < Q; i++) {
qnames.add(new QueueKey("queue-" + i, "vhost-" + (i % 5)));
}
List<BindingEntry> bindings = new ArrayList<>(B);
for (int i = 0; i < B; i++) {
// Each binding points to a queue that exists — worst-case scan to find it
int idx = (i * 7 + 3) % Q; // spread across queues
bindings.add(new BindingEntry(
qnames.get(idx).name,
qnames.get(idx).vhost,
true
));
}
// SLOW run
slowOps = 0;
List<BindingEntry> slowResult = slowExport(bindings, qnames);
// FAST run
fastOps = 0;
List<BindingEntry> fastResult = fastExport(bindings, qnames);
// Correctness check
boolean pass = true;
if (slowResult.size() != fastResult.size()) {
System.out.println("FAIL: result size mismatch: slow=" + slowResult.size() + " fast=" + fastResult.size());
pass = false;
}
// Verify same bindings exported (order may differ, but all B bindings match)
if (slowResult.size() != B) {
System.out.println("FAIL: expected all " + B + " bindings exported, got slow=" + slowResult.size());
pass = false;
}
// Ratio check
double ratio = (double) slowOps / (double) fastOps;
System.out.printf("N=%d/%d B=%d Q=%d slow=%d ops fast=%d ops ratio=%.1fx%n",
B, Q, B, Q, slowOps, fastOps, ratio);
if (ratio < 5.0) {
System.out.println("FAIL: ratio too low (expected >= 5x)");
pass = false;
}
if (pass) {
System.out.println("1/1 PASS");
} else {
System.exit(1);
}
}
}