Skip to content

Commit 18e2080

Browse files
committed
Updating ZipperMoving::descend_until to accept generic write sink as opposed to Option<&mut Vec<u8>> and fixing a couple other bugs & todos along the way
1 parent 193b48e commit 18e2080

15 files changed

Lines changed: 79 additions & 103 deletions

benches/oeis.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
use std::io::Read;
22
use std::usize;
33
use pathmap::PathMap;
4-
use pathmap::zipper::{Zipper, ZipperValues, ZipperMoving, ZipperWriting, ZipperCreation};
4+
use pathmap::zipper::{Zipper, ZipperValues, ZipperMoving, ZipperPath, ZipperWriting, ZipperCreation};
55
use num::BigInt;
66
use divan::{Divan, Bencher, black_box};
77

88
const MAX_OFFSET: u8 = 10;
99

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

1313
let p = loc.path().to_vec();
1414
while let Some(b) = it.next() {
1515
if b == 0 { continue }
1616
assert!(loc.descend_to(&[b]));
1717
loc.join_k_path_into(b as usize, true);
18-
assert!(loc.ascend(1));
18+
assert_eq!(loc.ascend(1), 1);
1919
}
2020
loc.reset();
2121
loc.descend_to(&p[..]);

pathmap-derive/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,9 +300,9 @@ pub fn derive_poly_zipper(input: TokenStream) -> TokenStream {
300300
}
301301
}
302302

303-
fn descend_until(&mut self, mut dst_path: Option<&mut Vec<u8>>) -> bool {
303+
fn descend_until<W: std::io::Write>(&mut self, desc_bytes: W) -> bool {
304304
match self {
305-
#(#variant_arms => inner.descend_until(dst_path),)*
305+
#(#variant_arms => inner.descend_until(desc_bytes),)*
306306
}
307307
}
308308

src/arena_compact.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1879,9 +1879,7 @@ where Storage: AsRef<[u8]>
18791879
self.descend_indexed_byte(0)
18801880
}
18811881

1882-
/// Descends the zipper's focus until a branch or a value is encountered. Returns `true` if the focus
1883-
/// moved otherwise returns `false`
1884-
fn descend_until(&mut self, dst: Option<&mut Vec<u8>>) -> bool {
1882+
fn descend_until<W: std::io::Write>(&mut self, mut desc_bytes: W) -> bool {
18851883
self.trace_pos();
18861884
let mut descended = false;
18871885
let orig_len = self.path.len();
@@ -1925,9 +1923,7 @@ where Storage: AsRef<[u8]>
19251923
}
19261924
}
19271925
}
1928-
if let Some(dst) = dst {
1929-
dst.extend_from_slice(&self.path[orig_len..]);
1930-
}
1926+
let _ = desc_bytes.write_all(&self.path[orig_len..]);
19311927
descended
19321928
}
19331929

