Skip to content

refactor(storage): split db.rs into a directory module — mod/hash_ttl/kv_ops/accessors#403

Merged
TinDang97 merged 1 commit into
mainfrom
refactor/db-directory-split
Jul 20, 2026
Merged

refactor(storage): split db.rs into a directory module — mod/hash_ttl/kv_ops/accessors#403
TinDang97 merged 1 commit into
mainfrom
refactor/db-directory-split

Conversation

@TinDang97

@TinDang97 TinDang97 commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

What

db.rs (3113 lines, vs the repo's 1500-line rule) becomes a directory module:

File Lines Contents
db/mod.rs 1152 Database struct, constants, cost fns, HashTtlCond/FieldState/WrongType, ctor/clock, memory accounting, Default, all tests
db/kv_ops.rs 833 get/set/remove families, lazy expiry, cold-tier promotion/read-through, scan, versioning/LRU
db/accessors.rs 701 W5 ValueKind/OwnedKind generics, per-type delegators, intset/listpack bespoke accessors, read-only refs, blocking-hook helpers, streams
db/hash_ttl.rs 476 HEXPIRE-family per-field TTL primitives

Why now

The W5 typed-accessor unification (#400) concentrated the accessor matrix into three generics, leaving clean seams. Follow-up flagged at campaign close.

Invariants

  • Pure code motion — every method body moved verbatim; public paths unchanged (submodules only add inherent impl Database blocks; pub use re-exports untouched).
  • Only visibility changed: check_expired / is_expired / wrongtype_error / cold_contains_alive / cold_read_onlypub(super) (cross-file access within the module tree).
  • Submodule files use crate:: imports; tests stay in mod.rs — both per the CLAUDE.md module-structure convention.

Gates

  • macOS lib: 4427 passed (identical count to pre-split main)
  • VM Linux lib: 4449 (monoio) + 3616 (tokio,jemalloc), both green
  • clippy -D warnings clean on both feature sets; fmt clean; CHANGELOG entry added

Summary by CodeRabbit

  • New Features

    • Added per-field expiration controls for hashes, including conditional expiration, TTL inspection, persistence, and atomic get-and-delete operations.
    • Improved support for collections stored in the cold tier, including read-through access and promotion when needed.
    • Added more consistent expiration handling across keys and collection types.
  • Bug Fixes

    • Prevented expired or cold-stored data from appearing as missing or being replaced by empty containers.
    • Improved key existence, scanning, random-key selection, and memory tracking across hot and cold storage.

…/kv_ops/accessors

db.rs had grown to 3113 lines against the repo's 1500-line file-size
rule. The W5 typed-accessor unification (#400) concentrated the accessor
matrix into three generics, which made the module's internal seams
clean enough for a mechanical split:

- db/mod.rs (1152 lines): Database struct, listpack/intset constants,
  per-element cost functions, HashTtlCond/FieldState/WrongType,
  ctor/clock methods, O(1) memory accounting, Default impl, and the
  whole test module (tests stay in mod.rs per repo convention).
- db/hash_ttl.rs (476): HEXPIRE-family per-field TTL storage
  primitives (hash_set_field_ttl .. cleanup_empty_hash).
- db/kv_ops.rs (833): core keyspace ops — get/set/remove families,
  lazy expiry, cold-tier promotion/read-through, scan/keys/random_key,
  expiry bookkeeping, versioning/LRU touch.
- db/accessors.rs (701): W5 ValueKind/OwnedKind generic skeletons,
  per-type thin delegators, bespoke intset/listpack accessors,
  read-only ref accessors, blocking-wakeup list/zset helpers, streams.

Pure code motion: every method body moved verbatim; public paths are
unchanged (storage::db::Database and the cost fns resolve exactly as
before; submodules only add inherent impl blocks). The only signature
changes are visibility: check_expired / is_expired / wrongtype_error /
cold_contains_alive / cold_read_only became pub(super) so sibling
files and mod.rs tests keep access. Submodule files use crate::
imports per the module-structure convention.

Gates: lib suite 4427 green (identical count to pre-split main);
clippy -D warnings clean on default and tokio,jemalloc feature sets;
fmt; VM Linux lib green on both runtimes.

author: Tin Dang
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@TinDang97
TinDang97 merged commit 6c213fd into main Jul 20, 2026
6 of 8 checks passed
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 36bee76b-08ca-4fe5-a172-45c92d6ee3f1

📥 Commits

Reviewing files that changed from the base of the PR and between 3cf6474 and 5a217e1.

📒 Files selected for processing (6)
  • CHANGELOG.md
  • src/storage/db.rs
  • src/storage/db/accessors.rs
  • src/storage/db/hash_ttl.rs
  • src/storage/db/kv_ops.rs
  • src/storage/db/mod.rs

📝 Walkthrough

Walkthrough

The database implementation is reorganized into src/storage/db modules for core state, keyspace operations, typed collection access, and hash field TTL behavior. It adds hot/cold promotion and read-through paths, O(1) memory accounting, and tests covering expiration, encoding upgrades, and cold-tier visibility.

Changes

Database storage implementation

Layer / File(s) Summary
Database core contracts and state
src/storage/db/mod.rs, CHANGELOG.md
Defines database state, TTL semantic types, memory-cost helpers, cached time handling, accounting APIs, and documents the module split.
Hot and cold keyspace operations
src/storage/db/kv_ops.rs
Implements lazy expiration, cold-tier reads and promotion, mutations, deletion, enumeration, sampling, TTL updates, versioning, and LRU tracking.
Typed collection and stream access
src/storage/db/accessors.rs
Adds typed read and mutation accessors for collections and streams, compact encoding upgrades, existence checks, and list/sorted-set helpers.
Hash field TTL and atomic removal
src/storage/db/hash_ttl.rs
Adds conditional field expiry, persistence and clearing, encoding downgrades, field deletion, atomic get-and-delete, and empty-hash cleanup.
Database behavior validation
src/storage/db/mod.rs
Adds coverage for expiration, memory accounting, hot/cold shadows, typed access, and cold collection visibility.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Database
  participant ColdIndex
  participant ColdDisk
  Client->>Database: Read key
  Database->>ColdIndex: Check cold location and TTL
  ColdIndex-->>Database: Return location
  Database->>ColdDisk: Read cold value
  ColdDisk-->>Database: Return decoded value
  Database->>ColdIndex: Revalidate and update cold state
  Database-->>Client: Return value or absence
Loading

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/db-directory-split

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.

@TinDang97
TinDang97 deleted the refactor/db-directory-split branch July 20, 2026 06:47
TinDang97 added a commit that referenced this pull request Jul 20, 2026
…L fidelity (#404)

Patch release rolling up the storage-unification stacked train
(#396#401) and the follow-up db.rs directory split (#403).

Correctness: millisecond-TTL keys no longer expire up to 999 ms early
(CompactEntry stored expiry as ms/1000-floored seconds; now absolute
Unix ms end-to-end, exact PTTL readback, exact-ms RDB round-trips).

Unification (behavior-preserving, pinned by golden byte-spec tests):
one value codec behind RDB/spill/kv_serde with fail-closed corrupt
decode + DoS count guards on every path; one spill pipeline — sync
eviction batches victims into shared files (~N/256 manifest fsyncs
instead of N per-key) and retains unserializable victims fail-closed;
one eviction entry point (evict_to_budget + EvictionRun/EvictionSink,
was 13 variants / 5 reclaim-loop copies); one typed-accessor skeleton
(storage::db_kind static-dispatch markers); AofShardManifest rename;
db.rs split into db/{mod,hash_ttl,kv_ops,accessors}.rs.

Validation: same-VM A/B v0.8.1-vs-main — p=1 parity-or-better,
eviction-plain faster every paired round, spill +3%, p=16 within
noise. Release gate: crash-matrix nightly full matrix + ITERS=20
soak dispatched on the RC, green before tag (soak-first-then-tag).

Rolls CHANGELOG [Unreleased] into [0.8.2], bumps Cargo.toml/lock,
adds the RELEASES.md row, updates the README milestone table.

author: Tin Dang
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant