Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2cdf46f
separate zipper path method
imlvts Sep 25, 2025
dd8d80e
update all the APIs & tests to allow ZipperMoving to track where it goes
imlvts Sep 25, 2025
98e06fb
added wrapper to support tracking paths on blind zippers
imlvts Sep 25, 2025
7b5e75c
Reverting to main-line gxhash, now that all the changes we need have …
luketpeterson Oct 8, 2025
519341f
Merging main in, which involved updating PolyZipper and EmptyZipper t…
luketpeterson Oct 8, 2025
6b095df
Fixing build for `fuzzer` feature
luketpeterson Oct 8, 2025
d4411e9
Merge branch 'master' into blind-zippers
luketpeterson Oct 9, 2025
65cd1d4
Merge branch 'master' into blind-zippers
luketpeterson Oct 9, 2025
d0feb3b
refactor ascend functions
imlvts Oct 10, 2025
69fa706
renamed TrackPath to PathTracker
imlvts Oct 10, 2025
6336a68
Updating ZipperMoving API as per discussion in github PR for blind_zi…
luketpeterson Oct 10, 2025
302690e
implemented new APIs for arena_compact
imlvts Oct 10, 2025
0782de1
Implementing blind zipper changes for viz, counters, and arena_compact
luketpeterson Oct 10, 2025
031b30b
Oops. Important stuff was happening inside a debug_assert! breaking r…
luketpeterson Oct 10, 2025
11ac984
Fixing issue with prefix_zipper that was causing failures in ACT tests
luketpeterson Oct 10, 2025
193b48e
Merge branch 'master' into blind-zippers
luketpeterson Oct 11, 2025
18e2080
Updating `ZipperMoving::descend_until` to accept generic write sink a…
luketpeterson Oct 11, 2025
0dc9cb4
Merge branch 'master' into blind-zippers
luketpeterson Oct 15, 2025
703808f
Adding `focus_byte` method to `ZipperMoving` trait, to permit default…
luketpeterson Oct 15, 2025
52a6798
Re-adding default impls for ZipperMoving to_sibling methods
luketpeterson Oct 15, 2025
eb80139
Updating book to clarify that the path is no longer on `ZipperMoving`…
luketpeterson Oct 15, 2025
b982c8a
Adding `PathObserver` trait, and taking it as an argument for `descen…
luketpeterson Oct 15, 2025
a87f5a0
Merge branch 'master' into blind-zippers
luketpeterson Oct 16, 2025
676463b
Merge branch 'master' into blind-zippers
luketpeterson Oct 29, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions benches/oeis.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
use std::io::Read;
use std::usize;
use pathmap::PathMap;
use pathmap::zipper::{Zipper, ZipperValues, ZipperMoving, ZipperWriting, ZipperCreation};
use pathmap::zipper::{Zipper, ZipperValues, ZipperMoving, ZipperPath, ZipperWriting, ZipperCreation};
use num::BigInt;
use divan::{Divan, Bencher, black_box};

const MAX_OFFSET: u8 = 10;

fn drop_symbol_head_byte<Z: ZipperWriting<usize> + Zipper + ZipperMoving>(loc: &mut Z) {
fn drop_symbol_head_byte<Z: ZipperWriting<usize> + Zipper + ZipperMoving + ZipperPath>(loc: &mut Z) {
let mut it = loc.child_mask().iter();

let p = loc.path().to_vec();
while let Some(b) = it.next() {
if b == 0 { continue }
loc.descend_to_existing_byte(b);
loc.join_k_path_into(b as usize, true);
assert!(loc.ascend(1));
assert_eq!(loc.ascend(1), 1);
}
loc.reset();
loc.descend_to(&p[..]);
Expand Down
1 change: 1 addition & 0 deletions pathmap-book/src/1.02.00_zippers.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Zipper capabilities are defined across a number of traits. There are many diffe
| [`ZipperValues`](./1.02.02_zipper_values.md#zippervalues) | Access values |
| [`ZipperReadOnlyValues`](./1.02.02_zipper_values.md#zipperreadonlyvalues) | Access values with extended lifetime |
| [`ZipperReadOnlyConditionalValues`](./1.02.02_zipper_values.md#zipperreadonlyconditionalvalues) | Access values with `witness` pattern |
| [`ZipperPath`](./1.02.03_zipper_paths.md#zipper_relative_path) | Get basic path information |
| [`ZipperAbsolutePath`](./1.02.03_zipper_paths.md#zipperabsolutepath) | Get more complete path information |
| [`ZipperPathBuffer`](./1.02.03_zipper_paths.md#zipperpathbuffer) | Control zipper's internal buffer allocation |
| [`ZipperMoving`](./1.02.04_zipper_moving.md) | Moves the zipper's focus within the trie |
Expand Down
6 changes: 3 additions & 3 deletions pathmap-book/src/1.02.03_zipper_paths.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Paths and Absolute Paths
Some zippers maintain can expose their focus position within the trie as a `path`. The following traits expose access to the path buffer in some way.
Some zippers maintain and can expose their focus position within the trie as a contiguous `path` of type `&[u8]`. The following traits expose access to the path buffer in some way.

## Zipper Relative Path
The [`path`] method in [`ZipperMoving`] returns the current path from the zipper's root to its focus as a byte slice. This represents the sequence of bytes traversed to reach the current focus position.
The [`path`] method in the [`ZipperPath`] trait returns the current path from the zipper's root to its focus, as a byte slice. This represents the sequence of bytes traversed to reach the current focus position.

Note that this path is relative to the zipper's root, which may not be the same as the absolute path from the original data structure's root if the zipper was created with a prefix or from a subtrie.
Note that this path is relative to the zipper's root, which may not be the same as the absolute path from the original data structure's root if the zipper was created with a prefix or from within a subtrie.

## ZipperAbsolutePath
The [`ZipperAbsolutePath`] trait provides methods to access a more complete path slice, including the [`origin_path`], and may extend above the zipper's root.
Expand Down
102 changes: 97 additions & 5 deletions pathmap-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,24 @@ pub fn derive_poly_zipper(input: TokenStream) -> TokenStream {
// }
// };

// Generate ZipperPath trait implementation
let zipper_path_impl = {
let variant_arms = &variant_arms;
quote! {
impl #impl_generics pathmap::zipper::ZipperPath for #enum_name #ty_generics
where
#(#inner_types: pathmap::zipper::ZipperPath,)*
#where_clause
{
fn path(&self) -> &[u8] {
match self {
#(#variant_arms => inner.path(),)*
}
}
}
}
};

// Generate ZipperMoving trait implementation
let zipper_moving_impl = {
let variant_arms = &variant_arms;
Expand All @@ -222,9 +240,22 @@ pub fn derive_poly_zipper(input: TokenStream) -> TokenStream {
#(#inner_types: pathmap::zipper::ZipperMoving,)*
#where_clause
{
fn path(&self) -> &[u8] {
fn at_root(&self) -> bool {
match self {
#(#variant_arms => inner.path(),)*
#(#variant_arms => inner.at_root(),)*
}
}

#[inline]
fn focus_byte(&self) -> Option<u8> {
match self {
#(#variant_arms => inner.focus_byte(),)*
}
}

fn reset(&mut self) {
match self {
#(#variant_arms => inner.reset(),)*
}
}

Expand All @@ -240,6 +271,18 @@ pub fn derive_poly_zipper(input: TokenStream) -> TokenStream {
}
}

fn descend_to_existing<K: AsRef<[u8]>>(&mut self, k: K) -> usize {
match self {
#(#variant_arms => inner.descend_to_existing(k),)*
}
}

fn descend_to_val<K: AsRef<[u8]>>(&mut self, k: K) -> usize {
match self {
#(#variant_arms => inner.descend_to_val(k),)*
}
}

fn descend_to_check<K: AsRef<[u8]>>(&mut self, k: K) -> bool {
match self {
#(#variant_arms => inner.descend_to_check(k),)*
Expand All @@ -260,23 +303,71 @@ pub fn derive_poly_zipper(input: TokenStream) -> TokenStream {
}
}

fn ascend(&mut self, steps: usize) -> bool {
fn descend_indexed_byte(&mut self, idx: usize) -> Option<u8> {
match self {
#(#variant_arms => inner.descend_indexed_byte(idx),)*
}
}

fn descend_first_byte(&mut self) -> Option<u8> {
match self {
#(#variant_arms => inner.descend_first_byte(),)*
}
}

fn descend_last_byte(&mut self) -> Option<u8> {
match self {
#(#variant_arms => inner.descend_last_byte(),)*
}
}

fn descend_until<Obs: pathmap::zipper::PathObserver>(&mut self, obs: &mut Obs) -> bool {
match self {
#(#variant_arms => inner.descend_until(obs),)*
}
}

fn ascend(&mut self, steps: usize) -> usize {
match self {
#(#variant_arms => inner.ascend(steps),)*
}
}

fn ascend_until(&mut self) -> bool {
fn ascend_byte(&mut self) -> bool {
match self {
#(#variant_arms => inner.ascend_byte(),)*
}
}

fn ascend_until(&mut self) -> usize {
match self {
#(#variant_arms => inner.ascend_until(),)*
}
}

fn ascend_until_branch(&mut self) -> bool {
fn ascend_until_branch(&mut self) -> usize {
match self {
#(#variant_arms => inner.ascend_until_branch(),)*
}
}

fn to_next_sibling_byte(&mut self) -> Option<u8> {
match self {
#(#variant_arms => inner.to_next_sibling_byte(),)*
}
}

fn to_prev_sibling_byte(&mut self) -> Option<u8> {
match self {
#(#variant_arms => inner.to_prev_sibling_byte(),)*
}
}

fn to_next_step(&mut self) -> bool {
match self {
#(#variant_arms => inner.to_next_step(),)*
}
}
}
}
};
Expand Down Expand Up @@ -447,6 +538,7 @@ pub fn derive_poly_zipper(input: TokenStream) -> TokenStream {
#zipper_read_only_values_impl
#zipper_read_only_conditional_values_impl
// #zipper_forking_impl
#zipper_path_impl
#zipper_moving_impl
#zipper_concrete_impl
#zipper_absolute_path_impl
Expand Down
Loading