Open qthree opened 1 week ago
And for TreeIndex we can add another trait for Borrow + Ord, something like
pub trait Compare<K: ?Sized> {
// Required method
fn compare(&self, key: &K) -> std::cmp::Ordering;
}
impl<Q, K> Compare<K> for Q
where
Q: Ord + ?Sized,
K: Borrow<Q> + ?Sized,
{
fn compare(&self, key: &K) -> std::cmp::Ordering {
self.cmp(key.borrow())
}
}
impl<K, V> TreeIndex<K, V> {
pub fn peek<'g, Q>(&self, key: &Q, guard: &'g Guard) -> Option<&'g V>
where
Q: Compare<K>,
{...}
}
Actually, there is already crate with exactly those two traits, what's your policy for adding deps?
Hi @qthree,
This looks a really good idea, thanks a lot. On the other hand, the crate seems way too trivial to be a dependency, so can you possibly use your own code in your comment (in compare.rs? + for the equivalent trait, you may have to state that the code is "inspired" or "copied" from the equivalent crate) instead of adding the crate to Cargo.toml?
@wvwwvwwv I can do It the same way hashbrown did it.
Copy-paste Comparable and Equivalent traits into scc, in a new module, but then place this new module under #[cfg(not(feature = "equivalent")]
.
So if users want to they can enable equivalent dependency. For example if they want to use the same query type in different maps without reimplementing the same trait twice.
hashbrown crate uses Equivalent trait instead of Borrow for get operations. It's much more useful cause you can't return non-reference from Borrow::borrow, for example if you want to implement you own String/str combination (newtypes). Of course you can use bytemuck transparent derive to convert between &str and newtype reference, but that's not ideal, for example if want to add another field into query type. I propose to rewrite all scc methods to use new Equivalent trait instead of Borrow, and do blanket impl for Borrow as hashbrown does.