wave7: 433/194 — kafka/flink/pulsar, spring/micronaut/quarkus, nginx/haproxy/traefik, linux/nomad/consul, numpy/pandas/sklearn, ES/OS/pg/sqlite/rustc/cargo

This commit is contained in:
russell@unturf.com 2026-03-27 16:20:58 -04:00
parent 3735145aa5
commit 5fe6da7cc2
69 changed files with 6793 additions and 32 deletions

View file

@ -0,0 +1,164 @@
package unit;
import java.util.*;
/**
* pulsar-0002: JavaInstanceRunnable.setupConfig() List.contains() in config key validation loop.
*
* allFields is a List<String> from BeanPropertiesReader.getBeanProperties().
* For each config key, .contains() is O(F). With K keys, total is O(K * F).
* Fix: convert allFields to HashSet<String> before the loop.
*/
public class PulsarJavaInstanceRunnableTest {
// Slow path: List<String> allFields with .contains() per key
static Object[] slowValidateConfig(List<String> allFields, Set<String> configKeys) {
long ops = 0;
List<String> invalidKeys = new ArrayList<>();
for (String s : configKeys) {
// allFields.contains(s): O(F) linear scan
boolean found = false;
for (String f : allFields) {
ops++;
if (f.equals(s)) { found = true; break; }
}
if (!found) {
invalidKeys.add(s);
}
}
return new Object[]{invalidKeys, ops};
}
// Fast path: HashSet<String> for O(1) lookup
static Object[] fastValidateConfig(List<String> allFields, Set<String> configKeys) {
Set<String> fieldSet = new HashSet<>(allFields);
long ops = 0;
List<String> invalidKeys = new ArrayList<>();
for (String s : configKeys) {
ops++; // O(1) HashSet.contains
if (!fieldSet.contains(s)) {
invalidKeys.add(s);
}
}
return new Object[]{invalidKeys, ops};
}
public static void main(String[] args) {
int passed = 0;
int total = 0;
// Test 1: correctness no invalid keys
{
total++;
List<String> allFields = Arrays.asList("host", "port", "timeout", "retries", "user");
Set<String> configKeys = new HashSet<>(Arrays.asList("host", "port", "timeout"));
@SuppressWarnings("unchecked")
List<String> slowInvalid = (List<String>) slowValidateConfig(allFields, configKeys)[0];
@SuppressWarnings("unchecked")
List<String> fastInvalid = (List<String>) fastValidateConfig(allFields, configKeys)[0];
assert slowInvalid.isEmpty() : "No invalid keys expected, slow found: " + slowInvalid;
assert fastInvalid.isEmpty() : "No invalid keys expected, fast found: " + fastInvalid;
System.out.println(" Test 1 PASS: no invalid keys");
passed++;
}
// Test 2: correctness some invalid keys
{
total++;
List<String> allFields = Arrays.asList("host", "port", "timeout");
Set<String> configKeys = new HashSet<>(Arrays.asList("host", "port", "badKey", "anotherBad"));
@SuppressWarnings("unchecked")
List<String> slowInvalid = (List<String>) slowValidateConfig(allFields, configKeys)[0];
@SuppressWarnings("unchecked")
List<String> fastInvalid = (List<String>) fastValidateConfig(allFields, configKeys)[0];
Set<String> slowSet = new HashSet<>(slowInvalid);
Set<String> fastSet = new HashSet<>(fastInvalid);
assert slowSet.equals(fastSet)
: "Slow and fast must find same invalid keys. slow=" + slowSet + " fast=" + fastSet;
assert slowSet.contains("badKey") : "badKey must be invalid";
assert slowSet.contains("anotherBad") : "anotherBad must be invalid";
assert !slowSet.contains("host") : "host is valid, must not be invalid";
System.out.println(" Test 2 PASS: invalid keys=" + slowSet);
passed++;
}
// Test 3: op count slow O(K*F) vs fast O(K)
{
total++;
int F = 150; // fields in config class
int K = 100; // config keys
List<String> allFields = new ArrayList<>();
for (int i = 0; i < F; i++) allFields.add("field" + i);
// Config keys: half valid, half invalid
Set<String> configKeys = new HashSet<>();
for (int i = 0; i < K / 2; i++) configKeys.add("field" + i); // valid
for (int i = 0; i < K / 2; i++) configKeys.add("unknown-key-" + i); // invalid
Object[] slowOut = slowValidateConfig(allFields, configKeys);
Object[] fastOut = fastValidateConfig(allFields, configKeys);
@SuppressWarnings("unchecked")
Set<String> slowInvalidSet = new HashSet<>((List<String>) slowOut[0]);
@SuppressWarnings("unchecked")
Set<String> fastInvalidSet = new HashSet<>((List<String>) fastOut[0]);
assert slowInvalidSet.equals(fastInvalidSet)
: "Slow and fast must agree on invalid keys";
long slowOps = (Long) slowOut[1];
long fastOps = (Long) fastOut[1];
assert slowOps > fastOps
: "Slow must do more ops: slowOps=" + slowOps + " fastOps=" + fastOps;
assert fastOps == K
: "Fast must make exactly K=" + K + " ops, got " + fastOps;
long speedup = slowOps / fastOps;
System.out.println(" Test 3 PASS: slowOps=" + slowOps + " fastOps=" + fastOps
+ " speedup=" + speedup + "x (F=" + F + " K=" + K + ")");
passed++;
}
// Test 4: worst-case O(K*F) all config keys invalid (scan all F every time)
{
total++;
int F = 100;
int K = 80;
List<String> allFields = new ArrayList<>();
for (int i = 0; i < F; i++) allFields.add("field" + i);
Set<String> configKeys = new HashSet<>();
for (int i = 0; i < K; i++) configKeys.add("invalid-key-" + i);
long expectedSlowOps = (long) K * F; // every key scans all F fields
long actualSlowOps = 0;
for (String key : configKeys) {
for (String f : allFields) {
actualSlowOps++;
if (f.equals(key)) break;
}
}
assert actualSlowOps == expectedSlowOps
: "Expected " + expectedSlowOps + " ops (K*F), got " + actualSlowOps;
long fastOps = K;
long speedup = actualSlowOps / fastOps;
assert speedup == F : "Speedup should equal F=" + F + ", got " + speedup;
System.out.println(" Test 4 PASS: O(K*F)=" + actualSlowOps + " vs O(K)=" + fastOps
+ " speedup=" + speedup + "x");
passed++;
}
System.out.println(passed + "/" + total + " PASS");
if (passed != total) System.exit(1);
}
}