You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I would like to suggest changing lookup API from
where
K:Borrow<Q>,Q: ?Sized + Ord,
to
where
Q: ?Sized + Ord + equivalent::Comparable<K>,
The equivalent is the crate used by indexmap.
I find the lookup API is limited by the Borrow trait. e.g., with Borrow trait, this example cannot be implemented as we cannot implement impl<'a> core::borrow::Borrow<FooRef<'a>> for Foo because of Rust's rule.
#[derive(PartialEq,Eq,PartialOrd,Ord)]structFoo{a:u64,b:u32,}#[derive(PartialEq,Eq)]structFooRef<'a>{data:&'a [u8],}implPartialOrdforFooRef<'_>{fnpartial_cmp(&self,other:&Self) -> Option<std::cmp::Ordering>{Some(self.cmp(other))}}implOrdforFooRef<'_>{fncmp(&self,other:&Self) -> std::cmp::Ordering{let a = u64::from_be_bytes(self.data[..8].try_into().unwrap());let b = u32::from_be_bytes(self.data[8..].try_into().unwrap());let other_a = u64::from_be_bytes(other.data[..8].try_into().unwrap());let other_b = u32::from_be_bytes(other.data[8..].try_into().unwrap());Foo{ a, b }.cmp(&Foo{a: other_a,b: other_b,})}}impl<'a> core::borrow::Borrow<FooRef<'a>>forFoo{fnborrow(&self) -> &FooRef<'a>{// we cannot return a reference to a local variabletodo!()}}fnlookup(){let s = SkipMap::new();let foo = Foo{a:1,b:2};
s.insert(foo,12);let buf = 1u64.to_be_bytes().iter().chain(2u32.to_be_bytes().iter()).copied().collect::<Vec<_>>();let foo_ref = FooRef{data:&buf };let ent = s.get(&foo_ref).unwrap();assert_eq!(ent.key().a, 1);assert_eq!(ent.key().b, 2);assert_eq!(*ent.value(), 12);}
After change to Q: ?Sized + Ord + Comparable<K>, just like how indexmap do in its lookup API, the above example can be implemented.
use equivalent::{Comparable,Equivalent};#[derive(PartialEq,Eq,PartialOrd,Ord)]structFoo{a:u64,b:u32,}#[derive(PartialEq,Eq)]structFooRef<'a>{data:&'a [u8],}implPartialOrdforFooRef<'_>{fnpartial_cmp(&self,other:&Self) -> Option<std::cmp::Ordering>{Some(self.cmp(other))}}implOrdforFooRef<'_>{fncmp(&self,other:&Self) -> std::cmp::Ordering{let a = u64::from_be_bytes(self.data[..8].try_into().unwrap());let b = u32::from_be_bytes(self.data[8..].try_into().unwrap());let other_a = u64::from_be_bytes(other.data[..8].try_into().unwrap());let other_b = u32::from_be_bytes(other.data[8..].try_into().unwrap());Foo{ a, b }.cmp(&Foo{a: other_a,b: other_b,})}}implEquivalent<Foo>forFooRef<'_>{fnequivalent(&self,key:&Foo) -> bool{let a = u64::from_be_bytes(self.data[..8].try_into().unwrap());let b = u32::from_be_bytes(self.data[8..].try_into().unwrap());
a == key.a && b == key.b}}implComparable<Foo>forFooRef<'_>{fncompare(&self,key:&Foo) -> std::cmp::Ordering{let a = u64::from_be_bytes(self.data[..8].try_into().unwrap());let b = u32::from_be_bytes(self.data[8..].try_into().unwrap());Foo{ a, b }.cmp(key)}}fnlookup(){let s = SkipMap::new();let foo = Foo{a:1,b:2};
s.insert(foo,12);let buf = 1u64.to_be_bytes().iter().chain(2u32.to_be_bytes().iter()).copied().collect::<Vec<_>>();let foo_ref = FooRef{data:&buf };let ent = s.get(&foo_ref).unwrap();assert_eq!(ent.key().a, 1);assert_eq!(ent.key().b, 2);assert_eq!(*ent.value(), 12);}
This feature is quite important when using some zero-copy deserialization frameworks like rkyv's types with SkipMap to avoid the allocation.
The text was updated successfully, but these errors were encountered:
Hi, I would like to suggest changing lookup API from
to
The
equivalent
is the crate used byindexmap
.I find the lookup API is limited by the
Borrow
trait. e.g., withBorrow
trait, this example cannot be implemented as we cannot implementimpl<'a> core::borrow::Borrow<FooRef<'a>> for Foo
because of Rust's rule.After change to
Q: ?Sized + Ord + Comparable<K>
, just like howindexmap
do in its lookup API, the above example can be implemented.This feature is quite important when using some zero-copy deserialization frameworks like
rkyv
's types withSkipMap
to avoid the allocation.The text was updated successfully, but these errors were encountered: