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,49 @@
# pulsar-0001: GetTopicsResult.getTopics() — ArrayList.contains() inside dedup for loop
## Defect ID
pulsar-0001
## File:Line
`pulsar-common/src/main/java/org/apache/pulsar/common/lookup/GetTopicsResult.java:117`
## Description
`getTopics()` deduplicates partitioned topic names:
```java
List<String> grouped = new ArrayList<>();
for (String topic : nonPartitionedOrPartitionTopics) { // O(N)
String partitionedTopic = TopicName.get(topic).getPartitionedTopicName();
if (!grouped.contains(partitionedTopic)) { // O(N) linear scan
grouped.add(partitionedTopic);
}
}
```
`grouped` is an `ArrayList<String>`. Each `.contains()` is O(N). Total: O(N²).
This method is called on every consumer subscription lookup, broker topic listing,
and namespace topic query. For a namespace with 1,000 topic partitions (e.g.,
a topic with 1000 partitions), this scans up to 1000×1000 = 1M comparisons
instead of 1000 with a `LinkedHashSet`.
## Complexity
- Slow: O(N²) — ArrayList.contains() = O(N)
- Fast: O(N) — LinkedHashSet.add() = O(1) with preserved insertion order
## Severity
HIGH
## Speedup Estimate
~N× improvement = 1000x at N=1000 partitions.
## Fix
Replace `ArrayList` with `LinkedHashSet<String>` to preserve order while giving
O(1) dedup, then convert to `List` for the return type:
```java
LinkedHashSet<String> grouped = new LinkedHashSet<>();
for (String topic : nonPartitionedOrPartitionTopics) {
grouped.add(TopicName.get(topic).getPartitionedTopicName());
}
topics = new ArrayList<>(grouped);
```

View file

@ -0,0 +1,46 @@
# pulsar-0002: JavaInstanceRunnable — List.contains() inside config key validation loop
## Defect ID
pulsar-0002
## File:Line
`pulsar-functions/instance/src/main/java/org/apache/pulsar/functions/instance/JavaInstanceRunnable.java:987`
## Description
In `setupConfig()`:
```java
final List<String> allFields = BeanPropertiesReader.getBeanProperties(configClass); // List<String>
for (String s : config.keySet()) { // O(K) iterations over config keys
if (!allFields.contains(s)) { // O(F) linear scan over field names
...
}
}
```
`allFields` is a `List<String>` returned by `BeanPropertiesReader.getBeanProperties()`.
Each `.contains()` is O(F) where F = number of bean fields. Total: O(K × F).
While this runs at function startup (not hot per-message), it runs once per function
instance initialization. For a config class with 200 fields and 150 config keys,
this is 30,000 comparisons vs 350 with a HashSet.
## Complexity
- Slow: O(K × F) — List.contains() = O(F)
- Fast: O(K) — HashSet.contains() = O(1)
## Severity
MEDIUM
## Speedup Estimate
~F× improvement = 200x at F=200 fields.
## Fix
Convert `allFields` to `HashSet<String>` immediately after retrieval:
```java
Set<String> allFieldsSet = new HashSet<>(BeanPropertiesReader.getBeanProperties(configClass));
for (String s : config.keySet()) {
if (!allFieldsSet.contains(s)) { ... }
}
```