src/empty_zipper.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl ZipperMoving for EmptyZipper {
4545
}
4646
fn descend_indexed_byte(&mut self, _idx: usize) -> Option<u8> { None }
4747
fn descend_first_byte(&mut self) -> Option<u8> { None }
48-
fn descend_until(&mut self, _dst_path: Option<&mut Vec<u8>>) -> bool { false }
48+
fn descend_until<W: std::io::Write>(&mut self, _desc_bytes: W) -> bool { false }
4949
fn ascend(&mut self, steps: usize) -> usize {
5050
let old_path_len = self.path.len() - self.path_start_idx;
5151
if steps > old_path_len {

src/experimental.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,8 @@ impl ZipperMoving for FullZipper {
5555
self.path.push(0);
5656
Some(0)
5757
}
58-
fn descend_until(&mut self, dst: Option<&mut Vec<u8>>) -> bool {
59-
self.path.push(0); // not sure?
60-
if let Some(dst) = dst { dst.push(0) }
61-
true
58+
fn descend_until<W: std::io::Write>(&mut self, _desc_bytes: W) -> bool {
59+
false
6260
}
6361
fn ascend(&mut self, steps: usize) -> usize {
6462
if steps > self.path.len() {

src/morphisms.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ fn cata_side_effect_body<'a, Z, V: 'a, W, Err, AlgF, const JUMPING: bool>(mut z:
415415
//Descend to the next forking point, or leaf
416416
let mut is_leaf = false;
417417
while z.child_count() < 2 {
418-
if !z.descend_until(None) {
418+
if !z.descend_until(std::io::sink()) {
419419
is_leaf = true;
420420
break;
421421
}
@@ -735,7 +735,7 @@ fn into_cata_cached_body<'a, Z, V: 'a, W, E, AlgF, Cache, const JUMPING: bool>(
735735
// Descend until leaf or branch
736736
let mut is_leaf = false;
737737
'descend: while zipper.child_count() < 2 {
738-
if !zipper.descend_until(None) {
738+
if !zipper.descend_until(std::io::sink()) {
739739
is_leaf = true;
740740
break 'descend;
741741
}

src/overlay_zipper.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,10 @@ impl<AV, BV, OutV, AZipper, BZipper, Mapping> ZipperMoving
212212
Some(byte)
213213
}
214214

215-
fn descend_until(&mut self, _dst: Option<&mut Vec<u8>>) -> bool {
216-
// TODO: track dst
215+
fn descend_until<W: std::io::Write>(&mut self, mut desc_bytes: W) -> bool {
217216
let start_depth = self.a.path().len();
218-
let desc_a = self.a.descend_until(None);
219-
let desc_b = self.b.descend_until(None);
217+
let desc_a = self.a.descend_until(std::io::sink());
218+
let desc_b = self.b.descend_until(std::io::sink());
220219
let path_a = &self.a.path()[start_depth..];
221220
let path_b = &self.b.path()[start_depth..];
222221
if !desc_a && !desc_b {
@@ -255,7 +254,14 @@ impl<AV, BV, OutV, AZipper, BZipper, Mapping> ZipperMoving
255254
let ascended = self.b.ascend(to_ascend);
256255
debug_assert_eq!(ascended, to_ascend);
257256
}
258-
overlap > 0
257+
debug_assert_eq!(self.a.path(), self.b.path());
258+
debug_assert_eq!(start_depth + overlap, self.a.path().len());
259+
if overlap > 0 {
260+
let _ = desc_bytes.write_all(&self.a.path()[start_depth..]);
261+
true
262+
} else {
263+
false
264+
}
259265
}
260266

261267
fn ascend(&mut self, steps: usize) -> usize {

src/path_tracker.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,10 @@ impl<Z: ZipperMoving> ZipperMoving for PathTracker<Z> {
132132
self.path.push(byte);
133133
Some(byte)
134134
}
135-
fn descend_until(&mut self, dst: Option<&mut Vec<u8>>) -> bool {
135+
fn descend_until<W: std::io::Write>(&mut self, mut desc_bytes: W) -> bool {
136136
let orig_len = self.path.len();
137-
let descended = self.zipper.descend_until(Some(&mut self.path));
138-
if let Some(dst) = dst {
139-
dst.extend_from_slice(&self.path[orig_len..]);
140-
}
137+
let descended = self.zipper.descend_until(&mut self.path);
138+
let _ = desc_bytes.write_all(&self.path[orig_len..]);
141139
descended
142140
}
143141
// TODO: using default impl. re-using zipper's own `to_next_step` implementation

src/prefix_zipper.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ impl<'prefix, Z> ZipperMoving for PrefixZipper<'prefix, Z>
369369
self.descend_indexed_byte(0)
370370
}
371371

372-
fn descend_until(&mut self, dst: Option<&mut Vec<u8>>) -> bool {
372+
fn descend_until<W: std::io::Write>(&mut self, desc_bytes: W) -> bool {
373373
if self.position.is_invalid() {
374374
return false;
375375
}
@@ -378,7 +378,7 @@ impl<'prefix, Z> ZipperMoving for PrefixZipper<'prefix, Z>
378378
self.position = PrefixPos::Source;
379379
}
380380
let len_before = self.source.path().len();
381-
if !self.source.descend_until(dst) {
381+
if !self.source.descend_until(desc_bytes) {
382382
return false;
383383
}
384384
let path = self.source.path();

src/product_zipper.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,8 +239,8 @@ impl<'trie, V: Clone + Send + Sync + Unpin + 'trie, A: Allocator + 'trie> Zipper
239239
self.ensure_descend_next_factor();
240240
result
241241
}
242-
fn descend_until(&mut self, dst: Option<&mut Vec<u8>>) -> bool {
243-
let result = self.z.descend_until(dst);
242+
fn descend_until<W: std::io::Write>(&mut self, desc_bytes: W) -> bool {
243+
let result = self.z.descend_until(desc_bytes);
244244
self.ensure_descend_next_factor();
245245
result
246246
}
@@ -729,19 +729,19 @@ impl<'trie, PrimaryZ, SecondaryZ, V> ZipperMoving for ProductZipperG<'trie, Prim
729729
fn descend_first_byte(&mut self) -> Option<u8> {
730730
self.descend_indexed_byte(0)
731731
}
732-
fn descend_until(&mut self, dst: Option<&mut Vec<u8>>) -> bool {
732+
fn descend_until<W: std::io::Write>(&mut self, desc_bytes: W) -> bool {
733733
self.enter_factors();
734734
let rv = if let Some(idx) = self.factor_idx(false) {
735735
let zipper = &mut self.secondary[idx];
736736
let before = zipper.path().len();
737-
let rv = zipper.descend_until(dst);
737+
let rv = zipper.descend_until(desc_bytes);
738738
let path = zipper.path();
739739
if path.len() > before {
740740
self.primary.descend_to(&path[before..]);
741741
}
742742
rv
743743
} else {
744-
self.primary.descend_until(dst)
744+
self.primary.descend_until(desc_bytes)
745745
};
746746
self.enter_factors();
747747
rv
@@ -1385,6 +1385,10 @@ mod tests {
13851385
// together, so the resulting virtual product trie is just one long path with repetitions,
13861386
// and then validate that ascend, ascend_until, ascend_until_branch, etc. all do the right
13871387
// thing traversing across multiple factors, not stopping spuriously at the factor stitch points.
1388+
//
1389+
// UPDATE, Also test `descend_until` in this case, because the correct behavior should be seamlessly
1390+
// descend flowing across multiple factor zippers in one call, and some of the impls don't appear to
1391+
// do that.
13881392

13891393
}
13901394
// --- END OF MACRO GENERATED MOD ---

0 commit comments

Comments
 (0)