From 86ab3026de0a88df5c4e881fb74f1872a0e872c7 Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Thu, 20 Feb 2025 18:55:37 +0300 Subject: [PATCH 1/2] Added an ability to get the nth ancestor --- src/lib.rs | 80 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d1697ff..1f7ee5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -541,23 +541,7 @@ impl OrdPath { /// Returns the `OrdPath` without its final element, if there is one. pub fn parent(&self) -> Option<&OrdPath> { - let src = self.bytes(); - if src.len() == 0 { - return None; - } - let mut bits_prev = 0usize; - let mut reader = Reader::new(src, self.encoding()); - unsafe { - // SAFETY: Validation of the data happens on creation even for a byte slice. - if let Some((_, stage)) = reader.read().unwrap_unchecked() { - let mut bits = stage.bits() as usize; - while let Some((_, stage)) = reader.read().unwrap_unchecked() { - bits_prev = bits; - bits += stage.bits() as usize; - } - } - } - Some(Self::new(self.path(), bits_prev)) + self.ancestors().next() } /// Returns `true` if `self` is an ancestor of `other`. @@ -708,6 +692,32 @@ impl Bytes { }, } } + + #[inline] + fn ancestor(&self, enc: &E, nth: usize) -> Option<&Self> { + const FORWARD_BUF_LEN: usize = size_of::(); + let mut bytes = self; + for _ in 0..=nth.div_ceil(FORWARD_BUF_LEN) { + if bytes.len_in_bits() == 0 { + return None; + } + let mut idx = 0; + let mut buf = [0u8; FORWARD_BUF_LEN]; + let mut bits = 0; + let mut reader = Reader::new(bytes, enc); + while let Some((_, stage)) = reader.read().unwrap() { + bits += stage.bits() as usize; + buf[idx % buf.len()] = stage.bits(); + idx = idx.wrapping_add(1); + } + for _ in 0..=buf.len().min(nth % FORWARD_BUF_LEN) { + idx = idx.wrapping_sub(1); + bits -= buf[idx % buf.len()] as usize; + } + bytes = unsafe { Bytes::from_raw_parts(bytes.data.as_ptr(), bits) }; + } + Some(bytes) + } } impl Read for &Bytes { @@ -867,7 +877,15 @@ impl<'a, E: Encoding, const N: usize> Iterator for Ancestors<'a, E, N> { type Item = &'a OrdPath; fn next(&mut self) -> Option { - self.path = self.path.and_then(|p| p.parent()); + self.nth(0) + } + + fn nth(&mut self, n: usize) -> Option { + self.path = self.path.and_then(|p| { + p.bytes() + .ancestor(p.encoding(), n) + .map(|b| OrdPath::new(p.path(), b.len_in_bits())) + }); self.path } } @@ -1046,21 +1064,19 @@ mod tests { #[test] fn path_parent() { - fn parent(p: Option) -> Option { - p.and_then(|p| p.parent().map(|p| p.to_owned())) - } - - fn assert(s: &[i64]) { - let mut p = Some(::from_ordinals(s, DefaultEncoding)); - for i in (0..s.len()).rev() { - p = parent(p); - assert_eq!(p, Some(OrdPathBuf::from_ordinals(&s[..i], DefaultEncoding))); - } - assert_eq!(parent(p), None); + let ords = (i8::MIN..i8::MAX).map(|x| x as i64).collect::>(); + for n in 1..ords.len() { + let ords = &ords[..n]; + let path = ::from_ordinals(ords, DefaultEncoding); + dbg!(&ords); + dbg!(&path); + assert_eq!( + ords[..(ords.len() - 1)], + path.parent() + .map(|p| p.ordinals().collect::>()) + .unwrap_or_default() + ); } - - assert(&[1, 2]); - assert(&[344, 345]); } #[cfg(feature = "serde")] From 1a120c8590acd6cd695a2198d5fec9d810b3127a Mon Sep 17 00:00:00 2001 From: Yoh Deadfall Date: Thu, 20 Feb 2025 22:08:45 +0300 Subject: [PATCH 2/2] Parenthesized expressions --- src/reader.rs | 2 +- src/writer.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reader.rs b/src/reader.rs index 97d0417..f7086a4 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -45,7 +45,7 @@ impl Reader { if consumed > 0 { let acc_next = u64::from_be_bytes(buf); let acc = if self.len > 0 { - acc_next >> self.len | self.acc + (acc_next >> self.len) | self.acc } else { acc_next }; diff --git a/src/writer.rs b/src/writer.rs index d5616dd..0d27cae 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -32,8 +32,8 @@ impl Writer { let value = (value - stage.ordinal_min()) as u64; let buf = match stage.bits() < 64 { - true => (prefix << (stage.ordinal_bits()) | value) << (64 - stage.bits()), - false => prefix << (64 - stage.prefix_bits()) | (value >> (stage.bits() - 64)), + true => ((prefix << stage.ordinal_bits()) | value) << (64 - stage.bits()), + false => (prefix << (64 - stage.prefix_bits())) | (value >> (stage.bits() - 64)), }; let len = self.len & 127;