Skip to content

Support parallel AddIndexEntry in trie index - #14966

Open
zaidoon1 wants to merge 11 commits into
facebook:mainfrom
zaidoon1:zaidoon/udi-09-trie-parallel-builder
Open

Support parallel AddIndexEntry in trie index#14966
zaidoon1 wants to merge 11 commits into
facebook:mainfrom
zaidoon1:zaidoon/udi-09-trie-parallel-builder

Conversation

@zaidoon1

@zaidoon1 zaidoon1 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Part 11 of 13 in the UDI split.

Stack order:

  1. Add IndexFactory compatibility names #14954 Add IndexFactory compatibility names
  2. Add UDI index mode API vocabulary #14959 Add UDI index mode API vocabulary
  3. Add optional UDI builder protocols #14960 Add optional UDI builder protocols
  4. Add built-in index factory wrappers #14961 Add built-in index factory wrappers
  5. Add built-in index factory tests #14969 Add built-in index factory tests
  6. Promote IndexFactory as UDI SPI #14962 Promote IndexFactory as UDI SPI
  7. Wire IndexFactory through block-based tables #14963 Wire IndexFactory through block-based tables
  8. Add IndexFactory table routing tests #14964 Add IndexFactory table routing tests
  9. Add IndexFactory parallel routing tests #14970 Add IndexFactory parallel routing tests
  10. Account UDI blocks as index blocks #14965 Account UDI blocks as index blocks
  11. Support parallel AddIndexEntry in trie index #14966 Support parallel AddIndexEntry in trie index
  12. Cover trie index modes #14967 Cover trie index modes
  13. Add IndexFactory stress and benchmark flags #14968 Add IndexFactory stress and benchmark flags

Previous: #14965.
Next: #14967.

Depends on #14965. Because this PR targets facebook/rocksdb:main, GitHub shows a cumulative diff until earlier PRs land. After those land, the intended review diff is:

zaidoon/udi-08-udi-block-cache-accounting..zaidoon/udi-09-trie-parallel-builder

That final review delta is 4 files with 505 insertions and 170 deletions.

What changed:

  • Support parallel AddIndexEntry calls in the trie index builder path.
  • Add trie tests for the parallel builder behavior.

Validation:

  • AUTO_CLEAN=1 make -j14 trie_index_test
  • ./trie_index_test --gtest_filter=TrieIndexFactoryTest.*:TrieIndexSSTTest.*
  • make check-sources

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown

✅ clang-tidy: No findings on changed lines

Completed in 1027.7s.

@zaidoon1
zaidoon1 force-pushed the zaidoon/udi-09-trie-parallel-builder branch 3 times, most recently from ecf915c to 03ee07a Compare July 20, 2026 04:53
@github-actions

Copy link
Copy Markdown

✅ Claude Code Review

Auto-triggered after CI passed — reviewing commit 03ee07a


Summary

Clean, well-structured PR that adds parallel compression support to the trie index builder. The split of AddIndexEntry into PrepareAddEntry (emit thread) + FinishAddEntry (BG writer) is logically correct and faithfully mirrors the synchronous path. The same-user-key detection split is sound. Thread safety is handled via atomic mirrors for EstimatedSize(). Four new tests cover the core parallel protocol, serial-parallel equivalence, and edge cases.

High-severity findings (0):

No high-severity findings.

Full review (click to expand)

Findings

🔴 HIGH

None.

🟡 MEDIUM

M1. Redundant non-atomic counter maintenance -- trie_index_factory.h
  • Issue: Both total_separator_bytes_ (non-atomic) and total_separator_bytes_atomic_ (atomic) are maintained in lockstep. The non-atomic total_separator_bytes_ is never read after this PR -- EstimatedSize() was the sole consumer and now reads the atomic. The non-atomic counter appears to be dead code.
  • Root cause: The non-atomic counter was preserved for backward compatibility but is no longer consumed.
  • Suggested fix: Remove total_separator_bytes_ entirely and use only the atomic, or document why it's kept (e.g., for debug assertions).
M2. No concurrent-thread test for EstimatedSize() -- trie_index_test.cc
  • Issue: ParallelEstimatedSizeStaysMonotonic calls PrepareAddEntry and FinishAddEntry sequentially on the same thread. It does NOT exercise the actual concurrent scenario where EstimatedSize() is called on the emit thread while FinishAddEntry runs on a BG worker thread. The test comment acknowledges this.
  • Suggested fix: Add a stress test with actual threading, or use COERCE_CONTEXT_SWITCH=1 with sync-point-based concurrency.
M3. Missing parallel-path test for same-user-key overflow runs -- trie_index_test.cc
  • Issue: ParallelMatchesSerialOutput has one same-user-key boundary but no large overflow runs (3+ consecutive same-separator blocks). The sync path has LargeOverflowRun and MixedSameKeyRuns tests but no parallel equivalents. The buffer-back-check in FinishAddEntry for long runs deserves dedicated coverage.
  • Suggested fix: Add ParallelLargeOverflowRunMatchesSerial with 5+ same-key blocks.

🟢 LOW / NIT

L1. separator_key string allocation in PrepareAddEntry -- trie_index_factory.cc:279
  • Issue: ToString() allocates on every call. Ring buffer reuse amortizes this after warmup. Not a bottleneck since it's called once per data block.
L2. Test helper EntryCtx uses raw bit-shifting instead of PackSequenceAndType -- trie_index_test.cc:52
  • Issue: Inconsistent with SeekCtx which uses the canonical packing function. Both produce correct results.

Cross-Component Analysis

Context Assumptions hold? Action needed?
Parallel compression YES - emit/BG writer split correct None
Single-threaded fallback YES - AddIndexEntry sync path unchanged None
kCustomOnly mode YES - index_builder null, custom_indexes has trie None
kStandardDefault mode YES - both built-in and custom entries staged None

Key invariant verification: The parallel path produces identical buffered_entries_ to the sync path because (1) FindShortestSeparator receives identical inputs, (2) FinishAddEntry runs serially in commit order so back() is always the correct preceding entry, and (3) tag assignment logic is duplicated identically.

Positive Observations

  1. Clean Prepare/Finish split faithfully mirrors the built-in index builder pattern
  2. Defensive valid flag prevents processing stale ring buffer data
  3. Ring buffer flag reset (custom_entries_prepared = false) at top of EmitBlockForParallel prevents stale-flag bugs
  4. ParallelMatchesSerialOutput test verifies byte-identical output
  5. SkipCustomPrepare sync point is a thoughtful test hook for flag-reset safety

ℹ️ About this response

Generated by Claude Code.
Review methodology: claude_md/code_review.md

Limitations:

  • Claude may miss context from files not in the diff
  • Large PRs may be truncated
  • Always apply human judgment to AI suggestions

Commands:

  • /claude-review [context] — Request a code review
  • /claude-query <question> — Ask about the PR or codebase

@zaidoon1
zaidoon1 force-pushed the zaidoon/udi-09-trie-parallel-builder branch from 03ee07a to 2ee40ce Compare July 20, 2026 17:53
@zaidoon1
zaidoon1 force-pushed the zaidoon/udi-09-trie-parallel-builder branch from 2ee40ce to e1a6462 Compare July 21, 2026 23:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant