diff --git a/crates/xline/src/storage/index.rs b/crates/xline/src/storage/index.rs index 6f223163e..42d478d15 100644 --- a/crates/xline/src/storage/index.rs +++ b/crates/xline/src/storage/index.rs @@ -144,19 +144,16 @@ impl Index { .map_read(|revs| Self::filter_revision(revs.as_ref(), revision)) }) .unwrap_or_default(), - KeyRange::Range(r) - if r.low == BytesAffine::Unbounded && r.high == BytesAffine::Unbounded => - { - self.inner - .iter() - .flat_map(|entry| { - entry - .value() - .map_read(|revs| Self::filter_revision(revs.as_ref(), revision)) - }) - .sorted() - .collect() - } + KeyRange::Range(_) if keyrange.is_all_keys() => self + .inner + .iter() + .flat_map(|entry| { + entry + .value() + .map_read(|revs| Self::filter_revision(revs.as_ref(), revision)) + }) + .sorted() + .collect(), KeyRange::Range(_) => self .inner .range(keyrange) @@ -269,14 +266,11 @@ impl IndexOperate for Index { .and_then(fmap_value(|revs| Index::get_revision(revs, revision))) .map(|rev| vec![rev]) .unwrap_or_default(), - KeyRange::Range(r) - if r.low == BytesAffine::Unbounded && r.high == BytesAffine::Unbounded => - { - self.inner - .iter() - .filter_map(fmap_value(|revs| Index::get_revision(revs, revision))) - .collect() - } + KeyRange::Range(_) if keyrange.is_all_keys() => self + .inner + .iter() + .filter_map(fmap_value(|revs| Index::get_revision(revs, revision))) + .collect(), KeyRange::Range(_) => self .inner .range(keyrange) @@ -355,24 +349,17 @@ impl IndexOperate for Index { let keys = if pairs.is_empty() { vec![] } else { vec![key] }; (pairs, keys) } - KeyRange::Range(r) - if r.low == BytesAffine::Unbounded && r.high == BytesAffine::Unbounded => - { - self.inner - .iter() - .zip(0..) - .filter_map(|(entry, i)| { - entry.value().map_write(|mut revs| { - Self::gen_del_revision( - &mut revs, - revision, - sub_revision.overflow_add(i), - ) + KeyRange::Range(_) if keyrange.is_all_keys() => self + .inner + .iter() + .zip(0..) + .filter_map(|(entry, i)| { + entry.value().map_write(|mut revs| { + Self::gen_del_revision(&mut revs, revision, sub_revision.overflow_add(i)) .map(|pair| (pair, entry.key().clone())) - }) }) - .unzip() - } + }) + .unzip(), KeyRange::Range(_) => self .inner .range(keyrange) @@ -524,14 +511,11 @@ impl IndexOperate for IndexState<'_> { .map(|rev| vec![rev]) .unwrap_or_default() } - KeyRange::Range(r) - if r.low == BytesAffine::Unbounded && r.high == BytesAffine::Unbounded => - { - self.all_key_revisions() - .into_iter() - .filter_map(|(_, revs)| Index::get_revision(revs.as_ref(), revision)) - .collect() - } + KeyRange::Range(_) if keyrange.is_all_keys() => self + .all_key_revisions() + .into_iter() + .filter_map(|(_, revs)| Index::get_revision(revs.as_ref(), revision)) + .collect(), KeyRange::Range(_) => self .range_key_revisions(keyrange) .into_iter() @@ -618,11 +602,7 @@ impl IndexOperate for IndexState<'_> { .delete_one(&key, revision, sub_revision) .into_iter() .unzip(), - KeyRange::Range(r) - if r.low == BytesAffine::Unbounded && r.high == BytesAffine::Unbounded => - { - self.delete_all(revision, sub_revision) - } + KeyRange::Range(_) if keyrange.is_all_keys() => self.delete_all(revision, sub_revision), KeyRange::Range(_) => self.delete_range(keyrange, revision, sub_revision), }; diff --git a/crates/xlineapi/src/keyrange.rs b/crates/xlineapi/src/keyrange.rs index 87c6de060..f138a1c58 100644 --- a/crates/xlineapi/src/keyrange.rs +++ b/crates/xlineapi/src/keyrange.rs @@ -13,7 +13,7 @@ pub const UNBOUNDED: &[u8] = &[0_u8]; /// Range end to get one key pub const ONE_KEY: &[u8] = &[]; -trait Add1 { +pub trait Add1 { fn add1(self) -> Self; } @@ -25,7 +25,7 @@ impl Add1 for Vec { /// ```rust /// use xlineapi::keyrange::Add1; /// assert_eq!(vec![5, 6, 7].add1(), vec![5, 6, 8]); - /// assert_eq!(vec![5, 6, 255].add1(), vec![5, 6]); + /// assert_eq!(vec![5, 6, 255].add1(), vec![5, 7]); /// assert_eq!(vec![255, 255].add1(), vec![0]); /// ``` fn add1(mut self) -> Self { @@ -200,6 +200,18 @@ impl KeyRange { key.as_ref().to_vec().add1() } + /// if this range contains all keys + #[must_use] + #[inline] + pub fn is_all_keys(&self) -> bool { + match self { + Self::OneKey(_) => false, + Self::Range(r) => { + r.low == BytesAffine::Bytes(UNBOUNDED.into()) && r.high == BytesAffine::Unbounded + } + } + } + /// unpack `KeyRange` to `BytesAffine` tuple #[must_use] #[inline]