8000 perf: bound attribute scans to exactly the queried attribute (#381) by adityamukho · Pull Request #382 · project-minigraf/minigraf · GitHub
[go: up one dir, main page]

Skip to content

perf: bound attribute scans to exactly the queried attribute (#381) - #382

Merged
adityamukho merged 1 commit into
mainfrom
fix/381-attr-scan-bound
Sep 26, 2026
Merged

adityamukho merged 1 commit into
mainfrom
fix/381-attr-scan-bound

Conversation

@adityamukho
@adityamukho adityamukho 8000 commented Sep 26, 2026
Copy link
Copy Markdown
Collaborator

Summary

FactStorage::get_facts_by_attribute ended its AEVT range at next_string_prefix(attr), which increments the last byte. For attributes ending in 0x7F or 0xBF (about 1 in 64 non-ASCII characters, e.g. :丿, :ÿ), the result is not valid UTF-8, so the committed scan ran to the end of the whole AEVT index and resolved every later fact before post-filtering. The range also covered prefix siblings (:ab, :a/b for :a).

Results are unchanged. The committed post-filter is still there as a guard, and the file format is unchanged.

Measurements

Checkpointed file: 100 facts on :丿 plus 40,000 on the neighbouring :丿x and :乀. Query [:find (count ?e) :where [?e :丿 ?v]], bench profile, mean of 10 runs:

before after
sparse :丿 scan 45.4 ms 251 µs (181×)

Tests

  • attribute_committed_range_is_bounded_for_any_attribute: a mock CommittedIndexReader records the AEVT bounds. It checks that the scan is bounded for :plain, :丿, :\u{bf} and :a\u{7f}, and that prefix siblings fall outside the range. This test fails on main.
  • attribute_scan_excludes_prefix_siblings_and_non_ascii_neighbours: runs the pending-index path.
  • tests/point_query_history_test.rs::attribute_scan_exact_for_non_ascii_and_prefix_siblings_file_backed: uses committed and pending facts on a real file and checks the results against the full-scan oracle.

Full suite: 1168 passed, 0 failed, 8 ignored. cargo clippy -D warnings is clean. Test counts are updated in CLAUDE.md, README.md and docs/TEST_COVERAGE.md, and the change is added to the CHANGELOG under Unreleased.

Closes #381
Refs #323

🤖 Generated with Claude Code

https://claude.ai/code/session_01BedF9ZmqVZLkvDwn91fuKy

get_facts_by_attribute ended its AEVT range at next_string_prefix(attr),
which increments the last byte. For attributes ending in 0x7F or 0xBF
(e.g. `:丿`, `:ÿ`) that is not valid UTF-8, so the committed scan ran to
the end of the AEVT index. It also covered prefix siblings (`:ab` for `:a`).

End the range at `attribute + "\0"`, the exact successor, as #380 does for
the entity path. Remove the now-unused next_string_prefix.

Sparse `:丿` scan (100 of 40.1k facts, checkpointed): 45.4 ms -> 251 µs.

Closes #381
Refs #323

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BedF9ZmqVZLkvDwn91fuKy
@adityamukho adityamukho added this to the v2.3.0 milestone Sep 26, 2026
@codecov
codecov Bot commented Sep 26, 2026
Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@adityamukho
adityamukho merged commit 69da4b2 into main Sep 26, 2026
17 checks passed
@adityamukho
adityamukho deleted the fix/381-attr-scan-bound branch September 26, 2026 04:40
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.

perf: attribute scan is unbounded to end of AEVT index for attributes ending in a 0xBF/0x7F byte

1 participant

0