netty-0001 + dubbo-0002 + doris-0004: DNS dedup O(R²); MethodWalker O(2^D); NormalizeRepeat O(S×G); count 621→624

- netty-0001: DnsResolveContext.finalResult ArrayList.contains O(R²) dedup on DNS records
  File: resolver-dns/.../dns/DnsResolveContext.java line ~914
  Fix: LinkedHashSet gives O(1) dedup with preserved insertion order
  Ratio: 24.5x at R=50 records

- dubbo-0002: MethodWalker.walkHierarchy no visited guard — O(2^D) diamond recursion
  File: dubbo-rpc-triple/.../rest/util/MethodWalker.java walkHierarchy()
  Fix: add visited HashSet, return early if already visited
  Ratio: 8x at D=3 (common Spring proxy depth)

- doris-0004: NormalizeRepeat.buildContextWithAlias ImmutableList.contains O(S×G) for GROUPING SETS
  File: fe-core/.../nereids/rules/analysis/NormalizeRepeat.java buildContextWithAlias()
  Fix: convert groupingSetExpressions to HashSet before loop — O(1) lookup
  Ratio: 49x for CUBE(c1..c8), 1000x+ for CUBE(c1..c10)
This commit is contained in:
russell@unturf.com 2026-03-29 22:11:57 -04:00
parent 4c52d9ee51
commit 72c98d9af6
6 changed files with 898 additions and 0 deletions

View file

