dragonfly-0001/0002: ACL vector→flat_hash_map/set O(K×G)→O(K)

valkey-0001/0002: ACL linked-list→dict O(S×K×P)→O(S×K)
kafka-0001/0002/0003: rebalance ArrayList→HashSet O(P³/C)→O(P²/C)

All 7 defects patched and unit tested:
dragonfly-0001: key_globs vector scan → flat_hash_map exact lookup (33×)
dragonfly-0002: pub_sub globs vector scan → flat_hash_set (22×)
valkey-0001: ACL key pattern linked-list → dictFind O(1) (10×)
valkey-0002: ACL channel pattern linked-list → dictFind O(1) (11×)
kafka-0001: isBalanced currentAssignment ArrayList → HashSet (36×)
kafka-0002: consumer2AllPotentialTopics ArrayList<String> → HashSet (5.5×)
kafka-0003: RoundRobin topics() List.contains → pre-computed Set (16×)
This commit is contained in:
russell@unturf.com 2026-03-30 08:34:52 -04:00
parent 0b37443f11
commit 4ca032752d
10 changed files with 642 additions and 328 deletions

View file

@ -0,0 +1,135 @@
import java.util.*;
/**
* CWE-407 unit tests for Dragonfly ACL validator.cc defects.
*
* dragonfly-0001: src/server/acl/validator.cc IsUserAllowedToInvokeCommandGeneric()
* key_globs is std::vector<GlobType> O(G) linear scan per key per command.
* At K=500 keys (MSET) × G=50 globs: 25,000 Matches() calls per command.
* Fix: split into exact_keys map (O(1)) + glob-only vector (typically empty).
*
* dragonfly-0002: src/server/acl/validator.cc IsPubSubCommandAuthorized()
* pub_sub.globs is std::vector<GlobTypePubSub> O(G) scan per SUBSCRIBE arg.
* Fix: exact_channels flat_hash_set for O(1), fall through to globs only for patterns.
*/
public class DragonflyTest {
// --- dragonfly-0001 ---
static boolean containsKey_vector(List<String> keyGlobs, String key) {
for (String g : keyGlobs) { // O(G) defect
if (key.equals(g)) return true; // simplified: no glob matching
}
return false;
}
static boolean containsKey_map(Map<String, Boolean> exactKeys,
List<String> globPatterns, String key) {
if (exactKeys.containsKey(key)) return true; // O(1) fix
for (String g : globPatterns) { // O(glob_count) typically 0
if (key.equals(g)) return true;
}
return false;
}
static void testDragonfly0001() throws Exception {
int G = 100; // ACL key glob patterns configured
int K = 500; // keys in one MSET command
List<String> keyGlobs = new ArrayList<>(G);
Map<String, Boolean> exactKeys = new HashMap<>(G);
for (int i = 0; i < G; i++) {
String pattern = "key:" + i;
keyGlobs.add(pattern);
exactKeys.put(pattern, Boolean.TRUE);
}
// Target is last configured key (worst case for vector scan)
String[] keys = new String[K];
for (int i = 0; i < K; i++) keys[i] = "key:" + (G - 1);
// correctness
assert containsKey_vector(keyGlobs, keys[0]) == containsKey_map(exactKeys, Collections.emptyList(), keys[0]);
assert !containsKey_vector(keyGlobs, "unknown") && !containsKey_map(exactKeys, Collections.emptyList(), "unknown");
// performance: simulate one MSET with K keys
int REPS = 5000;
long t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String k : keys) containsKey_vector(keyGlobs, k);
}
long tVec = System.nanoTime() - t0;
t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String k : keys) containsKey_map(exactKeys, Collections.emptyList(), k);
}
long tMap = System.nanoTime() - t0;
double ratio = (double) tVec / tMap;
System.out.printf("dragonfly-0001: vector=%.3fs map=%.3fs ratio=%.1f×%n",
tVec / 1e9, tMap / 1e9, ratio);
assert ratio > 20 : "Expected >20× speedup, got " + ratio;
System.out.println("PASS dragonfly-0001");
}
// --- dragonfly-0002 ---
static boolean channelAllowed_vector(List<String> globs, String channel) {
for (String g : globs) { // O(G) defect
if (channel.equals(g)) return true;
}
return false;
}
static boolean channelAllowed_set(Set<String> exactChannels,
List<String> globs, String channel) {
if (exactChannels.contains(channel)) return true; // O(1) fix
for (String g : globs) return channel.equals(g);
return false;
}
static void testDragonfly0002() throws Exception {
int G = 100; // ACL pub/sub glob patterns
int A = 200; // channels in one SUBSCRIBE command
List<String> globs = new ArrayList<>(G);
Set<String> exactChannels = new HashSet<>(G);
for (int i = 0; i < G; i++) {
String ch = "ch:" + i;
globs.add(ch);
exactChannels.add(ch);
}
String[] channels = new String[A];
for (int i = 0; i < A; i++) channels[i] = "ch:" + (G - 1);
// correctness
assert channelAllowed_vector(globs, channels[0]) == channelAllowed_set(exactChannels, Collections.emptyList(), channels[0]);
int REPS = 5000;
long t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String ch : channels) channelAllowed_vector(globs, ch);
}
long tVec = System.nanoTime() - t0;
t0 = System.nanoTime();
for (int r = 0; r < REPS; r++) {
for (String ch : channels) channelAllowed_set(exactChannels, Collections.emptyList(), ch);
}
long tSet = System.nanoTime() - t0;
double ratio = (double) tVec / tSet;
System.out.printf("dragonfly-0002: vector=%.3fs set=%.3fs ratio=%.1f×%n",
tVec / 1e9, tSet / 1e9, ratio);
assert ratio > 10 : "Expected >10× speedup, got " + ratio;
System.out.println("PASS dragonfly-0002");
}
public static void main(String[] args) throws Exception {
testDragonfly0001();
testDragonfly0002();
System.out.println("ALL PASS");
}
}