package bench; import support.MongodbIndexPlannerAlgorithm; import support.MongodbIndexPlannerAlgorithm.DefectiveRelevantTag; import support.MongodbIndexPlannerAlgorithm.FixedRelevantTag; import support.MongodbIndexPlannerAlgorithm.StripResult; import support.MongodbIndexPlannerAlgorithm.EnumResult; import support.MongodbPipelineAlgorithm; import support.MongodbPipelineAlgorithm.FieldIndexResult; import support.MongodbPipelineAlgorithm.OptimizationResult; import java.util.*; /** * MongodbBenchmark — timing benchmark for mongodb-0001 through -0004. * * Four sites across two MongoDB subsystems, all CWE-407: * * mongodb-0001 planner_ixselect.cpp (4 sites) RelevantTag vector CRITICAL * mongodb-0002 plan_enumerator.cpp (4 sites) predicate vector tracking HIGH * mongodb-0003 unpack_bucket.cpp stage vector tracking HIGH * mongodb-0004 streaming_group.cpp idFieldNames vector scan MEDIUM * * Root cause of 0001: single struct change in index_tag.h:106-107 * std::vector first; → std::unordered_set first; * std::vector notFirst; → std::unordered_set notFirst; * fixes all 4 planner_ixselect.cpp sites simultaneously. * * These are ALGORITHM MICRO-BENCHMARKS, not real MongoDB query timings. * Real query planning also involves BSON parsing, candidate index selection, * and other work. The micro-benchmark isolates the membership-check cost. */ public class MongodbBenchmark { static final int WARMUP_ROUNDS = 5; // ── 0001: planner_ixselect.cpp — RelevantTag strip passes ──────────────── static void bench0001() { System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" mongodb-0001 — planner_ixselect.cpp RelevantTag (4 sites, CRITICAL)"); System.out.println(" Root cause: index_tag.h:106-107 vector → unordered_set"); System.out.println(" Defect: std::find O(M) per node Fix: .count() O(1) per node"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.printf(" %-10s %-10s %-14s %-12s %s%n", "N nodes", "M indexes", "Defective (ms)", "Fixed (ms)", "Speedup"); System.out.println(" " + "─".repeat(60)); int idxPerTag = 20; int totalIdxs = 30; for (int n : new int[]{50, 200, 500, 1000, 2000, 5000}) { Random rng1 = new Random(42); Random rng2 = new Random(42); List defTags = MongodbIndexPlannerAlgorithm.buildDefectiveTags(n, idxPerTag, totalIdxs, rng1); List fixTags = MongodbIndexPlannerAlgorithm.buildFixedTags(n, idxPerTag, totalIdxs, rng2); // warmup for (int i = 0; i < WARMUP_ROUNDS; i++) { MongodbIndexPlannerAlgorithm.defectiveStripInvalidAssignments(defTags, 5); MongodbIndexPlannerAlgorithm.fixedStripInvalidAssignments(fixTags, 5); } long t0 = System.nanoTime(); StripResult def = MongodbIndexPlannerAlgorithm.defectiveStripInvalidAssignments(defTags, 5); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); StripResult fix = MongodbIndexPlannerAlgorithm.fixedStripInvalidAssignments(fixTags, 5); long fixNs = System.nanoTime() - t0; System.out.printf(" %-10d %-10d %-14.3f %-12.3f %.1fx%n", n, idxPerTag, defNs / 1e6, fixNs / 1e6, (double) defNs / Math.max(1, fixNs)); } } // ── 0002: plan_enumerator.cpp — predicate de-dup ───────────────────────── static void bench0002() { System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" mongodb-0002 — plan_enumerator.cpp predicate tracking (4 sites, HIGH)"); System.out.println(" Defect: std::vector std::find O(A) per predicate"); System.out.println(" Fix: std::unordered_set O(1) per predicate"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.printf(" %-12s %-14s %-12s %s%n", "P predicates", "Defective (ms)", "Fixed (ms)", "Speedup"); System.out.println(" " + "─".repeat(50)); Random predRng = new Random(42); for (int p : new int[]{20, 50, 100, 200, 500, 1000}) { List preds = new ArrayList<>(); for (int i = 0; i < p; i++) preds.add(i); for (int i = 0; i < p / 4; i++) preds.add(predRng.nextInt(p)); Collections.shuffle(preds, predRng); // warmup for (int i = 0; i < WARMUP_ROUNDS; i++) { MongodbIndexPlannerAlgorithm.defectiveEnumeratePreds(preds); MongodbIndexPlannerAlgorithm.fixedEnumeratePreds(preds); } long t0 = System.nanoTime(); EnumResult def = MongodbIndexPlannerAlgorithm.defectiveEnumeratePreds(preds); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); EnumResult fix = MongodbIndexPlannerAlgorithm.fixedEnumeratePreds(preds); long fixNs = System.nanoTime() - t0; System.out.printf(" %-12d %-14.3f %-12.3f %.1fx%n", preds.size(), defNs / 1e6, fixNs / 1e6, (double) defNs / Math.max(1, fixNs)); } } // ── 0003: document_source_internal_unpack_bucket.cpp ───────────────────── static void bench0003() { System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" mongodb-0003 — unpack_bucket.cpp stage tracking (HIGH)"); System.out.println(" Defect: std::vector _triedComputedMetaPushDownFor"); System.out.println(" Fix: std::unordered_set O(1) lookup"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.printf(" %-10s %-14s %-12s %s%n", "S stages", "Defective (ms)", "Fixed (ms)", "Speedup"); System.out.println(" " + "─".repeat(50)); Random rng = new Random(42); for (int s : new int[]{20, 50, 100, 200, 500, 1000}) { List stages = new ArrayList<>(); for (int i = 0; i < s; i++) stages.add(i); for (int i = 0; i < s / 4; i++) stages.add(rng.nextInt(s)); Collections.shuffle(stages, rng); // warmup for (int i = 0; i < WARMUP_ROUNDS; i++) { MongodbPipelineAlgorithm.defectiveTrackStages(stages); MongodbPipelineAlgorithm.fixedTrackStages(stages); } long t0 = System.nanoTime(); OptimizationResult def = MongodbPipelineAlgorithm.defectiveTrackStages(stages); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); OptimizationResult fix = MongodbPipelineAlgorithm.fixedTrackStages(stages); long fixNs = System.nanoTime() - t0; System.out.printf(" %-10d %-14.3f %-12.3f %.1fx%n", stages.size(), defNs / 1e6, fixNs / 1e6, (double) defNs / Math.max(1, fixNs)); } } // ── 0004: document_source_streaming_group.cpp ──────────────────────────── static void bench0004() { System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" mongodb-0004 — streaming_group.cpp field index resolution (MEDIUM)"); System.out.println(" Defect: std::find on idFieldNames O(N × M)"); System.out.println(" Fix: unordered_map built once O(N + M)"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.printf(" %-8s %-8s %-14s %-12s %s%n", "N fields", "M mono", "Defective (ms)", "Fixed (ms)", "Speedup"); System.out.println(" " + "─".repeat(56)); for (int n : new int[]{10, 20, 50, 100, 200, 500}) { List idFields = new ArrayList<>(); for (int i = 0; i < n; i++) idFields.add("field_" + i); List mono = new ArrayList<>(idFields.subList(n / 2, n)); // warmup for (int i = 0; i < WARMUP_ROUNDS; i++) { MongodbPipelineAlgorithm.defectiveResolveIndexes(idFields, mono); MongodbPipelineAlgorithm.fixedResolveIndexes(idFields, mono); } long t0 = System.nanoTime(); FieldIndexResult def = MongodbPipelineAlgorithm.defectiveResolveIndexes(idFields, mono); long defNs = System.nanoTime() - t0; t0 = System.nanoTime(); FieldIndexResult fix = MongodbPipelineAlgorithm.fixedResolveIndexes(idFields, mono); long fixNs = System.nanoTime() - t0; System.out.printf(" %-8d %-8d %-14.3f %-12.3f %.1fx%n", n, mono.size(), defNs / 1e6, fixNs / 1e6, (double) defNs / Math.max(1, fixNs)); } } // ── Main ───────────────────────────────────────────────────────────────── public static void main(String[] args) { System.out.println(); System.out.println("╔══════════════════════════════════════════════════════════════════╗"); System.out.println("║ MongodbBenchmark — CWE-407 algorithm micro-benchmarks ║"); System.out.println("║ mongodb-0001 mongodb-0002 mongodb-0003 mongodb-0004 ║"); System.out.println("╠══════════════════════════════════════════════════════════════════╣"); System.out.println("║ All sites: list membership O(n²/n×m) → hash set O(n) ║"); System.out.println("║ mongodb-0001 root cause: single struct change in index_tag.h ║"); System.out.println("║ NOTE: algorithm isolation — not real MongoDB query timings ║"); System.out.println("╚══════════════════════════════════════════════════════════════════╝"); bench0001(); bench0002(); bench0003(); bench0004(); System.out.println(); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" SUMMARY"); System.out.println("══════════════════════════════════════════════════════════════════"); System.out.println(" mongodb-0001 PATCHED index_tag.h:106-107 + planner_ixselect.cpp (4 sites)"); System.out.println(" mongodb-0002 PATCHED plan_enumerator.cpp (4 sites)"); System.out.println(" mongodb-0003 PATCHED unpack_bucket.h:457 + unpack_bucket.cpp:1076"); System.out.println(" mongodb-0004 PATCHED streaming_group.cpp:142"); System.out.println(" mongodb-0005 DEFERRED ce_cache.h:122 — IndexBounds, no hash"); System.out.println(" mongodb-0006 NOT-WORTH-FIXING projection_ast.h:262 — removeChild O(n) erase irreducible"); System.out.println(" mongodb-0007 NOT-WORTH-FIXING join_graph.cpp — InlinedVector<2>, A≈1 at runtime"); System.out.println("══════════════════════════════════════════════════════════════════"); } }