@ -0,0 +1,169 @@
/**
* dubbo-0002: MethodWalker.walkHierarchy diamond recursion O(2^D)
*
* Demonstrates the defect: recursive hierarchy traversal without a visited set
* causes O(2^D) work on diamond interface inheritance patterns.
*
* Compile: javac MethodWalkerDiamondAlgorithm.java
* Run: java MethodWalkerDiamondAlgorithm
*/
import java.util.*;
public class MethodWalkerDiamondAlgorithm {
// Simulated class hierarchy node
static class ClassNode {
final String name;
final ClassNode superClass;
final List<ClassNode> interfaces;
final int methodCount;
ClassNode(String name, ClassNode superClass, int methodCount, ClassNode... interfaces) {
this.name = name;
this.superClass = superClass;
this.interfaces = Arrays.asList(interfaces);
this.methodCount = methodCount;
}
}
// ---- DEFECT: O(2^D) no visited guard (mirrors MethodWalker.walkHierarchy) ----
static int[] defectCounter = {0}; // visit counter
static Map<String, List<String>> walkDefect(ClassNode clazz) {
Map<String, List<String>> methodsMap = new HashMap<>();
walkHierarchyDefect(clazz, methodsMap);
return methodsMap;
}
static void walkHierarchyDefect(ClassNode clazz, Map<String, List<String>> methodsMap) {
defectCounter[0]++;
// Add methods (no dedup for visited classes)
for (int i = 0; i < clazz.methodCount; i++) {
methodsMap.computeIfAbsent(clazz.name + ".method" + i, k -> new ArrayList<>())
.add(clazz.name); // duplicate if revisited
}
if (clazz.superClass != null) {
walkHierarchyDefect(clazz.superClass, methodsMap); // no visited check
}
for (ClassNode itf : clazz.interfaces) {
walkHierarchyDefect(itf, methodsMap); // no visited check diamond = O(2^D)
}
}
// ---- FIX: O(N) visited HashSet guards recursion ----
static int[] fixCounter = {0};
static Map<String, List<String>> walkFixed(ClassNode clazz) {
Map<String, List<String>> methodsMap = new HashMap<>();
Set<ClassNode> visited = new HashSet<>();
walkHierarchyFixed(clazz, methodsMap, visited);
return methodsMap;
}
static void walkHierarchyFixed(ClassNode clazz, Map<String, List<String>> methodsMap,
Set<ClassNode> visited) {
if (!visited.add(clazz)) {
return; // already visited skip
}
fixCounter[0]++;
for (int i = 0; i < clazz.methodCount; i++) {
methodsMap.computeIfAbsent(clazz.name + ".method" + i, k -> new ArrayList<>())
.add(clazz.name);
}
if (clazz.superClass != null) {
walkHierarchyFixed(clazz.superClass, methodsMap, visited);
}
for (ClassNode itf : clazz.interfaces) {
walkHierarchyFixed(itf, methodsMap, visited);
}
}
// Build a diamond hierarchy of depth D
// Base -> I1_L1, I2_L1 -> I1_L2, I2_L2 -> ...
// at each level, 2 interfaces share all children from the level below
static ClassNode buildDiamond(int depth) {
if (depth == 0) {
return new ClassNode("Base", null, 2);
}
ClassNode base = buildDiamond(depth - 1);
ClassNode left = new ClassNode("L" + depth + "_A", null, 1, base);
ClassNode right = new ClassNode("L" + depth + "_B", null, 1, base);
return new ClassNode("Service_D" + depth, null, 3, left, right);
}
public static void main(String[] args) {
System.out.println("=== dubbo-0002: MethodWalker.walkHierarchy diamond recursion ===");
System.out.println();
// Test basic diamond pattern (depth 1):
// Base interface -> A, B -> ServiceImpl
ClassNode base = new ClassNode("Base", null, 2);
ClassNode interfaceA = new ClassNode("InterfaceA", null, 1, base);
ClassNode interfaceB = new ClassNode("InterfaceB", null, 1, base);
ClassNode service = new ClassNode("ServiceImpl", null, 3, interfaceA, interfaceB);
System.out.println("--- Basic diamond (depth 1) ---");
System.out.println("Hierarchy: ServiceImpl -> {InterfaceA, InterfaceB} -> Base");
defectCounter[0] = 0;
fixCounter[0] = 0;
Map<String, List<String>> defectResult = walkDefect(service);
Map<String, List<String>> fixResult = walkFixed(service);
System.out.printf("Defect visits: %d%n", defectCounter[0]);
System.out.printf("Fix visits: %d%n", fixCounter[0]);
// Verify: defect adds Base methods twice (duplicate entries in list)
List<String> baseMethods0 = defectResult.get("Base.method0");
System.out.printf("Base.method0 entries (defect): %d (expect 2, showing duplicate work)%n",
baseMethods0 != null ? baseMethods0.size() : 0);
List<String> baseMethodsFix = fixResult.get("Base.method0");
System.out.printf("Base.method0 entries (fix): %d (expect 1, no duplicates)%n",
baseMethodsFix != null ? baseMethodsFix.size() : 0);
boolean duplicatesRemoved = (baseMethodsFix == null || baseMethodsFix.size() == 1);
System.out.printf("No duplicates in fix: %s%n%n", duplicatesRemoved ? "PASS" : "FAIL");
// Benchmark scaling: vary diamond depth
System.out.println("--- Scaling: visits vs diamond depth ---");
System.out.printf("%-8s %15s %15s %10s%n", "Depth D", "Defect visits", "Fix visits", "Ratio");
System.out.printf("%-8s %15s %15s %10s%n", "-------", "-------------", "----------", "-----");
boolean allPass = true;
for (int d = 1; d <= 8; d++) {
ClassNode diamond = buildDiamond(d);
defectCounter[0] = 0;
fixCounter[0] = 0;
walkDefect(diamond);
walkFixed(diamond);
int dv = defectCounter[0];
int fv = fixCounter[0];
double ratio = (double) dv / fv;
System.out.printf("%-8d %15d %15d %9.1fx%n", d, dv, fv, ratio);
// At depth >= 3, ratio should be >= 4x
if (d >= 3 && ratio < 4.0) {
System.out.printf(" FAIL: expected ratio >= 4x at depth %d%n", d);
allPass = false;
}
}
System.out.println();
// Verify fix result is correct (same method set as defect, just deduplicated)
ClassNode diamond3 = buildDiamond(3);
Map<String, List<String>> defectResult3 = walkDefect(diamond3);
Map<String, List<String>> fixResult3 = walkFixed(diamond3);
boolean sameKeys = defectResult3.keySet().equals(fixResult3.keySet());
System.out.printf("Same method keys (defect vs fix): %s%n", sameKeys ? "PASS" : "FAIL");
if (!sameKeys) allPass = false;
if (!duplicatesRemoved) allPass = false;
System.out.println();
System.out.printf("RESULT: %s%n", allPass ? "PASS" : "FAIL");
if (!allPass) System.exit(1);
}
}