wave13: 514/239 — flink/nifi/artemis + K8s/cilium/linkerd2 + ES/OpenSearch/Solr + hadoop/hbase/spark
This commit is contained in:
parent
424a2a7787
commit
8f0bc73afa
32 changed files with 3977 additions and 5 deletions
161
defects/hbase/unit/BaseLoadBalancerAlgorithm.java
Normal file
161
defects/hbase/unit/BaseLoadBalancerAlgorithm.java
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
package unit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Unit test for hbase-0002: BaseLoadBalancer.randomAssignment usedSNs ArrayList.contains() O(n²).
|
||||
*
|
||||
* Standalone — no JUnit. Run: javac -d . BaseLoadBalancerAlgorithm.java && java -ea unit.BaseLoadBalancerAlgorithm
|
||||
*/
|
||||
public class BaseLoadBalancerAlgorithm {
|
||||
|
||||
// Simulates the wouldLowerAvailability predicate — always true to trigger maxIterations
|
||||
static boolean wouldLowerAvailability(int server) {
|
||||
return true; // worst-case: triggers maxIterations path
|
||||
}
|
||||
|
||||
// ---------- Slow: ArrayList.contains in do-while + fallback for loop ----------
|
||||
static class SlowResult {
|
||||
final int serverChosen;
|
||||
final long containsOps;
|
||||
|
||||
SlowResult(int server, long ops) {
|
||||
this.serverChosen = server;
|
||||
this.containsOps = ops;
|
||||
}
|
||||
}
|
||||
|
||||
static SlowResult slowRandomAssignment(List<Integer> servers) {
|
||||
int numServers = servers.size();
|
||||
int sn = -1;
|
||||
final int maxIterations = numServers * 4;
|
||||
int iterations = 0;
|
||||
List<Integer> usedSNs = new ArrayList<>(numServers);
|
||||
Random rand = new Random(42);
|
||||
long ops = 0;
|
||||
|
||||
do {
|
||||
int i = rand.nextInt(numServers);
|
||||
sn = servers.get(i);
|
||||
ops += usedSNs.size(); // O(size) per contains
|
||||
if (!usedSNs.contains(sn)) {
|
||||
usedSNs.add(sn);
|
||||
}
|
||||
} while (wouldLowerAvailability(sn) && iterations++ < maxIterations);
|
||||
|
||||
if (iterations >= maxIterations) {
|
||||
// Fallback: scan all servers
|
||||
for (Integer unusedServer : servers) {
|
||||
ops += usedSNs.size(); // O(size) per contains
|
||||
if (!usedSNs.contains(unusedServer)) {
|
||||
if (!wouldLowerAvailability(unusedServer)) {
|
||||
sn = unusedServer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new SlowResult(sn, ops);
|
||||
}
|
||||
|
||||
// ---------- Fast: LinkedHashSet.contains O(1) ----------
|
||||
static class FastResult {
|
||||
final int serverChosen;
|
||||
final long containsOps;
|
||||
|
||||
FastResult(int server, long ops) {
|
||||
this.serverChosen = server;
|
||||
this.containsOps = ops;
|
||||
}
|
||||
}
|
||||
|
||||
static FastResult fastRandomAssignment(List<Integer> servers) {
|
||||
int numServers = servers.size();
|
||||
int sn = -1;
|
||||
final int maxIterations = numServers * 4;
|
||||
int iterations = 0;
|
||||
Set<Integer> usedSNs = new LinkedHashSet<>(numServers);
|
||||
Random rand = new Random(42);
|
||||
long ops = 0;
|
||||
|
||||
do {
|
||||
int i = rand.nextInt(numServers);
|
||||
sn = servers.get(i);
|
||||
ops += 1; // O(1) per contains
|
||||
usedSNs.add(sn);
|
||||
} while (wouldLowerAvailability(sn) && iterations++ < maxIterations);
|
||||
|
||||
if (iterations >= maxIterations) {
|
||||
for (Integer unusedServer : servers) {
|
||||
ops += 1; // O(1)
|
||||
if (!usedSNs.contains(unusedServer)) {
|
||||
if (!wouldLowerAvailability(unusedServer)) {
|
||||
sn = unusedServer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new FastResult(sn, ops);
|
||||
}
|
||||
|
||||
static void testCorrectness() {
|
||||
int S = 50;
|
||||
List<Integer> servers = new ArrayList<>();
|
||||
for (int i = 0; i < S; i++) servers.add(i);
|
||||
|
||||
SlowResult slow = slowRandomAssignment(servers);
|
||||
FastResult fast = fastRandomAssignment(servers);
|
||||
|
||||
// Both should end up not finding a server (all trigger wouldLowerAvailability)
|
||||
assert slow.serverChosen == fast.serverChosen :
|
||||
"server mismatch: slow=" + slow.serverChosen + " fast=" + fast.serverChosen;
|
||||
System.out.println("PASS: correctness — same server chosen: " + slow.serverChosen);
|
||||
}
|
||||
|
||||
static void testPerformance() {
|
||||
int S = 500; // 500 servers — large HBase cluster
|
||||
List<Integer> servers = new ArrayList<>();
|
||||
for (int i = 0; i < S; i++) servers.add(i);
|
||||
|
||||
SlowResult slow = slowRandomAssignment(servers);
|
||||
FastResult fast = fastRandomAssignment(servers);
|
||||
|
||||
double ratio = (double) slow.containsOps / fast.containsOps;
|
||||
System.out.printf("randomAssignment S=%d: slow_ops=%,d fast_ops=%,d ratio=%.1fx%n",
|
||||
S, slow.containsOps, fast.containsOps, ratio);
|
||||
assert ratio >= 10.0 :
|
||||
"Expected >=10x speedup, got ratio=" + ratio;
|
||||
System.out.println("PASS: performance — ratio >= 10x");
|
||||
}
|
||||
|
||||
static void testLargeCluster() {
|
||||
// Simulate 2000-server cluster (very large HBase)
|
||||
int S = 2000;
|
||||
List<Integer> servers = new ArrayList<>();
|
||||
for (int i = 0; i < S; i++) servers.add(i);
|
||||
|
||||
SlowResult slow = slowRandomAssignment(servers);
|
||||
FastResult fast = fastRandomAssignment(servers);
|
||||
|
||||
double ratio = (double) slow.containsOps / fast.containsOps;
|
||||
System.out.printf("randomAssignment S=%d: slow_ops=%,d fast_ops=%,d ratio=%.1fx%n",
|
||||
S, slow.containsOps, fast.containsOps, ratio);
|
||||
assert ratio >= 50.0 :
|
||||
"Expected >=50x speedup for large cluster, got ratio=" + ratio;
|
||||
System.out.println("PASS: large cluster — ratio >= 50x");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
testCorrectness();
|
||||
testPerformance();
|
||||
testLargeCluster();
|
||||
System.out.println("ALL PASS (3/3)");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue