diff --git a/Cargo.lock b/Cargo.lock
index 221be3944b67ee3177da0a048f2b199318ba6021..a8e8112d3a50e773bdb65f1561e2d29cfbf49b21 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1952,6 +1952,7 @@ name = "kv_typed"
 version = "0.1.0"
 dependencies = [
  "async-std",
+ "byteorder",
  "cfg-if 0.1.10",
  "criterion",
  "flume",
diff --git a/rust-libs/tools/kv_typed/Cargo.toml b/rust-libs/tools/kv_typed/Cargo.toml
index d1d549612dab8f0bcb8290d6397a219e5cff5974..fe242ec6fad58dc04d5743883113d7d2658429ec 100644
--- a/rust-libs/tools/kv_typed/Cargo.toml
+++ b/rust-libs/tools/kv_typed/Cargo.toml
@@ -12,6 +12,7 @@ edition = "2018"
 path = "src/lib.rs"
 
 [dependencies]
+byteorder = "1.3.4"
 cfg-if = "0.1.10"
 flume = "0.9.1"
 leveldb_minimal = { version = "0.1.0", optional = true }
diff --git a/rust-libs/tools/kv_typed/src/backend.rs b/rust-libs/tools/kv_typed/src/backend.rs
index 6e8688c93c09e3099d6ce2d2d07d9a02ea7ea444..5e91cc21d5e569bf2314c533f25e4bc56861b7b5 100644
--- a/rust-libs/tools/kv_typed/src/backend.rs
+++ b/rust-libs/tools/kv_typed/src/backend.rs
@@ -58,7 +58,22 @@ pub trait BackendCol: 'static + Clone + Debug + Send + Sync {
     fn contains_key<K: Key>(&self, k: &K) -> KvResult<bool>;
     fn count(&self) -> KvResult<usize>;
     fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter;
-    fn iter_rev<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter;
+    fn iter_ref_slice<D, K, V, F>(
+        &self,
+        range: RangeBytes,
+        f: F,
+    ) -> KvInnerIterRefSlice<Self, D, K, V, F>
+    where
+        K: KeyZc,
+        V: ValueSliceZc,
+        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+    {
+        KvInnerIterRefSlice {
+            backend_iter: self.iter::<K, V>(range),
+            f,
+            phantom: PhantomData,
+        }
+    }
     fn put<K: Key, V: Value>(&mut self, k: &K, value: &V) -> KvResult<()>;
     fn delete<K: Key>(&mut self, k: &K) -> KvResult<()>;
     fn new_batch() -> Self::Batch;
diff --git a/rust-libs/tools/kv_typed/src/backend/leveldb.rs b/rust-libs/tools/kv_typed/src/backend/leveldb.rs
index 7176a7fddffc71fcfac14165bcf8f2ae74201b9b..f710347418e55a1c36d9fe76439838c39830d0aa 100644
--- a/rust-libs/tools/kv_typed/src/backend/leveldb.rs
+++ b/rust-libs/tools/kv_typed/src/backend/leveldb.rs
@@ -206,12 +206,8 @@ impl BackendCol for LevelDbCol {
         Ok(())
     }
     #[inline(always)]
-    fn iter<K: Key, V: Value>(&self, _range: RangeBytes) -> Self::Iter {
-        LevelDbIter(self.0.iter(ReadOptions::new()))
-    }
-    #[inline(always)]
-    fn iter_rev<K: Key, V: Value>(&self, _range: RangeBytes) -> Self::Iter {
-        LevelDbIter(self.0.iter(ReadOptions::new()).reverse())
+    fn iter<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
+        LevelDbIter::new(self.0.iter(ReadOptions::new()), range)
     }
     #[inline(always)]
     fn save(&self) -> KvResult<()> {
@@ -219,11 +215,28 @@ impl BackendCol for LevelDbCol {
     }
 }
 
-pub struct LevelDbIter(LevelDbIterator);
+pub struct LevelDbIter {
+    inner: LevelDbIterator,
+    range_start: Bound<IVec>,
+    range_end: Bound<IVec>,
+    reversed: bool,
+}
+impl LevelDbIter {
+    fn new(inner: LevelDbIterator, range: RangeBytes) -> Self {
+        LevelDbIter {
+            inner,
+            range_start: range.0,
+            range_end: range.1,
+            reversed: false,
+        }
+    }
+}
 impl Debug for LevelDbIter {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("LevelDbIter")
-            .field("0", &"LevelDbIterator<'db>")
+            .field("inner", &"LevelDbIterator<'db>")
+            .field("range_start", &self.range_start)
+            .field("range_end", &self.range_end)
             .finish()
     }
 }
@@ -233,15 +246,60 @@ impl Iterator for LevelDbIter {
 
     #[inline(always)]
     fn next(&mut self) -> Option<Self::Item> {
-        self.0
-            .next()
-            .map(|(k, v)| Ok((LevelDbBytes(k), LevelDbBytes(v))))
+        loop {
+            match self
+                .inner
+                .next()
+                .map(|(k, v)| Ok((LevelDbBytes(k), LevelDbBytes(v))))
+            {
+                Some(Ok((key_bytes, value_bytes))) => {
+                    let start_bound_ok = match &self.range_start {
+                        Bound::Included(start_bytes) => key_bytes.as_ref() >= start_bytes.as_ref(),
+                        Bound::Excluded(start_bytes) => key_bytes.as_ref() > start_bytes.as_ref(),
+                        Bound::Unbounded => true,
+                    };
+                    let end_bound_ok = match &self.range_end {
+                        Bound::Included(end_bytes) => key_bytes.as_ref() <= end_bytes.as_ref(),
+                        Bound::Excluded(end_bytes) => key_bytes.as_ref() < end_bytes.as_ref(),
+                        Bound::Unbounded => true,
+                    };
+                    if start_bound_ok {
+                        if end_bound_ok {
+                            break Some(Ok((key_bytes, value_bytes)));
+                        } else if self.reversed {
+                            // The interval has not yet begun.
+                            continue;
+                        } else {
+                            // The range has been fully traversed, the iterator is finished.
+                            break None;
+                        }
+                    } else if end_bound_ok {
+                        if self.reversed {
+                            // The range has been fully traversed, the iterator is finished.
+                            break None;
+                        } else {
+                            // The interval has not yet begun.
+                            continue;
+                        }
+                    } else {
+                        // Empty range, the iterator is finished.
+                        break None;
+                    }
+                }
+                other => break other,
+            }
+        }
     }
 }
 impl ReversableIterator for LevelDbIter {
     #[inline(always)]
     fn reverse(self) -> Self {
-        Self(self.0.reverse())
+        LevelDbIter {
+            range_start: self.range_start,
+            range_end: self.range_end,
+            reversed: !self.reversed,
+            inner: self.inner.reverse(),
+        }
     }
 }
 impl BackendIter<LevelDbBytes, LevelDbBytes> for LevelDbIter {}
diff --git a/rust-libs/tools/kv_typed/src/backend/memory.rs b/rust-libs/tools/kv_typed/src/backend/memory.rs
index b3ec5589cae81679324b4bf4e341a59040f1d695..fd3709c5c59eab6c3b1f59155c34ca701d075525 100644
--- a/rust-libs/tools/kv_typed/src/backend/memory.rs
+++ b/rust-libs/tools/kv_typed/src/backend/memory.rs
@@ -337,10 +337,6 @@ impl BackendCol for MemCol {
         })
     }
     #[inline(always)]
-    fn iter_rev<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
-        self.iter::<K, V>(range).reverse()
-    }
-    #[inline(always)]
     fn save(&self) -> KvResult<()> {
         /*if let Some(ref file_path) = self.path {
             let bytes = Self::tree_to_bytes(&self.tree);
diff --git a/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs b/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
index 200973d752061dd568183fd666e62c57d35a45f5..d77bcedda42b506b4861a5587fec26312038a3ea 100644
--- a/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
+++ b/rust-libs/tools/kv_typed/src/backend/memory_singleton.rs
@@ -155,10 +155,6 @@ impl BackendCol for MemCol {
         MemIter(self.0.clone())
     }
     #[inline(always)]
-    fn iter_rev<K: Key, V: Value>(&self, _: RangeBytes) -> Self::Iter {
-        MemIter(self.0.clone())
-    }
-    #[inline(always)]
     fn save(&self) -> KvResult<()> {
         Ok(())
     }
diff --git a/rust-libs/tools/kv_typed/src/backend/sled.rs b/rust-libs/tools/kv_typed/src/backend/sled.rs
index d519fa0027192b23992bd233f6cf298fa1ec04f8..6efd6cb2144035c5896afa99120005d8c45ea14c 100644
--- a/rust-libs/tools/kv_typed/src/backend/sled.rs
+++ b/rust-libs/tools/kv_typed/src/backend/sled.rs
@@ -163,10 +163,6 @@ impl BackendCol for SledCol {
         }
     }
     #[inline(always)]
-    fn iter_rev<K: Key, V: Value>(&self, range: RangeBytes) -> Self::Iter {
-        self.iter::<K, V>(range).reverse()
-    }
-    #[inline(always)]
     fn save(&self) -> KvResult<()> {
         self.0.flush()?;
         Ok(())
diff --git a/rust-libs/tools/kv_typed/src/collection_inner.rs b/rust-libs/tools/kv_typed/src/collection_inner.rs
index a03d9883ef2e6bab986194de3fb6eb42360b088d..452cc3f7904d983d1df3c6db8fe1764f9a0d6184 100644
--- a/rust-libs/tools/kv_typed/src/collection_inner.rs
+++ b/rust-libs/tools/kv_typed/src/collection_inner.rs
@@ -16,7 +16,7 @@
 use crate::*;
 
 #[derive(Debug)]
-pub(crate) struct ColInner<BC: BackendCol, E: EventTrait> {
+pub struct ColInner<BC: BackendCol, E: EventTrait> {
     pub(crate) backend_col: BC,
     subscribers: ColSubscribers<E>,
 }
diff --git a/rust-libs/tools/kv_typed/src/collection_ro.rs b/rust-libs/tools/kv_typed/src/collection_ro.rs
index 485b204f6445616c67f7779a78a38ccd16caad41..1ab5360100f86ddbb25da8e20c57ba886c42f735 100644
--- a/rust-libs/tools/kv_typed/src/collection_ro.rs
+++ b/rust-libs/tools/kv_typed/src/collection_ro.rs
@@ -67,6 +67,8 @@ mockall::mock! {
     }
 }
 
+type ColRoReader<'r, BC, E> = parking_lot::RwLockReadGuard<'r, ColInner<BC, E>>;
+
 #[derive(Debug)]
 pub struct ColRo<BC: BackendCol, E: EventTrait> {
     pub(crate) inner: Arc<parking_lot::RwLock<ColInner<BC, E>>>,
@@ -123,8 +125,8 @@ impl<BC: BackendCol, E: EventTrait> DbCollectionRo for ColRo<BC, E> {
     ) -> D {
         let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
         let r = self.inner.read();
-        let iter = r.backend_col.iter::<Self::K, Self::V>(range.clone());
-        f(KvIter::new(iter, range))
+        let iter = r.backend_col.iter::<Self::K, Self::V>(range);
+        f(KvIter::new(iter))
     }
     #[inline(always)]
     fn iter_rev<
@@ -147,8 +149,8 @@ impl<BC: BackendCol, E: EventTrait> DbCollectionRo for ColRo<BC, E> {
     ) -> D {
         let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
         let r = self.inner.read();
-        let iter = r.backend_col.iter::<Self::K, Self::V>(range.clone());
-        f(KvIter::new(iter, range).reverse())
+        let iter = r.backend_col.iter::<Self::K, Self::V>(range).reverse();
+        f(KvIter::new(iter))
     }
     #[inline(always)]
     fn subscribe(&self, subscriber_sender: Subscriber<Self::Event>) -> KvResult<()> {
@@ -193,3 +195,73 @@ impl<V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> DbCollectionRoGetRef
         r.backend_col.get_ref_slice::<E::K, V, D, F>(k, f)
     }
 }
+
+pub trait DbCollectionRoIterRefSlice<'r, BC: BackendCol, K: KeyZc, V: ValueSliceZc, READER>:
+    DbCollectionRo<K = K, V = V>
+{
+    fn iter_ref_slice<D, R, F>(&'r self, range: R, f: F) -> KvIterRefSlice<BC, D, K, V, F, READER>
+    where
+        K: KeyZc,
+        V: ValueSliceZc,
+        R: 'static + RangeBounds<K>,
+        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>;
+    fn iter_ref_slice_rev<D, R, F>(
+        &'r self,
+        range: R,
+        f: F,
+    ) -> KvIterRefSlice<BC, D, K, V, F, READER>
+    where
+        K: KeyZc,
+        V: ValueSliceZc,
+        R: 'static + RangeBounds<K>,
+        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>;
+}
+
+impl<'r, K: KeyZc, V: ValueSliceZc, BC: BackendCol, E: EventTrait<K = K, V = V>>
+    DbCollectionRoIterRefSlice<'r, BC, K, V, ColRoReader<'r, BC, E>> for ColRo<BC, E>
+{
+    fn iter_ref_slice<D, R, F>(
+        &'r self,
+        range: R,
+        f: F,
+    ) -> KvIterRefSlice<BC, D, K, V, F, ColRoReader<'r, BC, E>>
+    where
+        K: KeyZc,
+        V: ValueSliceZc,
+        R: 'static + RangeBounds<K>,
+        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+    {
+        let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
+        let reader = self.inner.read();
+        let inner_iter = reader.backend_col.iter_ref_slice::<D, K, V, F>(range, f);
+
+        KvIterRefSlice {
+            inner: inner_iter,
+            reader: OwnedOrRef::Owned(reader),
+        }
+    }
+
+    fn iter_ref_slice_rev<D, R, F>(
+        &'r self,
+        range: R,
+        f: F,
+    ) -> KvIterRefSlice<BC, D, K, V, F, ColRoReader<'r, BC, E>>
+    where
+        K: KeyZc,
+        V: ValueSliceZc,
+        R: 'static + RangeBounds<K>,
+        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+    {
+        let range: RangeBytes = crate::iter::convert_range::<Self::K, R>(range);
+        let reader = self.inner.read();
+        let inner_iter = reader
+            .backend_col
+            .iter_ref_slice::<D, K, V, F>(range, f)
+            .reverse();
+
+        KvIterRefSlice {
+            inner: inner_iter,
+            reader: OwnedOrRef::Owned(reader),
+        }
+    }
+}
diff --git a/rust-libs/tools/kv_typed/src/iter.rs b/rust-libs/tools/kv_typed/src/iter.rs
index 2fee25780e6d7c43c306fe38f70e0db159dbe23a..7e1256df0a51970e08f66b4df15f724016a26686 100644
--- a/rust-libs/tools/kv_typed/src/iter.rs
+++ b/rust-libs/tools/kv_typed/src/iter.rs
@@ -16,7 +16,6 @@
 //! KV Typed iterators
 
 pub mod keys;
-mod range;
 pub mod values;
 
 use crate::*;
@@ -49,9 +48,8 @@ pub struct KvIter<
     K: Key,
     V: Value,
 > {
-    range_iter: range::RangeIter<C, KB, VB, BI>,
-    phantom_key: PhantomData<K>,
-    phantom_value: PhantomData<V>,
+    backend_iter: BI,
+    phantom: PhantomData<(C, KB, VB, K, V)>,
 }
 
 impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
@@ -60,7 +58,7 @@ impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Ke
     type Item = KvResult<(K, V)>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        match self.range_iter.next() {
+        match self.backend_iter.next() {
             Some(Ok((key_bytes, value_bytes))) => match K::from_bytes(key_bytes.as_ref()) {
                 Ok(key) => match V::from_bytes(value_bytes.as_ref()) {
                     Ok(value) => Some(Ok((key, value))),
@@ -74,36 +72,13 @@ impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Ke
     }
 }
 
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
-    ReversableIterator for KvIter<C, KB, VB, BI, K, V>
-{
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        Self {
-            range_iter: self.range_iter.reverse(),
-            phantom_key: PhantomData,
-            phantom_value: PhantomData,
-        }
-    }
-}
-
 impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
     KvIter<C, KB, VB, BI, K, V>
 {
-    #[cfg(feature = "mock")]
-    pub fn new(backend_iter: BI, range: RangeBytes) -> Self {
-        Self {
-            range_iter: range::RangeIter::new(backend_iter, range.0, range.1),
-            phantom_key: PhantomData,
-            phantom_value: PhantomData,
-        }
-    }
-    #[cfg(not(feature = "mock"))]
-    pub(crate) fn new(backend_iter: BI, range: RangeBytes) -> Self {
+    pub fn new(backend_iter: BI) -> Self {
         Self {
-            range_iter: range::RangeIter::new(backend_iter, range.0, range.1),
-            phantom_key: PhantomData,
-            phantom_value: PhantomData,
+            backend_iter,
+            phantom: PhantomData,
         }
     }
 }
@@ -127,10 +102,10 @@ impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Ke
     type ValuesIter = KvIterValues<C, KB, VB, BI, K, V>;
 
     fn keys(self) -> KvIterKeys<C, KB, VB, BI, K> {
-        KvIterKeys::new(self.range_iter)
+        KvIterKeys::new(self.backend_iter)
     }
     fn values(self) -> KvIterValues<C, KB, VB, BI, K, V> {
-        KvIterValues::new(self.range_iter)
+        KvIterValues::new(self.backend_iter)
     }
 }
 
@@ -148,3 +123,92 @@ fn convert_bound<K: Key>(bound_key: Bound<&K>) -> Bound<IVec> {
         Bound::Unbounded => Bound::Unbounded,
     }
 }
+
+#[allow(dead_code, missing_debug_implementations)]
+pub struct KvIterRefSlice<'db, BC, D, K, V, F, R>
+where
+    BC: BackendCol,
+    K: KeyZc,
+    V: ValueSliceZc,
+    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+{
+    pub(crate) inner: KvInnerIterRefSlice<BC, D, K, V, F>,
+    pub(crate) reader: OwnedOrRef<'db, R>,
+}
+impl<'db, BC, D, K, V, F, R> Iterator for KvIterRefSlice<'db, BC, D, K, V, F, R>
+where
+    BC: BackendCol,
+    K: KeyZc,
+    V: ValueSliceZc,
+    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+{
+    type Item = KvResult<D>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.inner.next()
+    }
+}
+
+#[allow(missing_debug_implementations)]
+pub struct KvInnerIterRefSlice<BC, D, K, V, F>
+where
+    BC: BackendCol,
+    K: KeyZc,
+    V: ValueSliceZc,
+    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+{
+    pub(crate) backend_iter: BC::Iter,
+    pub(crate) f: F,
+    pub(crate) phantom: PhantomData<(D, K, V)>,
+}
+impl<BC, D, K, V, F> Iterator for KvInnerIterRefSlice<BC, D, K, V, F>
+where
+    BC: BackendCol,
+    K: KeyZc,
+    V: ValueSliceZc,
+    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+{
+    type Item = KvResult<D>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        match self.backend_iter.next() {
+            Some(Ok((k_bytes, v_bytes))) => {
+                if let Some(k_layout) = zerocopy::LayoutVerified::<_, K::Ref>::new(k_bytes.as_ref())
+                {
+                    if let Some(v_layout) = zerocopy::LayoutVerified::<_, [V::Elem]>::new_slice(
+                        &v_bytes.as_ref()[V::prefix_len()..],
+                    ) {
+                        Some((self.f)(&k_layout, &v_layout))
+                    } else {
+                        Some(Err(KvError::DeserError(
+                            "Bytes are invalid length or alignment.".into(),
+                        )))
+                    }
+                } else {
+                    Some(Err(KvError::DeserError(
+                        "Bytes are invalid length or alignment.".into(),
+                    )))
+                }
+            }
+            Some(Err(e)) => Some(Err(KvError::BackendError(e))),
+            None => None,
+        }
+    }
+}
+
+impl<BC, D, K, V, F> ReversableIterator for KvInnerIterRefSlice<BC, D, K, V, F>
+where
+    BC: BackendCol,
+    K: KeyZc,
+    V: ValueSliceZc,
+    F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+{
+    #[inline(always)]
+    fn reverse(self) -> Self {
+        Self {
+            backend_iter: self.backend_iter.reverse(),
+            f: self.f,
+            phantom: PhantomData,
+        }
+    }
+}
diff --git a/rust-libs/tools/kv_typed/src/iter/keys.rs b/rust-libs/tools/kv_typed/src/iter/keys.rs
index 89c63f7a5ce67f8d8b6d9cada919337df347531b..0555e16cefc6a54977e7230581121aad84f4517d 100644
--- a/rust-libs/tools/kv_typed/src/iter/keys.rs
+++ b/rust-libs/tools/kv_typed/src/iter/keys.rs
@@ -20,8 +20,8 @@ use crate::*;
 #[derive(Debug)]
 pub struct KvIterKeys<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key>
 {
-    range_iter: super::range::RangeIter<C, KB, VB, BI>,
-    phantom_key: PhantomData<K>,
+    backend_iter: BI,
+    phantom: PhantomData<(C, KB, VB, K)>,
 }
 
 impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key> Iterator
@@ -30,7 +30,7 @@ impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Ke
     type Item = KvResult<K>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        match self.range_iter.next() {
+        match self.backend_iter.next() {
             Some(Ok((key_bytes, _value_bytes))) => match K::from_bytes(key_bytes.as_ref()) {
                 Ok(key) => Some(Ok(key)),
                 Err(e) => Some(Err(KvError::DeserError(format!("{}", e)))),
@@ -41,25 +41,13 @@ impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Ke
     }
 }
 
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key>
-    ReversableIterator for KvIterKeys<C, KB, VB, BI, K>
-{
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        Self {
-            range_iter: self.range_iter.reverse(),
-            phantom_key: PhantomData,
-        }
-    }
-}
-
 impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key>
     KvIterKeys<C, KB, VB, BI, K>
 {
-    pub(super) fn new(range_iter: super::range::RangeIter<C, KB, VB, BI>) -> Self {
+    pub(super) fn new(backend_iter: BI) -> Self {
         Self {
-            range_iter,
-            phantom_key: PhantomData,
+            backend_iter,
+            phantom: PhantomData,
         }
     }
 }
diff --git a/rust-libs/tools/kv_typed/src/iter/range.rs b/rust-libs/tools/kv_typed/src/iter/range.rs
deleted file mode 100644
index cabef97a24211929e74fdee83e1c28519998e873..0000000000000000000000000000000000000000
--- a/rust-libs/tools/kv_typed/src/iter/range.rs
+++ /dev/null
@@ -1,122 +0,0 @@
-//  Copyright (C) 2020 Éloïs SANCHEZ.
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as
-// published by the Free Software Foundation, either version 3 of the
-// License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-//! KV Typed iterators
-
-use crate::*;
-
-pub(super) struct RangeIter<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>> {
-    backend_iter: BI,
-    phantom: PhantomData<C>,
-    phantom_kb: PhantomData<KB>,
-    phantom_vb: PhantomData<VB>,
-    reversed: bool,
-    range_start: Bound<IVec>,
-    range_end: Bound<IVec>,
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>> Debug
-    for RangeIter<C, KB, VB, BI>
-{
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("LevelDbCol")
-            .field("backend_iter", &"BackendIter")
-            .field("reversed", &format!("{:?}", self.reversed))
-            .field("range_start", &format!("{:?}", self.range_start))
-            .field("range_end", &format!("{:?}", self.range_end))
-            .finish()
-    }
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>>
-    RangeIter<C, KB, VB, BI>
-{
-    #[inline(always)]
-    pub(crate) fn new(backend_iter: BI, range_start: Bound<IVec>, range_end: Bound<IVec>) -> Self {
-        RangeIter {
-            backend_iter,
-            phantom: PhantomData,
-            phantom_kb: PhantomData,
-            phantom_vb: PhantomData,
-            reversed: false,
-            range_start,
-            range_end,
-        }
-    }
-}
-
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>> Iterator
-    for RangeIter<C, KB, VB, BI>
-{
-    type Item = Result<(KB, VB), DynErr>;
-
-    fn next(&mut self) -> Option<Self::Item> {
-        loop {
-            match self.backend_iter.next() {
-                Some(Ok((key_bytes, value_bytes))) => {
-                    let start_bound_ok = match &self.range_start {
-                        Bound::Included(start_bytes) => key_bytes.as_ref() >= start_bytes.as_ref(),
-                        Bound::Excluded(start_bytes) => key_bytes.as_ref() > start_bytes.as_ref(),
-                        Bound::Unbounded => true,
-                    };
-                    let end_bound_ok = match &self.range_end {
-                        Bound::Included(end_bytes) => key_bytes.as_ref() <= end_bytes.as_ref(),
-                        Bound::Excluded(end_bytes) => key_bytes.as_ref() < end_bytes.as_ref(),
-                        Bound::Unbounded => true,
-                    };
-                    if start_bound_ok {
-                        if end_bound_ok {
-                            break Some(Ok((key_bytes, value_bytes)));
-                        } else if self.reversed {
-                            // The interval has not yet begun.
-                            continue;
-                        } else {
-                            // The range has been fully traversed, the iterator is finished.
-                            break None;
-                        }
-                    } else if end_bound_ok {
-                        if self.reversed {
-                            // The range has been fully traversed, the iterator is finished.
-                            break None;
-                        } else {
-                            // The interval has not yet begun.
-                            continue;
-                        }
-                    } else {
-                        // Empty range, the iterator is finished.
-                        break None;
-                    }
-                }
-                other => break other,
-            }
-        }
-    }
-}
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>> ReversableIterator
-    for RangeIter<C, KB, VB, BI>
-{
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        RangeIter {
-            backend_iter: self.backend_iter.reverse(),
-            phantom: PhantomData,
-            phantom_kb: PhantomData,
-            phantom_vb: PhantomData,
-            reversed: !self.reversed,
-            range_start: self.range_start,
-            range_end: self.range_end,
-        }
-    }
-}
diff --git a/rust-libs/tools/kv_typed/src/iter/values.rs b/rust-libs/tools/kv_typed/src/iter/values.rs
index f701dab041c0beff984dfa388c91dfe3294af3a1..8652d53c486a0bfbdadbe7dbe43ff873496e2bb0 100644
--- a/rust-libs/tools/kv_typed/src/iter/values.rs
+++ b/rust-libs/tools/kv_typed/src/iter/values.rs
@@ -26,9 +26,8 @@ pub struct KvIterValues<
     K: Key,
     V: Value,
 > {
-    range_iter: super::range::RangeIter<C, KB, VB, BI>,
-    phantom_key: PhantomData<K>,
-    phantom_value: PhantomData<V>,
+    backend_iter: BI,
+    phantom: PhantomData<(C, KB, VB, K, V)>,
 }
 
 impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
@@ -37,7 +36,7 @@ impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Ke
     type Item = KvResult<V>;
 
     fn next(&mut self) -> Option<Self::Item> {
-        match self.range_iter.next() {
+        match self.backend_iter.next() {
             Some(Ok((_key_bytes, value_bytes))) => match V::from_bytes(value_bytes.as_ref()) {
                 Ok(value) => Some(Ok(value)),
                 Err(e) => Some(Err(KvError::DeserError(format!("{}", e)))),
@@ -48,27 +47,13 @@ impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Ke
     }
 }
 
-impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
-    ReversableIterator for KvIterValues<C, KB, VB, BI, K, V>
-{
-    #[inline(always)]
-    fn reverse(self) -> Self {
-        Self {
-            range_iter: self.range_iter.reverse(),
-            phantom_key: PhantomData,
-            phantom_value: PhantomData,
-        }
-    }
-}
-
 impl<C: BackendCol, KB: KeyBytes, VB: ValueBytes, BI: BackendIter<KB, VB>, K: Key, V: Value>
     KvIterValues<C, KB, VB, BI, K, V>
 {
-    pub(super) fn new(range_iter: super::range::RangeIter<C, KB, VB, BI>) -> Self {
+    pub(super) fn new(backend_iter: BI) -> Self {
         Self {
-            range_iter,
-            phantom_key: PhantomData,
-            phantom_value: PhantomData,
+            backend_iter,
+            phantom: PhantomData,
         }
     }
 }
diff --git a/rust-libs/tools/kv_typed/src/key.rs b/rust-libs/tools/kv_typed/src/key.rs
index da3992b9a23d9e39ab8cb86e1b100a98f8e03bd0..8a1d1a94a4e7c8b8cba0fb3c9f2308fad6baf0ec 100644
--- a/rust-libs/tools/kv_typed/src/key.rs
+++ b/rust-libs/tools/kv_typed/src/key.rs
@@ -61,5 +61,26 @@ impl<T> Key for T where
 {
 }
 
-#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
+#[derive(
+    Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, zerocopy::AsBytes, zerocopy::FromBytes,
+)]
+#[repr(transparent)]
 pub struct U32BE(pub u32);
+
+impl From<&zerocopy::U32<byteorder::BigEndian>> for U32BE {
+    fn from(u32_zc: &zerocopy::U32<byteorder::BigEndian>) -> Self {
+        U32BE(u32_zc.get())
+    }
+}
+
+pub trait KeyZc: Key {
+    type Ref: Sized + zerocopy::AsBytes + zerocopy::FromBytes;
+}
+
+impl KeyZc for () {
+    type Ref = ();
+}
+
+impl KeyZc for U32BE {
+    type Ref = zerocopy::U32<byteorder::BigEndian>;
+}
diff --git a/rust-libs/tools/kv_typed/src/lib.rs b/rust-libs/tools/kv_typed/src/lib.rs
index 2a881c6b7e68ea2559c2c4e7fb7ec518d8286767..05a4fc5f4b9eea8ac677f35ac0465ceb7200c73e 100644
--- a/rust-libs/tools/kv_typed/src/lib.rs
+++ b/rust-libs/tools/kv_typed/src/lib.rs
@@ -72,6 +72,7 @@ pub mod prelude {
     pub use crate::collection_ro::MockColRo;
     pub use crate::collection_ro::{
         ColRo, DbCollectionRo, DbCollectionRoGetRef, DbCollectionRoGetRefSlice,
+        DbCollectionRoIterRefSlice,
     };
     pub use crate::collection_rw::{ColRw, DbCollectionRw};
     pub use crate::error::{DynErr, KvError, KvResult, StringErr};
@@ -79,8 +80,10 @@ pub mod prelude {
     #[cfg(feature = "explorer")]
     pub use crate::explorer::{ExplorableKey, ExplorableValue};
     pub use crate::from_bytes::FromBytes;
-    pub use crate::iter::{keys::KvIterKeys, values::KvIterValues, EntryIter, KvIter, ResultIter};
-    pub use crate::key::{Key, U32BE};
+    pub use crate::iter::{
+        keys::KvIterKeys, values::KvIterValues, EntryIter, KvIter, KvIterRefSlice, ResultIter,
+    };
+    pub use crate::key::{Key, KeyZc, U32BE};
     pub use crate::subscription::{NewSubscribers, Subscriber, Subscribers};
     pub use crate::transactional_read::{TransactionalRead, TxColRo};
     pub use crate::transactional_write::{DbTxCollectionRw, TransactionalWrite, TxColRw};
@@ -95,7 +98,7 @@ pub(crate) use crate::collection_inner::ColInner;
 pub(crate) use crate::error::BackendResult;
 #[cfg(feature = "explorer")]
 pub(crate) use crate::explorer::{ExplorableKey, ExplorableValue};
-pub(crate) use crate::iter::{RangeBytes, ReversableIterator};
+pub(crate) use crate::iter::{KvInnerIterRefSlice, RangeBytes, ReversableIterator};
 pub(crate) use crate::prelude::*;
 pub(crate) use crate::subscription::{ColSubscribers, SubscriptionsSender};
 pub(crate) use crate::transactional_write::tx_iter::BackendTxIter;
@@ -114,3 +117,16 @@ pub(crate) use std::{
     str::FromStr,
 };
 pub(crate) use thiserror::Error;
+
+pub enum OwnedOrRef<'a, T> {
+    Owned(T),
+    Borrow(&'a T),
+}
+impl<'a, T: Debug> Debug for OwnedOrRef<'a, T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Self::Owned(t) => write!(f, "OwnedOrRef::Owned({:?})", t),
+            Self::Borrow(t) => write!(f, "OwnedOrRef::Borrow({:?})", t),
+        }
+    }
+}
diff --git a/rust-libs/tools/kv_typed/src/transactional_read.rs b/rust-libs/tools/kv_typed/src/transactional_read.rs
index 94b63d4606815d5b18d35e95990a069265a006c5..647861f9b3c8d7c6518e3063e8fdcaf4639b70f8 100644
--- a/rust-libs/tools/kv_typed/src/transactional_read.rs
+++ b/rust-libs/tools/kv_typed/src/transactional_read.rs
@@ -18,19 +18,21 @@
 use crate::*;
 use parking_lot::RwLockReadGuard as ReadGuard;
 
-pub struct TxColRo<'db, BC: BackendCol, E: EventTrait> {
-    col_reader: ReadGuard<'db, ColInner<BC, E>>,
+type TxColRoReader<'r, BC, E> = parking_lot::RwLockReadGuard<'r, ColInner<BC, E>>;
+
+pub struct TxColRo<'tx, BC: BackendCol, E: EventTrait> {
+    col_reader: ReadGuard<'tx, ColInner<BC, E>>,
 }
-impl<'db, BC: BackendCol, E: EventTrait> Debug for TxColRo<'db, BC, E> {
+impl<'tx, BC: BackendCol, E: EventTrait> Debug for TxColRo<'tx, BC, E> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("LevelDbCol")
             .field("col_reader", &format!("{:?}", self.col_reader))
             .finish()
     }
 }
-impl<'db, BC: BackendCol, E: EventTrait> TxColRo<'db, BC, E> {
+impl<'tx, BC: BackendCol, E: EventTrait> TxColRo<'tx, BC, E> {
     #[inline(always)]
-    fn new(col_reader: ReadGuard<'db, ColInner<BC, E>>) -> Self {
+    fn new(col_reader: ReadGuard<'tx, ColInner<BC, E>>) -> Self {
         TxColRo { col_reader }
     }
     #[inline(always)]
@@ -51,11 +53,8 @@ impl<'db, BC: BackendCol, E: EventTrait> TxColRo<'db, BC, E> {
         F: FnOnce(KvIter<BC, BC::KeyBytes, BC::ValueBytes, BC::Iter, E::K, E::V>) -> D,
     {
         let range_bytes = crate::iter::convert_range::<E::K, R>(range);
-        let backend_iter = self
-            .col_reader
-            .backend_col
-            .iter::<E::K, E::V>(range_bytes.clone());
-        f(KvIter::new(backend_iter, range_bytes))
+        let backend_iter = self.col_reader.backend_col.iter::<E::K, E::V>(range_bytes);
+        f(KvIter::new(backend_iter))
     }
     #[allow(clippy::type_complexity)]
     #[inline(always)]
@@ -70,16 +69,67 @@ impl<'db, BC: BackendCol, E: EventTrait> TxColRo<'db, BC, E> {
         let backend_iter = self
             .col_reader
             .backend_col
-            .iter::<E::K, E::V>(range_bytes.clone());
-        f(KvIter::new(backend_iter, range_bytes).reverse())
+            .iter::<E::K, E::V>(range_bytes)
+            .reverse();
+        f(KvIter::new(backend_iter))
     }
 }
-impl<'db, V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'db, BC, E> {
+impl<'tx, V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'tx, BC, E> {
     pub fn get_ref<D, F: Fn(&V::Ref) -> KvResult<D>>(&self, k: &E::K, f: F) -> KvResult<Option<D>> {
         self.col_reader.backend_col.get_ref::<E::K, V, D, F>(k, f)
     }
 }
-impl<'db, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'db, BC, E> {
+impl<'tx, K: KeyZc, V: ValueSliceZc, BC: BackendCol, E: EventTrait<K = K, V = V>>
+    TxColRo<'tx, BC, E>
+{
+    pub fn iter_ref_slice<D, R, F>(
+        &self,
+        range: R,
+        f: F,
+    ) -> KvIterRefSlice<BC, D, K, V, F, TxColRoReader<BC, E>>
+    where
+        K: KeyZc,
+        V: ValueSliceZc,
+        R: 'static + RangeBounds<K>,
+        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+    {
+        let range: RangeBytes = crate::iter::convert_range::<K, R>(range);
+        let inner_iter = self
+            .col_reader
+            .backend_col
+            .iter_ref_slice::<D, K, V, F>(range, f);
+
+        KvIterRefSlice {
+            inner: inner_iter,
+            reader: OwnedOrRef::Borrow(&self.col_reader),
+        }
+    }
+    pub fn iter_ref_slice_rev<D, R, F>(
+        &self,
+        range: R,
+        f: F,
+    ) -> KvIterRefSlice<BC, D, K, V, F, TxColRoReader<BC, E>>
+    where
+        K: KeyZc,
+        V: ValueSliceZc,
+        R: 'static + RangeBounds<K>,
+        F: FnMut(&K::Ref, &[V::Elem]) -> KvResult<D>,
+    {
+        let range: RangeBytes = crate::iter::convert_range::<K, R>(range);
+        let inner_iter = self
+            .col_reader
+            .backend_col
+            .iter_ref_slice::<D, K, V, F>(range, f)
+            .reverse();
+
+        KvIterRefSlice {
+            inner: inner_iter,
+            reader: OwnedOrRef::Borrow(&self.col_reader),
+        }
+    }
+}
+
+impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'tx, BC, E> {
     pub fn get_ref_slice<D, F: Fn(&[V::Elem]) -> KvResult<D>>(
         &self,
         k: &E::K,
@@ -91,24 +141,24 @@ impl<'db, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRo<'db, BC
     }
 }
 
-pub trait TransactionalRead<'db, BC: BackendCol> {
+pub trait TransactionalRead<'tx, BC: BackendCol> {
     type TxCols;
 
-    fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'db self, f: F) -> KvResult<D>;
+    fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D>;
 
-    fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'db self, f: F) -> Result<KvResult<D>, F>;
+    fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> Result<KvResult<D>, F>;
 }
 
-impl<'db, BC: BackendCol, E: EventTrait> TransactionalRead<'db, BC> for &'db ColRo<BC, E> {
-    type TxCols = TxColRo<'db, BC, E>;
+impl<'tx, BC: BackendCol, E: EventTrait> TransactionalRead<'tx, BC> for &'tx ColRo<BC, E> {
+    type TxCols = TxColRo<'tx, BC, E>;
 
-    fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'db self, f: F) -> KvResult<D> {
+    fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D> {
         let read_guard_0 = self.inner.read();
 
         f(TxColRo::new(read_guard_0))
     }
 
-    fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'db self, f: F) -> Result<KvResult<D>, F> {
+    fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> Result<KvResult<D>, F> {
         if let Some(read_guard_0) = self.inner.try_read() {
             Ok(f(TxColRo::new(read_guard_0)))
         } else {
@@ -120,13 +170,13 @@ impl<'db, BC: BackendCol, E: EventTrait> TransactionalRead<'db, BC> for &'db Col
 macro_rules! impl_transactional_read {
     ($($i:literal),*) => {
         paste::paste! {
-            impl<'db, BC: BackendCol $( ,[<E $i>]: EventTrait)*> TransactionalRead<'db, BC>
-                for ($(&'db ColRo<BC, [<E $i>]>, )*)
+            impl<'tx, BC: BackendCol $( ,[<E $i>]: EventTrait)*> TransactionalRead<'tx, BC>
+                for ($(&'tx ColRo<BC, [<E $i>]>, )*)
             {
-                type TxCols = ($(TxColRo<'db, BC,  [<E $i>]>, )*);
+                type TxCols = ($(TxColRo<'tx, BC,  [<E $i>]>, )*);
 
                 fn read<D, F: Fn(Self::TxCols) -> KvResult<D>>(
-                    &'db self,
+                    &'tx self,
                     f: F,
                 ) -> KvResult<D> {
                     $(let [<read_guard_ $i>] = self.$i.inner.read();)*
@@ -135,7 +185,7 @@ macro_rules! impl_transactional_read {
                 }
 
                 fn try_read<D, F: Fn(Self::TxCols) -> KvResult<D>>(
-                    &'db self,
+                    &'tx self,
                     f: F,
                 ) -> Result<KvResult<D>, F> {
                     $(let [<read_guard_opt_ $i>] = self.$i.inner.try_read();)*
diff --git a/rust-libs/tools/kv_typed/src/transactional_write.rs b/rust-libs/tools/kv_typed/src/transactional_write.rs
index b7b4d4181871230679d6a3122a313debca46f75e..7f461bc49922859bef89215ce0cdf8df9cb94d3c 100644
--- a/rust-libs/tools/kv_typed/src/transactional_write.rs
+++ b/rust-libs/tools/kv_typed/src/transactional_write.rs
@@ -20,11 +20,11 @@ pub(crate) mod tx_iter;
 use crate::*;
 use parking_lot::RwLockUpgradableReadGuard as UpgradableReadGuard;
 
-pub struct TxColRw<'db, BC: BackendCol, E: EventTrait> {
+pub struct TxColRw<'tx, BC: BackendCol, E: EventTrait> {
     batch: &'static mut Batch<BC, ColRw<BC, E>>,
-    col_reader: &'db UpgradableReadGuard<'db, ColInner<BC, E>>,
+    col_reader: &'tx UpgradableReadGuard<'tx, ColInner<BC, E>>,
 }
-impl<'db, BC: BackendCol, E: EventTrait> Debug for TxColRw<'db, BC, E> {
+impl<'tx, BC: BackendCol, E: EventTrait> Debug for TxColRw<'tx, BC, E> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         f.debug_struct("LevelDbCol")
             .field("batch", &format!("{:?}", self.batch))
@@ -33,12 +33,12 @@ impl<'db, BC: BackendCol, E: EventTrait> Debug for TxColRw<'db, BC, E> {
     }
 }
 
-impl<'db, V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'db, BC, E> {
+impl<'tx, V: ValueZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'tx, BC, E> {
     pub fn get_ref<D, F: Fn(&V::Ref) -> KvResult<D>>(&self, k: &E::K, f: F) -> KvResult<Option<D>> {
         self.col_reader.backend_col.get_ref::<E::K, V, D, F>(k, f)
     }
 }
-impl<'db, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'db, BC, E> {
+impl<'tx, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'tx, BC, E> {
     pub fn get_ref_slice<D, F: Fn(&[V::Elem]) -> KvResult<D>>(
         &self,
         k: &E::K,
@@ -50,12 +50,7 @@ impl<'db, V: ValueSliceZc, BC: BackendCol, E: EventTrait<V = V>> TxColRw<'db, BC
     }
 }
 
-impl<'db, BC: BackendCol, E: EventTrait> TxColRw<'db, BC, E> {
-    /*type BackendCol = BC;
-    type K = E::K;
-    type V = E::V;
-    type Event = E;*/
-
+impl<'tx, BC: BackendCol, E: EventTrait> TxColRw<'tx, BC, E> {
     #[inline(always)]
     pub fn count(&self) -> KvResult<usize> {
         self.col_reader.backend_col.count()
@@ -73,7 +68,7 @@ impl<'db, BC: BackendCol, E: EventTrait> TxColRw<'db, BC, E> {
     #[allow(clippy::type_complexity)]
     #[inline(always)]
     /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    pub fn iter<'tx, D, R, F>(&'tx self, range: R, f: F) -> D
+    pub fn iter<D, R, F>(&'tx self, range: R, f: F) -> D
     where
         D: Send + Sync,
         R: 'static + RangeBounds<E::K>,
@@ -89,19 +84,16 @@ impl<'db, BC: BackendCol, E: EventTrait> TxColRw<'db, BC, E> {
         ) -> D,
     {
         let range_bytes = crate::iter::convert_range::<E::K, R>(range);
-        let backend_iter = self
-            .col_reader
-            .backend_col
-            .iter::<E::K, E::V>(range_bytes.clone());
-        f(KvIter::new(
-            BackendTxIter::new(backend_iter, &self.batch.tree),
-            range_bytes,
-        ))
+        let backend_iter = self.col_reader.backend_col.iter::<E::K, E::V>(range_bytes);
+        f(KvIter::new(BackendTxIter::new(
+            backend_iter,
+            &self.batch.tree,
+        )))
     }
     #[allow(clippy::type_complexity)]
     #[inline(always)]
     /// Don't worry about complex iter type. Use it like an `impl Iterator<Item=KvResult<(K, V)>>`.
-    pub fn iter_rev<'tx, D, R, F>(&'tx self, range: R, f: F) -> D
+    pub fn iter_rev<D, R, F>(&'tx self, range: R, f: F) -> D
     where
         D: Send + Sync,
         R: 'static + RangeBounds<E::K>,
@@ -117,15 +109,10 @@ impl<'db, BC: BackendCol, E: EventTrait> TxColRw<'db, BC, E> {
         ) -> D,
     {
         let range_bytes = crate::iter::convert_range::<E::K, R>(range);
-        let backend_iter = self
-            .col_reader
-            .backend_col
-            .iter::<E::K, E::V>(range_bytes.clone());
+        let backend_iter = self.col_reader.backend_col.iter::<E::K, E::V>(range_bytes);
         f(KvIter::new(
-            BackendTxIter::new(backend_iter, &self.batch.tree),
-            range_bytes,
-        )
-        .reverse())
+            BackendTxIter::new(backend_iter, &self.batch.tree).reverse(),
+        ))
     }
 }
 
@@ -138,7 +125,7 @@ pub trait DbTxCollectionRw {
     fn upsert(&mut self, k: Self::K, v: Self::V);
 }
 
-impl<'db, BC: BackendCol, E: EventTrait> DbTxCollectionRw for TxColRw<'db, BC, E> {
+impl<'tx, BC: BackendCol, E: EventTrait> DbTxCollectionRw for TxColRw<'tx, BC, E> {
     type K = E::K;
     type V = E::V;
     type Event = E;
@@ -153,16 +140,16 @@ impl<'db, BC: BackendCol, E: EventTrait> DbTxCollectionRw for TxColRw<'db, BC, E
     }
 }
 
-pub trait TransactionalWrite<'db, BC: BackendCol> {
+pub trait TransactionalWrite<'tx, BC: BackendCol> {
     type TxCols;
 
-    fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(&'db self, f: F) -> KvResult<D>;
+    fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D>;
 }
 
-impl<'db, BC: BackendCol, E: EventTrait> TransactionalWrite<'db, BC> for &'db ColRw<BC, E> {
-    type TxCols = TxColRw<'db, BC, E>;
+impl<'tx, BC: BackendCol, E: EventTrait> TransactionalWrite<'tx, BC> for &'tx ColRw<BC, E> {
+    type TxCols = TxColRw<'tx, BC, E>;
 
-    fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(&'db self, f: F) -> KvResult<D> {
+    fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(&'tx self, f: F) -> KvResult<D> {
         let upgradable_guard = self.inner.inner.upgradable_read();
 
         let mut batch = Batch::<BC, ColRw<BC, E>>::default();
@@ -189,13 +176,13 @@ impl<'db, BC: BackendCol, E: EventTrait> TransactionalWrite<'db, BC> for &'db Co
 macro_rules! impl_transactional_write {
     ($($i:literal),*) => {
         paste::paste! {
-            impl<'db, BC: BackendCol $( ,[<E $i>]: EventTrait)*> TransactionalWrite<'db, BC>
-                for ($(&'db ColRw<BC, [<E $i>]>, )*)
+            impl<'tx, BC: BackendCol $( ,[<E $i>]: EventTrait)*> TransactionalWrite<'tx, BC>
+                for ($(&'tx ColRw<BC, [<E $i>]>, )*)
             {
-                type TxCols = ($(TxColRw<'db, BC,  [<E $i>]>, )*);
+                type TxCols = ($(TxColRw<'tx, BC,  [<E $i>]>, )*);
 
                 fn write<D, F: FnOnce(Self::TxCols) -> KvResult<D>>(
-                    &'db self,
+                    &'tx self,
                     f: F,
                 ) -> KvResult<D> {
                     $(let [<upgradable_guard_ $i>] = self.$i.inner.inner.upgradable_read();)*
diff --git a/rust-libs/tools/kv_typed/src/value.rs b/rust-libs/tools/kv_typed/src/value.rs
index 92f0afd877a88cbcd55e17501e32dfb0393522f7..e55ecbf615cc5bf241df3d5ab597376bac5116ff 100644
--- a/rust-libs/tools/kv_typed/src/value.rs
+++ b/rust-libs/tools/kv_typed/src/value.rs
@@ -54,6 +54,10 @@ pub trait ValueZc: Value {
     type Ref: Sized + zerocopy::AsBytes + zerocopy::FromBytes;
 }
 
+impl ValueZc for () {
+    type Ref = ();
+}
+
 macro_rules! impl_value_zc_for_numbers {
     ($($T:ty),*) => {$(
         impl ValueZc for $T {
@@ -61,7 +65,6 @@ macro_rules! impl_value_zc_for_numbers {
         }
     )*};
 }
-
 impl_value_zc_for_numbers!(
     usize, u8, u16, u32, u64, u128, isize, i8, i16, i32, i64, i128, f32, f64
 );
@@ -74,6 +77,14 @@ pub trait ValueSliceZc: Value {
     }
 }
 
+impl ValueSliceZc for () {
+    type Elem = ();
+
+    fn prefix_len() -> usize {
+        0
+    }
+}
+
 impl ValueSliceZc for String {
     type Elem = u8;
 
diff --git a/rust-libs/tools/kv_typed/tests/test_db_schema.rs b/rust-libs/tools/kv_typed/tests/test_db_schema.rs
index 63f0cada21106fda528aafe03c56d834eb393dd6..3722783da33877a0374f8089d00216fe01f12271 100644
--- a/rust-libs/tools/kv_typed/tests/test_db_schema.rs
+++ b/rust-libs/tools/kv_typed/tests/test_db_schema.rs
@@ -8,7 +8,7 @@ db_schema!(
     [
         ["c1", Col1, i32, String],
         ["c2", Col2, usize, ()],
-        ["c3", Col3, u64, Vec<u128>],
+        ["c3", Col3, U32BE, Vec<u128>],
         ["c4", Col4, u64, BTreeSet<u128>],
     ]
 );
@@ -25,7 +25,7 @@ fn test_macro_db() {
             vec![
                 ("col1", "i32", "String"),
                 ("col2", "usize", "()"),
-                ("col3", "u64", "Vec<u128>"),
+                ("col3", "U32BE", "Vec<u128>"),
                 ("col4", "u64", "BTreeSet<u128>")
             ]
         );
@@ -111,8 +111,8 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
         Ok::<(), KvError>(())
     })?;
 
-    db.col3_write().upsert(4, vec![1, 2, 3])?;
-    db.col3().get_ref_slice(&4, |numbers| {
+    db.col3_write().upsert(U32BE(4), vec![1, 2, 3])?;
+    db.col3().get_ref_slice(&U32BE(4), |numbers| {
         assert_eq!(numbers, &[1, 2, 3]);
         Ok(())
     })?;
@@ -126,6 +126,13 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
         Ok(())
     })?;
 
+    // Test iter_ref_slice
+    let vec: Vec<(U32BE, Vec<u128>)> = db
+        .col3()
+        .iter_ref_slice(.., |k, v_slice| Ok((k.into(), Vec::from(v_slice))))
+        .collect::<KvResult<_>>()?;
+    assert_eq!(vec, vec![(U32BE(4), vec![1, 2, 3])]);
+
     // Test transactional
     // A read tx should be opened when write tx not commited
     let (s1, r1) = flume::bounded::<()>(0);
@@ -134,14 +141,14 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
     let read_task = std::thread::spawn(move || {
         r1.recv().expect("disconnected");
         (db_ro.col3(), db_ro.col4(), db_ro.col2()).read(|(c3, c4, _c2)| {
-            c3.get_ref_slice(&4, |numbers| {
+            c3.get_ref_slice(&U32BE(4), |numbers| {
                 assert_eq!(numbers, &[1, 2, 3]);
                 Ok(())
             })?;
             c3.iter(.., |it| {
                 let iter = it.keys();
                 s2.send(()).expect("disconnected");
-                assert_eq!(iter.collect::<KvResult<Vec<_>>>()?, vec![4]);
+                assert_eq!(iter.collect::<KvResult<Vec<_>>>()?, vec![U32BE(4)]);
                 Ok::<(), KvError>(())
             })?;
             c4.get_ref_slice(&4, |numbers| {
@@ -157,31 +164,34 @@ fn test_db<B: Backend>(db: &TestV1Db<B>) -> KvResult<()> {
             s1.send(()).expect("disconnected");
             assert_eq!(
                 c3.iter(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![4]
+                vec![U32BE(4)]
             );
             assert_eq!(
                 c3.iter(.., |it| it.values().collect::<KvResult<Vec<_>>>())?,
                 vec![vec![1, 2, 3]]
             );
-            c3.upsert(42, vec![5, 4, 6]);
+            c3.upsert(U32BE(42), vec![5, 4, 6]);
             assert_eq!(
                 c3.iter(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![4, 42]
+                vec![U32BE(4), U32BE(42)]
             );
             assert_eq!(
                 c3.iter_rev(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![42, 4]
+                vec![U32BE(42), U32BE(4)]
             );
-            c3.upsert(8, vec![11, 12, 13]);
-            c3.remove(4);
+            c3.upsert(U32BE(8), vec![11, 12, 13]);
+            c3.remove(U32BE(4));
             assert_eq!(
                 c3.iter(.., |it| it.keys().collect::<KvResult<Vec<_>>>())?,
-                vec![8, 42]
+                vec![U32BE(8), U32BE(42)]
             );
             c3.iter_rev(.., |it| {
                 let iter = it.keys();
                 r2.recv().expect("disconnected");
-                assert_eq!(iter.collect::<KvResult<Vec<_>>>()?, vec![42, 8]);
+                assert_eq!(
+                    iter.collect::<KvResult<Vec<_>>>()?,
+                    vec![U32BE(42), U32BE(8)]
+                );
 
                 Ok::<(), KvError>(())
             })?;