Skip to content

[ISSUE #4562]✨Enhance IndexService: improve file loading, add index type support, and optimize file deletion logic - #4563

Merged
rocketmq-rust-bot merged 1 commit into
mainfrom
enh-4562
Dec 11, 2025
Merged

rocketmq-rust-bot merged 1 commit into
mainfrom
enh-4562

Conversation

@mxsm

@mxsm mxsm commented Dec 11, 2025 •

Copy link
Copy Markdown
Owner

Which Issue(s) This PR Fixes(Closes)

Fixes #4562

Brief Description

How Did You Test This Change?

Summary by CodeRabbit

  • New Features

    • Added support for tag-type indexing alongside existing key and unique indexing types.
    • Introduced type-aware query capability for improved message retrieval flexibility.
  • Improvements

    • Enhanced index file lifecycle management with more robust loading, deletion, and validation logic.

✏️ Tip: You can customize this high-level summary in your review settings.

…ype support, and optimize file deletion logic
Copilot AI review requested due to automatic review settings December 11, 2025 15:11
@rocketmq-rust-bot rocketmq-rust-bot added the AI review first Ai review pr first label Dec 11, 2025
@rocketmq-rust-bot

Copy link
Copy Markdown
Collaborator

🔊@mxsm 🚀Thanks for your contribution🎉!

💡CodeRabbit(AI) will review your code first🔥!

Note

🚨The code review suggestions from CodeRabbit are to be used as a reference only, and the PR submitter can decide whether to make changes based on their own judgment. Ultimately, the project management personnel will conduct the final code review💥.

@coderabbitai

coderabbitai Bot commented Dec 11, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

Two files modified: constants added to MessageConst for index typing, and IndexService enhanced with type-aware query support, improved file lifecycle management (loading, deletion, destruction), and helper methods for type-prefixed key construction. Tests added for new functionality.

Changes

Cohort / File(s) Summary
Constants for Index Types
rocketmq-common/src/common/message.rs
Added three public associated constants (INDEX_KEY_TYPE, INDEX_UNIQUE_TYPE, INDEX_TAG_TYPE) to MessageConst for index type classification.
Type-Aware Querying
rocketmq-store/src/index/index_service.rs
Added query_offset_with_type() method accepting optional index type parameter; query_offset() now delegates to it with index_type=None. Added build_key_with_type() helper to construct type-prefixed keys (e.g., topic#T#key for tag-type queries).
File Lifecycle and Operations
rocketmq-store/src/index/index_service.rs
Reworked load() with early failure return, sorted file listing, and conditional loading logic; split delete_expired_file() into two-phase operation (collect, then delete); introduced delete_expired_file_list() for single-pass deletion and memory list update; reworked destroy() with write lock safety; enhanced get_and_create_last_index_file() with phase-split inspection and async flush.
Testing and Imports
rocketmq-store/src/index/index_service.rs
Added cheetah_string::CheetahString import. Added unit tests validating key formats, tag handling in build_index, and type-aware query behavior.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • File loading logic: Review conditional loading based on last_exit_ok vs checkpoint timestamp, early return handling, and sorted file iteration
  • Two-phase delete operation: Verify correctness of candidate collection and deletion phases, ensure memory index list is updated atomically
  • Type-aware key construction: Confirm type-prefixed key format (topic#T#key) doesn't conflict with existing non-typed queries
  • Lifecycle management in get_and_create_last_index_file: Check thread-safety of phase-split (read lock → possible write lock → async flush)
  • Test coverage: Validate unit tests comprehensively cover edge cases for new query paths and key formatting

Poem

🐰 Three types now tagged with K, U, and T,
Indexing queries dance wild and free,
File loading cleaned, deletions refined,
Lifecycle managed with careful mind,
A stronger store, hopping with glee! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main changes: enhanced IndexService with improved file loading, index type support, and optimized file deletion logic.
Linked Issues check ✅ Passed The PR code changes directly address all three objectives from issue #4562: improved file loading, added index type support, and optimized file deletion logic.
Out of Scope Changes check ✅ Passed All changes align with the stated objectives. The addition of message constants, index service enhancements, and related tests are directly related to supporting index types.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch enh-4562

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances the IndexService implementation with improved file loading logic, support for index types (particularly tag indexing), and optimized file deletion mechanisms. The changes refactor several methods to use more idiomatic Rust patterns and improve concurrency through better lock management.

Key Changes

  • Added index type constants (INDEX_KEY_TYPE, INDEX_UNIQUE_TYPE, INDEX_TAG_TYPE) to support different index formats
  • Introduced tag-based indexing capability with query_offset_with_type method and corresponding build_index logic
  • Optimized delete_expired_file logic with two-phase locking strategy to reduce write lock contention

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
rocketmq-common/src/common/message.rs Adds three index type constants (K, U, T) to support different index key formats
rocketmq-store/src/index/index_service.rs Major refactoring including: improved load method with better error handling, optimized file deletion with two-phase locking, new query_offset_with_type method for tag queries, tag indexing support in build_index, cleaner put_key/retry logic, better lock management in get_and_create_last_index_file, and comprehensive test coverage

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +216 to +217
/// * `index_type` - Optional index type (e.g., MessageConst::INDEX_TAG_TYPE) If None or empty,
/// uses default format: topic#key If INDEX_TAG_TYPE, uses format: topic#T#key

Copilot AI Dec 11, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation formatting is unclear. The sentence runs together without proper punctuation. Consider reformatting to:

  • index_type - Optional index type (e.g., MessageConst::INDEX_TAG_TYPE). If None or empty, uses default format: topic#key. If INDEX_TAG_TYPE, uses format: topic#T#key
Suggested change
/// * `index_type` - Optional index type (e.g., MessageConst::INDEX_TAG_TYPE) If None or empty,
/// uses default format: topic#key If INDEX_TAG_TYPE, uses format: topic#T#key
/// * `index_type` - Optional index type (e.g., MessageConst::INDEX_TAG_TYPE).
/// - If None or empty, uses default format: `topic#key`.
/// - If INDEX_TAG_TYPE, uses format: `topic#T#key`.

Copilot uses AI. Check for mistakes.
error!(
"putKey error commitlog {} tags {}",
dispatch_request.commit_log_offset, tags
);

Copilot AI Dec 11, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inconsistent error handling: when tag indexing fails, the function continues execution without returning early, unlike the error handling for uniq_key (line 315) and regular keys (line 334). Consider adding a return statement after the error log if tag indexing failures should also stop the indexing process, or add a comment explaining why tag indexing failures are non-fatal.

Suggested change
);
);
return;

Copilot uses AI. Check for mistakes.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
rocketmq-store/src/index/index_service.rs (3)

186-190: Consider using HashSet for O(n) lookup instead of O(n*m).

The current implementation uses Vec::contains() inside retain(), resulting in O(n*m) complexity. For large numbers of expired files, a HashSet would provide O(n+m) complexity.

+use std::collections::HashSet;
+
-        let mut destroyed_files = Vec::new();
+        let mut destroyed_files = HashSet::new();
         for file in files.iter() {
             let file_name = file.get_file_name();
             if file.destroy(3000) {
-                destroyed_files.push(file_name.clone());
+                destroyed_files.insert(file_name.clone());
                 info!("Delete expired index file success: {}", file_name);
             } else {
                 error!("Delete expired index file failed: {}", file_name);
                 break;
             }
         }

236-272: Consider using .iter().rev().enumerate() for more idiomatic iteration.

The current loop pattern for i in (1..=len).rev() with index_file_list[i - 1] works but is unconventional. A more idiomatic approach would use the iterator directly.

-            for i in (1..=index_file_list.len()).rev() {
-                let f = &index_file_list[i - 1];
-                let last_file = i == index_file_list.len();
+            let len = index_file_list.len();
+            for (rev_idx, f) in index_file_list.iter().rev().enumerate() {
+                let last_file = rev_idx == 0;

566-568: The 10ms sleep may cause test flakiness in CI environments.

The spawn_blocking task for flushing may not complete within 10ms on slower or loaded systems. Consider using a synchronization mechanism or accepting that this is a smoke test for the logic flow.

If the intent is just to verify no panics occur, the sleep can be removed. If you need to verify the async task completes, consider using a longer timeout or a proper synchronization mechanism:

-        // Give async tasks time to complete
-        tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
+        // Give async tasks time to complete - use longer timeout for CI stability
+        tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fec002a and 2c7dbbb.

📒 Files selected for processing (2)
  • rocketmq-common/src/common/message.rs (1 hunks)
  • rocketmq-store/src/index/index_service.rs (9 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Build & Test (ubuntu-latest)
  • GitHub Check: Build & Test (macos-latest)
  • GitHub Check: Build & Test (windows-latest)
  • GitHub Check: Code Coverage
  • GitHub Check: Agent
  • GitHub Check: auto-approve
🔇 Additional comments (9)
rocketmq-common/src/common/message.rs (1)

595-599: LGTM!

The new index type constants are well-defined and follow the existing naming conventions in MessageConst. The single-character type codes ("K", "U", "T") are consistent with typical RocketMQ conventions.

rocketmq-store/src/index/index_service.rs (8)

129-135: LGTM!

Clean, idiomatic implementation that correctly calculates total size based on uniform file sizes.


193-200: LGTM!

Clean implementation that safely destroys all index files under a write lock and clears the list.


339-364: LGTM!

Tag indexing correctly extracts tags from properties_map and uses the type-prefixed key format. Error handling is consistent with the existing pattern.


372-391: LGTM!

The refactored put_key method cleanly handles the retry logic with a simple loop that exits on success or when index file creation fails.


414-468: LGTM!

The two-phase read-then-write locking approach effectively minimizes lock contention. Using spawn_blocking for the flush operation is appropriate since it involves I/O.


470-489: LGTM!

Clean implementation using let-else for early return. The conditional checkpoint update based on is_write_full() is correct behavior.


492-500: LGTM!

Simple and well-defined helper functions for consistent key formatting. The inline annotation is appropriate for these small functions.


115-123: The review comment is based on a false premise. The load() method returns void (unit type), not a Result or bool. There is no return value to "ignore." The suggested diff would not compile because you cannot use if ! on a void method.

The actual error handling in the code uses .unwrap() on line 73 of index_header.rs, which will panic if get_bytes() fails. If error handling is a concern, it should address the aggressive .unwrap() rather than a non-existent return value.

Likely an incorrect or invalid review comment.

@codecov

codecov Bot commented Dec 11, 2025 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 47.36842% with 110 lines in your changes missing coverage. Please review.
✅ Project coverage is 31.01%. Comparing base (fec002a) to head (2c7dbbb).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
rocketmq-store/src/index/index_service.rs 47.36% 110 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4563      +/-   ##
==========================================
+ Coverage   30.79%   31.01%   +0.22%     
==========================================
  Files         673      673              
  Lines       97983    98095     +112     
==========================================
+ Hits        30172    30424     +252     
+ Misses      67811    67671     -140     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@rocketmq-rust-bot rocketmq-rust-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - All CI checks passed ✅

@rocketmq-rust-bot
rocketmq-rust-bot merged commit 1449505 into main Dec 11, 2025
28 checks passed
@rocketmq-rust-bot rocketmq-rust-bot added approved PR has approved and removed ready to review waiting-review waiting review this PR labels Dec 11, 2025
@mxsm
mxsm deleted the enh-4562 branch December 14, 2025 13:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Enhancement✨] Enhance IndexService: improve file loading, add index type support, and optimize file deletion logic

4 participants