Skip to content

Add hive-style path attributes to directory spools - #776

Merged
d-chambers merged 4 commits into
devfrom
hive-path-attrs
Jul 25, 2026
Merged

Add hive-style path attributes to directory spools#776
d-chambers merged 4 commits into
devfrom
hive-path-attrs

Conversation

@d-chambers

@d-chambers d-chambers commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Description

Directory spools now parse key=value pairs out of the paths inside the spool, Hive-style. Each directory segment can hold one pair (network=XX/), and any segment — including the file name, with its extension stripped — can hold several separated by __ (the same separator get_patch_names uses), e.g. station=A__tag=raw.h5. Parsed values become string attrs: they appear in get_contents(), work with select (equality, collections, glob, regex), participate in chunk grouping, survive unions/pickling, and are stamped onto loaded patches. When a path attr and a file-declared attr share a name, the path wins — renaming a directory (or file) attaches or corrects metadata without rewriting data.

Details:

  • Parser: dascore.utils.paths.parse_hive_path_attrs (percent-decoding, deepest-key-wins, Hive NULL sentinel skipped, letter-led extension stripping so depth=1.5 survives). Reserved/underscore key names follow the same skip/warn rules as file attrs.
  • Provenance: the applied dict is persisted per source (sources.path_attrs, JSON) and surfaced privately as _path_attrs, since derived/union catalogs absolutize paths. INDEX_VERSION 3 → 4; existing indexes rebuild automatically.
  • Move detection: updates match a disappeared path to a brand-new one by exact (mtime_ns, size_bytes) identity (unique 1:1 on both sides; the rename-invariant manifest signature for directory-format units) and rewrite paths + path-derived attrs in batched SQL, never re-reading contents. Renames that remove a hive key, or ambiguous stat matches, fall back to a rescan.
  • Values stay strings (no type inference); numeric inference could be a follow-up if range selects on path keys turn out to matter.

Benchmarks vs dev (600 files / 12 partition dirs): cold index build, no-op update, time select, and patch loading unchanged within noise; renaming one partition dir + update went 457 ms → 72 ms, renaming all 12 dirs 4.13 s → 0.12 s (~34×, and the gap grows with archive size since dev rescans contents). Path parsing costs ~1.5 µs/path. Two codspeed benchmarks added (TestHivePathAttrBenchmarks: hive indexing, patch loading with stamped attrs).

Behavior note for release: directories whose names happen to contain = now silently produce attrs, and the version bump forces a one-time index rebuild.

Changelog

  • added: directory spools parse Hive-style key=value path segments into string attrs, usable in get_contents(), select, and chunk grouping; a path attr wins over a file-declared attr of the same name, so renaming a directory attaches metadata without rewriting data. Any path segment containing = is parsed this way, so a directory named for something else that happens to contain one now yields an attr.

Checklist

I have (if applicable):

  • referenced the GitHub issue this PR closes.
  • documented the new feature with docstrings and/or appropriate doc page.
  • included tests. See testing guidelines.
  • added the "ready_for_review" tag once the PR is ready to be reviewed.

Summary by CodeRabbit

  • New Features
    • Added support for Hive-style key=value path attributes in directory-based spools.
    • Path attributes are now stored and surfaced in spool contents, enabling filtering and appearing on loaded patches.
    • Includes correct parsing (encoded values, __-separated pairs, repeated-key precedence) and efficient rename/move handling that updates attributes without rescanning when safe.
  • Bug Fixes
    • Path-derived attributes correctly override conflicting file-defined attributes.
  • Documentation
    • Expanded spool index and tutorial docs with examples and rename edge cases.
  • Tests
    • Added end-to-end coverage for parsing, selection, patch stamping, and move detection.

key=value segments in paths under a directory spool (each directory
segment, plus __-separated pairs in any segment including the
extension-stripped file name) become string attrs: they appear in
get_contents(), work with select (equality/collections/glob/regex),
and are stamped onto loaded patches. A path attr overrides a
same-named attr declared inside the file, so renaming a directory is
a cheap way to attach or correct metadata.

The applied dict is persisted per source (sources.path_attrs, JSON)
and surfaced privately as _path_attrs, since derived/union catalogs
absolutize paths. INDEX_VERSION bumps to 4; old indexes rebuild
automatically.

Directory updates now detect renames/moves by exact (mtime_ns,
size_bytes) identity (1:1 both sides) and rewrite paths and
path-derived attrs in batched SQL instead of rescanning contents;
renames that remove a hive key, or ambiguous stat matches, fall back
to a rescan. Renaming 12 partition dirs over 600 files went from
4.1s (full rescan) to 0.12s; steady-state indexing, selection, and
patch loading are unchanged within noise.
@d-chambers d-chambers added the ready_for_review PR is ready for review label Jul 25, 2026
@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@d-chambers, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 20 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: aa21d37d-ab97-4af8-9dc6-5565eefa43c6

