Skip to content

feat(flink): Extend RocksDBDAO with generic column-family lifecycle operations - #19744

Merged
danny0405 merged 1 commit into
apache:masterfrom
HuangZhenQiu:extend-rocksdb-dao
Aug 27, 2026
Merged

feat(flink): Extend RocksDBDAO with generic column-family lifecycle operations#19744
danny0405 merged 1 commit into
apache:masterfrom
HuangZhenQiu:extend-rocksdb-dao

Conversation

@HuangZhenQiu

@HuangZhenQiu HuangZhenQiu commented Aug 26, 2026

Copy link
Copy Markdown
Member

Extend RocksDBDAO with generic column-family lifecycle operations

Describe the issue this Pull Request addresses

Add columnFamilyExists and listColumnFamilies alongside the existing addColumnFamily/dropColumnFamily so callers can check existence and list managed column families; partition-aware naming and completeness tracking
belong in the Flink backend instead. Unit tests only; not wired into any operator yet.

closes #19600

Summary and Changelog

  1. Extend RocksDBDAO with new APIs to manage column family
  2. Add test cases for new apis

Impact

none

Risk Level

none

Documentation Update

none

Contributor's checklist

  • Read through contributor's guide
  • Enough context is provided in the sections above
  • Adequate tests were added if applicable

@github-actions github-actions Bot added the size:M PR with lines of changes in (100, 300] label Aug 26, 2026

@hudi-agent hudi-agent 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.

⚠️ 🤖 This review was generated by an AI agent and may contain mistakes. Please verify any suggestions before applying.

Thanks for working on this! This PR extends RocksDBDAO with column-family-per-partition lifecycle methods (create-if-absent, register-as-loaded, drop, and a default-CF registry), backed by unit tests and not yet wired into any operator. The encoding is consistent across put/get/delete/prefixSearch and no existing caller touches the default column family, so the change is self-contained. A couple of edge cases around concurrency and the default-CF exclusivity assumption are worth double-checking in the inline comments. Please take a look at any inline comments, and this should be ready for a Hudi committer or PMC member to take it from here. One naming inconsistency worth aligning, otherwise the code is clean and well-documented.

String columnFamilyName = getColumnFamilyNameForPartition(partitionPath);
ValidationUtils.checkArgument(managedDescriptorMap.containsKey(columnFamilyName),
"Column family for partition " + partitionPath + " must be created before it can be registered as loaded");
put(DEFAULT_COLUMN_FAMILY_NAME, partitionPath, Boolean.TRUE);

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.

🤖 The containsKey check followed by the registry put isn't atomic — if another thread runs dropPartitionColumnFamily for the same partition in between, we could end up registering it as loaded (registry=TRUE) after its column family handle has already been removed from managedHandlesMap. A later isPartitionRegistered would then return true while a read against the partition CF hits a null handle. Is this class intended to be single-writer per partition, or should register/drop be guarded so this interleaving can't leave the registry inconsistent?

⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.

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.

🤖 This looks like a real gap worth the author confirming. The sibling dropColumnFamily uses computeIfPresent to atomically remove the handle from managedHandlesMap, but there's no shared lock between it and the register path, and register spans two structures (the CF map plus the registry write into the default CF), so a single atomic map op wouldn't close it anyway. Existing users like RocksDbBasedFileSystemView rely on external single-threaded access — if the same single-writer-per-partition guarantee holds here it's fine, otherwise a lock around register/drop would be needed to avoid registering a partition whose handle was just dropped.

