Draft: TriHashMap Entry API#290
Draft
SG-devel wants to merge 10 commits into
Draft
Conversation
Remove a stale dead-code helper from support::entry and make TriHashMap non-unique entry Debug output use the public per-key view instead of internal slot-mapping fields.
Add model-based property tests for TriHashMap entry insertion and removal, matching the BiHashMap entry API coverage while preserving TRI's first-key-hit removal order. Extend the naive test oracle with TRI entry insert/remove behavior, including partial and mixed occupied entries. Also cover vacant insert_entry hash mismatch panics, exact unique occupied entry insert/remove cases, and or_insert_with laziness for unique and repeated mixed entries. Tighten TRI entry documentation around hash validation and improve entry-related panic messages.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft: I am opening this for maintainer feedback and discussion before converting it to a ready-for-review PR. The implementation follows the proposal in issue #7, but I would appreciate feedback on the API shape, scope, and semantics before continuing work and asking for formal review.
Summary
Implements the
TriHashMapEntry API.This adds a Tri-specific public Entry API while keeping the shared correctness-critical lookup-state logic internal. The API mirrors the existing
BiHashMapEntry style where appropriate, but uses accessor-backed non-unique views for TriHashMap so overlapping key matches such asA / A / BandA / B / Apreserve per-key mapping without exposing aliased mutable references.This implements the proposal from issue #7, with the concrete API shape shown below.
Commit structure
This PR is intentionally split into reviewable commits:
Prepare TriHashMap internals for Entry support
TriHashMap::tablesvisibility matchBiHashMapAdd shared internal Entry lookup state
support::entryMigrate BiHashMap internals to shared lookup state
Add initial TriHashMap Entry API
Entry,VacantEntry,OccupiedEntry,OccupiedEntryRef,NonUniqueEntryRefTriHashMap::entryAdd mutable occupied Entry views
OccupiedEntryMutandNonUniqueEntryMutand_modifyAdd occupied Entry mutation
removeinsertor_insertandor_insert_withDocument and harden the API
Clean up TriHashMap entry debug output
Test repeated non-unique key mapping
A / B / AmappingAand key2 toBfor_eachvisits distinct items once in first-key-hit orderAdd model-based TriHashMap Entry mutation coverage
NaiveMaporacle support for TRI entry remove and replacementinsert_entrymismatch, unique occupied, andor_insert_withlaziness testsImportant semantics
For
TriHashMap::entry(key1, key2, key3):None / None / Noneis vacant.A / A / Ais occupied unique.A / A / None,A / None / A, andNone / A / Aare occupied non-unique.A / A / B,A / B / A, andA / B / Care occupied non-unique.Non-unique access preserves per-key mapping. For example:
A / A / B, key1 and key2 both map toA, while key3 maps toB;A / B / A, key1 and key3 both map toA, while key2 maps toB.Mutable non-unique access is accessor-backed and stores one mutable reference per distinct matched item, preventing the public API from exposing aliased mutable references.
Removal, replacement, and visitor-style APIs process distinct matched items in deterministic first-key-hit order.
Testing notes
The entry mutation behavior is covered with model-based property tests.
The real
TriHashMapis tested againstNaiveMap, a simple vector-backed oracle. For each generated operation, the test applies the operation to both implementations, compares the externally visible result, and then validates the real map's internal invariants.For TRI entry coverage, the property tests include:
EntryRemove(UniqueKeysOp), which resolves entry keys from the current oracle state to generate vacant, partial, mixed, and unique occupied states.EntryInsertOverwrite(EntryInsertOverwriteOp), which resolves entry keys the same way, then constructs a replacement item using exactly those keys so the property test exercises compatible occupied replacement rather than mismatch panics.The oracle preserves TRI's documented first-key-hit return order while removing from its backing vector in descending physical index order to avoid shifted-index artifacts.
This is intended to give TRI entry mutation coverage comparable to the existing BI entry API property coverage while preserving TRI-specific ordering semantics.
Validation
GitHub CI is green in my fork. I ran locally:
cargo fmt --check cargo xfmt --check cargo check cargo check -p iddqd --no-default-features cargo clippy --all-targets --all-features -- -D warnings cargo test -p iddqd --doc cargo nextest run -p iddqd PROPTEST_CASES=10000 cargo nextest run -p iddqd \ bi_hash_map::proptest_ops \ tri_hash_map::proptest_ops PROPTEST_CASES=10000 cargo nextest run -p iddqd \ bi_hash_map::proptest_panic_safety::proptest_panic_ops \ tri_hash_map::proptest_panic_safety::proptest_panic_ops PROPTEST_CASES=10000 cargo nextest run -p iddqd bi_hash_map tri_hash_mapNotes
The implementation keeps the public API arity-specific. It does not introduce a generic public Entry framework.
The shared lookup-state primitive remains crate-internal and uses the existing internal item-index representation.
Contribution
I submit this contribution under the repository’s existing license terms, MIT OR Apache-2.0, without any warranty.
AI assistance disclosure: I used ChatGPT (GPT-5.5 Thinking, Codex) throughout development of this patch, including reasoning about the issue, writing code and tests, reviewing the implementation, and writing PR text. I guided the work and ran the listed checks.