From: Chris Mikkelson Date: Fri, 3 May 2024 05:54:15 +0000 (-0500) Subject: Seekable: relax Ord requirement on keys X-Git-Url: https://git.mikk.net/?a=commitdiff_plain;h=a86cb9330289f5fa1d957cce8b9a54c2de6d46fb;p=mtbl-rs Seekable: relax Ord requirement on keys This allows implementations to return Result<> types to propagate errors. Those errors will need to be handled prior to merging or coalescing. --- diff --git a/src/seekable.rs b/src/seekable.rs index a5c9162..94aa316 100644 --- a/src/seekable.rs +++ b/src/seekable.rs @@ -8,7 +8,7 @@ use merge::Merger; pub use vec::SeekableVec; pub trait Seekable: Sized { - type Key: Ord; + type Key; type Value; fn next(&mut self) -> Option<(Self::Key, Self::Value)>; @@ -24,6 +24,7 @@ pub trait Seekable: Sized { fn merge(iter: L) -> Merger where L: Iterator, + Self::Key: Ord, { merge::merge(iter) } @@ -31,6 +32,7 @@ pub trait Seekable: Sized { fn coalesce(self, cf: F) -> Coalesce where F: FnMut(&Self::Key, Self::Value, Self::Value) -> Self::Value, + Self::Key: PartialEq, { coalesce::coalesce(self, cf) } diff --git a/src/seekable/coalesce.rs b/src/seekable/coalesce.rs index 527b9c1..55c006d 100644 --- a/src/seekable/coalesce.rs +++ b/src/seekable/coalesce.rs @@ -26,6 +26,7 @@ where impl IntoIterator for Coalesce where S: Seekable, + S::Key: PartialEq, F: FnMut(&S::Key, S::Value, S::Value) -> S::Value, { type Item = (S::Key, S::Value); @@ -38,6 +39,7 @@ where impl Seekable for Coalesce where S: Seekable, + S::Key: PartialEq, F: FnMut(&S::Key, S::Value, S::Value) -> S::Value, { type Key = S::Key; diff --git a/src/seekable/merge.rs b/src/seekable/merge.rs index fb9860a..adbcf14 100644 --- a/src/seekable/merge.rs +++ b/src/seekable/merge.rs @@ -6,18 +6,25 @@ use std::collections::BinaryHeap; pub struct Merger where S: Seekable, + S::Key: Ord, { active: BinaryHeap>, ended: Vec, } -struct MergerEnt { +struct MergerEnt +where + S::Key: Ord, +{ cur_item: RefCell<(S::Key, S::Value)>, rest: S, } -impl Eq for MergerEnt {} -impl PartialEq for MergerEnt { +impl Eq for MergerEnt where S::Key: Ord {} +impl PartialEq for MergerEnt +where + S::Key: Ord, +{ fn eq(&self, other: &Self) -> bool { let sent = self.cur_item.borrow(); let oent = other.cur_item.borrow(); @@ -30,13 +37,19 @@ impl PartialEq for MergerEnt { // for MergerEnt vs. S::Key. We do this instead of using // std::cmp::Reverse to avoid the additional packing/unpacking // boilerplate. -impl PartialOrd for MergerEnt { +impl PartialOrd for MergerEnt +where + S::Key: Ord, +{ fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) + Some(self.cmp(other)) } } -impl Ord for MergerEnt { +impl Ord for MergerEnt +where + S::Key: Ord, +{ fn cmp(&self, other: &Self) -> Ordering { let sent = self.cur_item.borrow(); let oent = other.cur_item.borrow(); @@ -44,7 +57,10 @@ impl Ord for MergerEnt { } } -impl MergerEnt { +impl MergerEnt +where + S::Key: Ord, +{ fn new(mut source: S) -> Option> { Some(MergerEnt { cur_item: RefCell::new(source.next()?), @@ -61,6 +77,7 @@ pub fn merge(sources: L) -> Merger where L: Iterator, S: Seekable, + S::Key: Ord, { Merger { active: BinaryHeap::from( @@ -73,7 +90,10 @@ where } } -impl IntoIterator for Merger { +impl IntoIterator for Merger +where + S::Key: Ord, +{ type Item = (S::Key, S::Value); type IntoIter = Iter; fn into_iter(self) -> Self::IntoIter { @@ -81,7 +101,10 @@ impl IntoIterator for Merger { } } -fn heap_reset(m: &mut Merger, key: &S::Key) { +fn heap_reset(m: &mut Merger, key: &S::Key) +where + S::Key: Ord, +{ let mut active = Vec::>::new(); let mut ended = Vec::::new(); while let Some(e) = m.active.pop() { @@ -104,7 +127,10 @@ fn heap_reset(m: &mut Merger, key: &S::Key) { } // forward seek within the heap -fn heap_seek(m: &mut Merger, key: &S::Key) -> Option<()> { +fn heap_seek(m: &mut Merger, key: &S::Key) -> Option<()> +where + S::Key: Ord, +{ loop { let mut head = m.active.peek_mut()?; if head.cur_item.borrow().0 >= *key { @@ -122,7 +148,10 @@ fn heap_seek(m: &mut Merger, key: &S::Key) -> Option<()> { None } -impl Seekable for Merger { +impl Seekable for Merger +where + S::Key: Ord, +{ type Key = S::Key; type Value = S::Value;