*/
public List<String> listRegisteredPartitions() {
ValidationUtils.checkArgument(!closed);
return this.<Boolean>prefixSearch(DEFAULT_COLUMN_FAMILY_NAME, "").map(Pair::getKey).collect(Collectors.toList());

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.

🤖 listRegisteredPartitions treats every key in the default column family as a registered partition path. That works today because no caller writes to the default CF, but it's an implicit exclusivity contract on a shared class. Could you document that the default CF is reserved for the partition registry (or use a dedicated key prefix) so a future caller storing unrelated keys in the default CF doesn't silently corrupt this listing?

⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.

*
* @param partitionPath Partition path
*/
public boolean isPartitionRegistered(String partitionPath) {

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.

🤖 nit: registerPartitionAsLoaded / isPartitionRegistered use two different words for the same concept — could you align them? Either isPartitionLoaded or renaming the write side to registerPartition would make the pair easier to scan.

⚠️ AI-generated; verify before applying. React 👍/👎 to flag quality.

@codecov-commenter

codecov-commenter commented Aug 26, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 77.98%. Comparing base (bcaf2d4) to head (03876cf).

Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19744      +/-   ##
============================================
+ Coverage     77.96%   77.98%   +0.01%     
- Complexity    33457    33467      +10     
============================================
  Files          2539     2539              
  Lines        140939   140941       +2     
  Branches      17012    17012              
============================================
+ Hits         109886   109907      +21     
+ Misses        23397    23374      -23     
- Partials       7656     7660       +4     
Components Coverage Δ
hudi-common 83.48% <100.00%> (+0.01%) ⬆️
hudi-client 83.06% <ø> (-0.03%) ⬇️
hudi-flink 85.68% <ø> (+0.06%) ⬆️
hudi-spark-datasource 72.38% <ø> (+<0.01%) ⬆️
hudi-utilities 74.34% <ø> (+0.01%) ⬆️
hudi-cli 15.06% <ø> (ø)
hudi-hadoop 69.24% <ø> (ø)
hudi-sync 75.56% <ø> (+0.02%) ⬆️
hudi-io 79.85% <ø> (+0.09%) ⬆️
hudi-timeline-service 83.74% <ø> (+0.29%) ⬆️
hudi-cloud 64.27% <ø> (ø)
hudi-kafka-connect 53.20% <ø> (ø)
Flag Coverage Δ
common-and-other-modules 51.04% <100.00%> (+<0.01%) ⬆️
flink-integration-tests 49.02% <0.00%> (+0.03%) ⬆️
hadoop-mr-java-client 43.74% <0.00%> (-0.02%) ⬇️
integration-tests 13.56% <0.00%> (-0.01%) ⬇️
spark-client-hadoop-common 50.54% <0.00%> (-0.01%) ⬇️
spark-java-tests 52.01% <100.00%> (+0.01%) ⬆️
spark-scala-tests 46.64% <0.00%> (+0.01%) ⬆️
utilities 36.41% <0.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...apache/hudi/common/util/collection/RocksDBDAO.java 74.66% <100.00%> (+2.91%) ⬆️

... and 14 files with indirect coverage changes

🚀 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.

@cshuo cshuo 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.

RocksDBDAO should remain a generic column-family abstraction. Partition naming, registration, and loaded-state management are RFC-107 cache policies and should live in the partition-aware Flink backend.

We should limit this PR to basic column-family operations, such as create, drop, existence checks, and listing, and move partition-specific logic to the Flink backend.

…perations

Add columnFamilyExists and listColumnFamilies alongside the existing
addColumnFamily/dropColumnFamily so callers can check existence and list
managed column families; partition-aware naming and completeness tracking
belong in the Flink backend instead. Unit tests only; not wired into any
operator yet.
@HuangZhenQiu HuangZhenQiu changed the title feat(flink): Extend RocksDBDAO with column-family based partition state management feat(flink): Extend RocksDBDAO with generic column-family lifecycle operations Aug 26, 2026

@hudi-agent hudi-agent 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.

⚠️ 🤖 This review was generated by an AI agent and may contain mistakes. Please verify any suggestions before applying.

Thanks for working on this! This PR adds two read accessors to RocksDBDAO — columnFamilyExists and listColumnFamilies — over the managed column-family map, along with unit tests. No issues flagged from this automated pass — a Hudi committer or PMC member can take it from here for a final review.

cc @yihua

String columnFamilyName = getColumnFamilyNameForPartition(partitionPath);
ValidationUtils.checkArgument(managedDescriptorMap.containsKey(columnFamilyName),
"Column family for partition " + partitionPath + " must be created before it can be registered as loaded");
put(DEFAULT_COLUMN_FAMILY_NAME, partitionPath, Boolean.TRUE);

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.

🤖 This looks like a real gap worth the author confirming. The sibling dropColumnFamily uses computeIfPresent to atomically remove the handle from managedHandlesMap, but there's no shared lock between it and the register path, and register spans two structures (the CF map plus the registry write into the default CF), so a single atomic map op wouldn't close it anyway. Existing users like RocksDbBasedFileSystemView rely on external single-threaded access — if the same single-writer-per-partition guarantee holds here it's fine, otherwise a lock around register/drop would be needed to avoid registering a partition whose handle was just dropped.

@HuangZhenQiu

Copy link
Copy Markdown
Member Author

RocksDBDAO should remain a generic column-family abstraction. Partition naming, registration, and loaded-state management are RFC-107 cache policies and should live in the partition-aware Flink backend.

We should limit this PR to basic column-family operations, such as create, drop, existence checks, and listing, and move partition-specific logic to the Flink backend.

Thanks for the suggestions. It is a better design to push the partition management in partition-aware Flink backend. Revised the PR with minimal api changes.

@github-actions github-actions Bot added size:S PR with lines of changes in (10, 100] and removed size:M PR with lines of changes in (100, 300] labels Aug 26, 2026
@hudi-bot

Copy link
Copy Markdown
Collaborator

CI report:

Bot commands @hudi-bot supports the following commands:
  • @hudi-bot run azure re-run the last Azure build

@cshuo cshuo 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.

+1.

@danny0405
danny0405 merged commit 18ae8c3 into apache:master Aug 27, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S PR with lines of changes in (10, 100]

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extend RocksDBDAO with generic column-family lifecycle operations

6 participants