Add zipper-type property tests: same_trie, seeded ring algebra, long-path serialization#48
Conversation
Whether two maps share the same root node by pointer. Because PathMap is copy-on-write, a map and a clone of it stay same_trie until one is mutated (any insert/removal replaces the root node), so a true result proves the node structure is unchanged relative to the other. Holding the other map (a cheap COW clone snapshot) alive prevents ABA pointer reuse. This is the O(1) staleness signal a content-keyed cache needs -- val_count is O(n) and uncached at arbitrary paths (measured 47ms over 1M facts), which defeats any per-query cache. Tested for clone-sharing, insert, remove, distinct-but-equal maps, and empty maps.
Implements the fuzz test the trailing TEST TODO in ring.rs described: seeded pseudorandom HashSet and nested-HashMap lattices checked against plain set oracles across pjoin / pmeet / psubtract / join_into, 64 seeds each, asserting both the results and the identity/element status masks. Also gives the empty sub-set collapse case the coverage its inline TODO asked for, and covers the HashMap psubtract the notes flagged as untested. The resolved TODO notes are removed; the unresolved ones (Vec SetLattice, LatticeCounter/LatticeBitfield traits) stay.
Answers the note at the top of paths_serialization.rs: round-trips deterministic xorshift paths of 7 / 2049 / 4097 / 24000 bytes, so the input spans the internal 4096-byte compression CHUNK, asserting path counts on both directions, per-path containment after the round-trip, and that nothing extra appears. No behavior change; the resolved note is removed.
828d66f to
257c7da
Compare
| inner_map_1.insert("1", ()); | ||
| a.0.insert("A", inner_map_1.clone()); | ||
| b.0.insert("B", inner_map_1); | ||
| // b.0.insert("C", HashMap::new()); TODO: We might want to test collapse of empty items using the is_bottom() method |
There was a problem hiding this comment.
This comment is deleted but is_bottom check is not introduced?
| /// Whether `self` and `other` share the same root node by pointer (O(1)). | ||
| /// PathMap is copy-on-write, so a map and a clone of it stay `same_trie` | ||
| /// until one is mutated: any insert or removal replaces the root node with a | ||
| /// fresh allocation. A `true` result therefore proves the trie's node | ||
| /// structure has not changed relative to `other`. Because `other` (typically | ||
| /// a cheap COW clone kept as a snapshot) holds the old root alive, its | ||
| /// address cannot be reused while the snapshot exists, so this is free of the | ||
| /// ABA pointer-reuse hazard. Root VALUES (the empty-key entry) are not | ||
| /// compared; callers that key a cache on subtree contents do not touch it. |
There was a problem hiding this comment.
This seems like a verbose and at the same time unspecific explanation.
| /// ABA pointer-reuse hazard. Root VALUES (the empty-key entry) are not | ||
| /// compared; callers that key a cache on subtree contents do not touch it. | ||
| #[inline] | ||
| pub fn same_trie(&self, other: &Self) -> bool { |
There was a problem hiding this comment.
@luketpeterson good public interface addition? To me, "same trie" could also be logical, so I'd change this to "ptr eq".
There was a problem hiding this comment.
Should also use node_id?
same_trie compared only the root node, but PathMap stores root values in a separate root_val field and set_val_at on an empty key returns through set_root_val without touching root. So it answered true for maps whose contents differ. Returning false when either map has a root value keeps a true result sound. The name change follows: the predicate is root pointer identity, and it is false for separately-built identical tries, so 'same trie' over-promised in both directions. Mirrors ZipperConcrete::shared_node_id, which returns None at a focus with a value for the same reason.
257c7da to
95d8b7f
Compare
|
pushed a fix. #4 was the important one, it's a real bug. renamed the bug #4 points at: it compared only the root node, but root values live in on the ring.rs one: the |
Summary
Three additive test/API commits, no internals changed:
PathMap::same_trie— an O(1) copy-on-write root-identity stalenesscheck (compares the root node pointer, no traversal).
trailing TODO in
ring.rsdescribed: seeded pseudorandom HashSet andnested-HashMap lattices checked against plain set oracles across
pjoin/pmeet/psubtract/join_into, asserting both results and theidentity/element status masks. Also covers the empty-subset-collapse case
and the HashMap
psubtractcase the inline notes flagged as untested. Onlythe now-resolved TODO notes are removed; the still-open ones (
VecSetLattice,LatticeCounter/LatticeBitfieldtraits) are left in place.paths_serialization.rs: round-trips deterministic paths of 7 / 2049 /4097 / 24000 bytes, so the input spans the internal 4096-byte compression
chunk, checked in both directions.
Test plan
cargo test --release --lib(664/0, up from the 660/0/1 baseline)cargo test --release --lib same_trie/seeded/paths_serializationindividually