package unit; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; /** * camel-0001: InternalRouteStartupManager.doStartOrResumeRouteConsumers * * Defect: routeInputs is ArrayList. Each iteration calls * routeInputs.contains(endpoint) → O(R) inside an O(R) outer loop = O(R²). * * Fix: use LinkedHashSet for O(1) contains(). */ public class RouteStartupAlgorithm { // --- Slow path: ArrayList.contains() in loop --- static long slowStartupCheck(int routeCount) { long ops = 0; List routeInputs = new ArrayList<>(); for (int i = 0; i < routeCount; i++) { String endpoint = "endpoint-" + i; // Simulate: if (!doCheckMultipleConsumerSupportClash(endpoint, routeInputs)) // doCheckMultipleConsumerSupportClash calls routeInputs.contains(endpoint) ops++; boolean clash = routeInputs.contains(endpoint); // O(i) scan if (clash) { throw new RuntimeException("unexpected clash at " + i); } // Simulate existingEndpoints rebuild each iteration List existingEndpoints = new ArrayList<>(); for (int j = 0; j < i; j++) { existingEndpoints.add("endpoint-" + j); ops++; } // contains check on existingEndpoints ops++; boolean existingClash = existingEndpoints.contains(endpoint); // O(i) scan if (existingClash) { throw new RuntimeException("unexpected existing clash at " + i); } routeInputs.add(endpoint); } return ops; } // --- Fast path: LinkedHashSet.contains() in loop --- static long fastStartupCheck(int routeCount) { long ops = 0; Set routeInputs = new LinkedHashSet<>(); Set existingEndpointsSet = new LinkedHashSet<>(); for (int i = 0; i < routeCount; i++) { String endpoint = "endpoint-" + i; // O(1) contains ops++; boolean clash = routeInputs.contains(endpoint); if (clash) { throw new RuntimeException("unexpected clash at " + i); } // No need to rebuild existingEndpoints; maintain incrementally ops++; boolean existingClash = existingEndpointsSet.contains(endpoint); if (existingClash) { throw new RuntimeException("unexpected existing clash at " + i); } routeInputs.add(endpoint); existingEndpointsSet.add(endpoint); } return ops; } static void runTest(String label, int N, long slowOps, long fastOps) { double ratio = (double) slowOps / fastOps; boolean pass = ratio >= 10.0; System.out.printf(" %-12s N=%-5d slow=%,7d fast=%,5d ratio=%5.1fx %s%n", label, N, slowOps, fastOps, ratio, pass ? "PASS" : "FAIL"); if (!pass) { throw new AssertionError("Ratio " + ratio + " < 10x threshold at N=" + N); } } public static void main(String[] args) { System.out.println("camel-0001: RouteStartupAlgorithm"); System.out.println(" Defect: ArrayList.contains() in O(R) loop → O(R²)"); System.out.println(" Fix: LinkedHashSet.contains() → O(R)"); System.out.println(); int[] sizes = {100, 300, 500}; int passed = 0; int total = sizes.length; for (int N : sizes) { long slowOps = slowStartupCheck(N); long fastOps = fastStartupCheck(N); try { runTest("route-startup", N, slowOps, fastOps); passed++; } catch (AssertionError e) { System.out.println(" FAIL: " + e.getMessage()); } } System.out.println(); System.out.println(passed + "/" + total + " PASS"); if (passed < total) { System.exit(1); } } }