📥 Commits

Reviewing files that changed from the base of the PR and between f6bc65e and 05f078c.

📒 Files selected for processing (3)
  • dascore/io/index/backend.py
  • dascore/io/index/ingest.py
  • tests/test_io/test_index/test_hive_attrs.py
📝 Walkthrough

Walkthrough

Changes

Hive-style key=value path attributes are parsed, merged into patch attributes, persisted in the spool index, restored on patch loading, and updated during source renames. Tests, benchmarks, and documentation cover parsing, selection, stamping, moves, and edge cases.

Hive path attributes

Layer / File(s) Summary
Path attribute parsing and contracts
dascore/utils/paths.py, dascore/io/index/ingest.py, dascore/io/index/schema.py
Adds Hive path parsing, typed attribute handling, source-record storage, index versioning, and reserved-column protection.
Ingestion and index storage
dascore/io/index/ingest.py, dascore/io/index/backend.py, dascore/io/index/query.py
Merges path attributes into indexed patch attributes, serializes them on source rows, and includes them in SQL projections.
Patch attribute restoration
dascore/io/index/catalog.py, dascore/io/index/backend.py
Restores persisted path attributes onto loaded patches and exposes them as private _path_attrs in flattened relations.
Move detection and source rewriting
dascore/io/index/indexer.py, dascore/io/index/backend.py
Detects eligible source moves, rewrites paths and derived attributes without rescanning, and retains rescans for unsupported cases.
End-to-end validation and usage examples
tests/test_io/test_index/test_hive_attrs.py, benchmarks/test_spool_benchmarks.py, docs/notes/spool_index.qmd, docs/tutorial/spool.qmd
Covers parsing, indexing, patch stamping, selection, move handling, benchmarks, and documented usage examples.

Possibly related PRs

  • DASDAE/dascore#751: Extends the spool SQLite indexing stack that this change adds Hive-style path-attribute persistence and move rewriting to.

Suggested labels: IO, spool, documentation

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding hive-style path attributes to directory spools.
Description check ✅ Passed The description covers the feature, behavior, implementation details, benchmarks, and checklist items, matching the template well.
Docstring Coverage ✅ Passed Docstring coverage is 97.14% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hive-path-attrs

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.

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation IO Work for reading/writing different formats patch related to Patch class spool related to Spool class labels Jul 25, 2026

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@dascore/io/index/ingest.py`:
- Around line 228-257: Add stacklevel=2 to both warnings.warn calls in the
file-attribute and hive_path_attrs handling, including the calls near typed
attribute processing and inside hive_path_attrs, so warnings point to the
caller.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 032b5374-60fc-40e8-9855-500cff18c5d3

📥 Commits

Reviewing files that changed from the base of the PR and between f4fae61 and 4cdbad8.

📒 Files selected for processing (11)
  • benchmarks/test_spool_benchmarks.py
  • dascore/io/index/backend.py
  • dascore/io/index/catalog.py
  • dascore/io/index/indexer.py
  • dascore/io/index/ingest.py
  • dascore/io/index/query.py
  • dascore/io/index/schema.py
  • dascore/utils/paths.py
  • docs/notes/spool_index.qmd
  • docs/tutorial/spool.qmd
  • tests/test_io/test_index/test_hive_attrs.py

Comment thread dascore/io/index/ingest.py Outdated
sqlite3's context manager only wraps the transaction, so the test's
connection stayed open and blocked the rebuild's index unlink on
Windows; close it explicitly. The tutorial's rmtree likewise deleted
a directory holding the spool's open index; drop the cleanup like the
other tutorial cells.
@coderabbitai coderabbitai Bot removed the patch related to Patch class label Jul 25, 2026
@codecov

codecov Bot commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (f4fae61) to head (05f078c).

Additional details and impacted files
@@            Coverage Diff             @@
##               dev      #776    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files          164       164            
  Lines        17356     17471   +115     
==========================================
+ Hits         17356     17471   +115     
Flag Coverage Δ
network 48.10% <29.45%> (-0.17%) ⬇️
unittests 100.00% <100.00%> (ø)

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

☔ View full report in Codecov by Harness.
📢 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.

Drop the redundant empty-moves guard (the syncer already checks),
test a plain no-hive rename as a move, and unit-test _detect_moves
skipping unstatted sources and the root unit.
@github-actions

github-actions Bot commented Jul 25, 2026

Copy link
Copy Markdown

✅ Documentation built:
👉 Download
Note: You must be logged in to github and a DASDAE member to access the link.

@d-chambers
d-chambers merged commit 1183dbc into dev Jul 25, 2026
27 checks passed
@d-chambers
d-chambers deleted the hive-path-attrs branch July 25, 2026 10:54
@d-chambers d-chambers removed the ready_for_review PR is ready for review label Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation IO Work for reading/writing different formats spool related to Spool class

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant