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:
parent
3735145aa5
commit
5fe6da7cc2
69 changed files with 6793 additions and 32 deletions
164
defects/pulsar/unit/PulsarJavaInstanceRunnableTest.java
Normal file
164
defects/pulsar/unit/PulsarJavaInstanceRunnableTest.java
Normal 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);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue