From a00708d376d8e64226f55ec292e109c3a0f38acc Mon Sep 17 00:00:00 2001 From: Declan Kelly Date: Sun, 7 Jul 2024 22:11:03 -0700 Subject: [PATCH] Remove `AsBytes` bound from most places **Motivation** The `AsBytes` bound is only required in code path where the key type needs to be converted into `&[u8]`. Having it in other locations clutters the set of trait bounds required and causes it to propagate other places. **Testing Done** `./scripts/full-testing.sh nightly` --- src/collections/map.rs | 43 +++++++----- src/collections/map/entry_ref.rs | 10 +-- src/collections/map/iterators/fuzzy.rs | 1 + src/collections/map/iterators/into_iter.rs | 26 +++---- src/collections/map/iterators/iterator.rs | 19 ++--- src/collections/map/iterators/prefix.rs | 2 +- src/nodes/operations.rs | 6 +- src/nodes/operations/delete.rs | 14 ++-- src/nodes/operations/insert.rs | 8 +-- src/nodes/operations/minmax.rs | 6 +- src/nodes/representation.rs | 69 ++++++++++--------- src/nodes/representation/header.rs | 5 +- src/nodes/representation/inner_node_256.rs | 34 ++++----- src/nodes/representation/inner_node_48.rs | 36 ++++------ .../representation/inner_node_compressed.rs | 39 ++++------- src/nodes/visitor.rs | 39 ++++------- 16 files changed, 159 insertions(+), 198 deletions(-) diff --git a/src/collections/map.rs b/src/collections/map.rs index 55626059..b4750379 100644 --- a/src/collections/map.rs +++ b/src/collections/map.rs @@ -18,14 +18,14 @@ pub use entry_ref::*; pub use iterators::*; /// An ordered map based on an adaptive radix tree. -pub struct TreeMap { +pub struct TreeMap { /// The number of entries present in the tree. num_entries: usize, /// A pointer to the tree root, if present. pub(crate) root: Option>, } -impl TreeMap { +impl TreeMap { /// Create a new, empty [`crate::TreeMap`] with the default number of prefix /// bytes (16). /// @@ -45,7 +45,7 @@ impl TreeMap { } } -impl TreeMap { +impl TreeMap { /// Create a new, empty [`crate::TreeMap`]. /// /// This function will not pre-allocate anything. @@ -559,10 +559,7 @@ impl TreeMap { fn apply_delete_point( &mut self, delete_point: DeletePoint, - ) -> DeleteResult - where - K: AsBytes, - { + ) -> DeleteResult { // SAFETY: The root is sure to not be `None`, since the we somehow got a // `DeletePoint`. So the caller must have checked this let delete_result = delete_point.apply(unsafe { self.root.unwrap_unchecked() }); @@ -1116,7 +1113,10 @@ impl TreeMap { /// /// assert_eq!(p, vec![(&c"abcde", &0), (&c"abcdexxx", &0), (&c"abcdexxy", &0)]); /// ``` - pub fn prefix<'a, 'b>(&'a self, prefix: &'b [u8]) -> Prefix<'a, 'b, K, V, PREFIX_LEN> { + pub fn prefix<'a, 'b>(&'a self, prefix: &'b [u8]) -> Prefix<'a, 'b, K, V, PREFIX_LEN> + where + K: AsBytes, + { Prefix::new(self, prefix) } @@ -1139,10 +1139,10 @@ impl TreeMap { /// /// assert_eq!(p, vec![(&c"abcde", &mut 0), (&c"abcdexxx", &mut 0), (&c"abcdexxy", &mut 0)]); /// ``` - pub fn prefix_mut<'a, 'b>( - &'a mut self, - prefix: &'b [u8], - ) -> PrefixMut<'a, 'b, K, V, PREFIX_LEN> { + pub fn prefix_mut<'a, 'b>(&'a mut self, prefix: &'b [u8]) -> PrefixMut<'a, 'b, K, V, PREFIX_LEN> + where + K: AsBytes, + { PrefixMut::new(self, prefix) } @@ -1164,7 +1164,10 @@ impl TreeMap { /// /// assert_eq!(p, vec![&c"abcde", &c"abcdexxx", &c"abcdexxy"]); /// ``` - pub fn prefix_keys<'a, 'b>(&'a self, prefix: &'b [u8]) -> PrefixKeys<'a, 'b, K, V, PREFIX_LEN> { + pub fn prefix_keys<'a, 'b>(&'a self, prefix: &'b [u8]) -> PrefixKeys<'a, 'b, K, V, PREFIX_LEN> + where + K: AsBytes, + { PrefixKeys::new(self, prefix) } @@ -1189,7 +1192,10 @@ impl TreeMap { pub fn prefix_values<'a, 'b>( &'a self, prefix: &'b [u8], - ) -> PrefixValues<'a, 'b, K, V, PREFIX_LEN> { + ) -> PrefixValues<'a, 'b, K, V, PREFIX_LEN> + where + K: AsBytes, + { PrefixValues::new(self, prefix) } @@ -1215,7 +1221,10 @@ impl TreeMap { pub fn prefix_values_mut<'a, 'b>( &'a mut self, prefix: &'b [u8], - ) -> PrefixValuesMut<'a, 'b, K, V, PREFIX_LEN> { + ) -> PrefixValuesMut<'a, 'b, K, V, PREFIX_LEN> + where + K: AsBytes, + { PrefixValuesMut::new(self, prefix) } @@ -1251,7 +1260,7 @@ impl TreeMap { } } -impl TreeMap { +impl TreeMap { /// Tries to get the given key’s corresponding entry in the map for in-place /// manipulation. pub fn try_entry(&mut self, key: K) -> Result, InsertPrefixError> @@ -1352,7 +1361,7 @@ impl TreeMap { } } -impl Drop for TreeMap { +impl Drop for TreeMap { fn drop(&mut self) { self.clear(); } diff --git a/src/collections/map/entry_ref.rs b/src/collections/map/entry_ref.rs index ab2db2b4..06df9296 100644 --- a/src/collections/map/entry_ref.rs +++ b/src/collections/map/entry_ref.rs @@ -4,10 +4,7 @@ use crate::{AsBytes, DeletePoint, InsertPoint, LeafNode, NodePtr, OpaqueNodePtr, /// A view into an occupied entry in a [`TreeMap`]. It is part of the /// [`EntryRef`] enum. -pub struct OccupiedEntryRef<'a, K, V, const PREFIX_LEN: usize> -where - K: AsBytes, -{ +pub struct OccupiedEntryRef<'a, K, V, const PREFIX_LEN: usize> { pub(crate) leaf_node_ptr: NodePtr>, /// Used for the removal @@ -18,10 +15,7 @@ where pub(crate) parent_ptr_and_child_key_byte: Option<(OpaqueNodePtr, u8)>, } -impl<'a, K, V, const PREFIX_LEN: usize> OccupiedEntryRef<'a, K, V, PREFIX_LEN> -where - K: AsBytes, -{ +impl<'a, K, V, const PREFIX_LEN: usize> OccupiedEntryRef<'a, K, V, PREFIX_LEN> { /// Gets a reference to the value in the entry. pub fn get(&self) -> &V { // SAFETY: This is safe because `Self` has an mutable reference diff --git a/src/collections/map/iterators/fuzzy.rs b/src/collections/map/iterators/fuzzy.rs index aad22241..1434d960 100644 --- a/src/collections/map/iterators/fuzzy.rs +++ b/src/collections/map/iterators/fuzzy.rs @@ -171,6 +171,7 @@ trait FuzzySearch { ) -> bool where Self: InnerNode, + Self::Key: AsBytes, { // We can use the fact that the first entry in the old_row holds, // the length of how many bytes we used so far, so this becomes de depth diff --git a/src/collections/map/iterators/into_iter.rs b/src/collections/map/iterators/into_iter.rs index cca59dac..754594ec 100644 --- a/src/collections/map/iterators/into_iter.rs +++ b/src/collections/map/iterators/into_iter.rs @@ -1,4 +1,4 @@ -use crate::{AsBytes, TreeMap}; +use crate::TreeMap; /// An owning iterator over the entries of a `TreeMap`. /// @@ -7,15 +7,15 @@ use crate::{AsBytes, TreeMap}; /// /// [`into_iter`]: IntoIterator::into_iter /// [`IntoIterator`]: core::iter::IntoIterator -pub struct IntoIter(TreeMap); +pub struct IntoIter(TreeMap); -impl IntoIter { +impl IntoIter { pub(crate) fn new(tree: TreeMap) -> Self { IntoIter(tree) } } -impl Iterator for IntoIter { +impl Iterator for IntoIter { type Item = (K, V); fn next(&mut self) -> Option { @@ -29,7 +29,7 @@ impl Iterator for IntoIter DoubleEndedIterator for IntoIter { +impl DoubleEndedIterator for IntoIter { fn next_back(&mut self) -> Option { self.0.pop_last() } @@ -39,15 +39,15 @@ impl DoubleEndedIterator for IntoIter(IntoIter); +pub struct IntoKeys(IntoIter); -impl IntoKeys { +impl IntoKeys { pub(crate) fn new(tree: TreeMap) -> Self { IntoKeys(IntoIter::new(tree)) } } -impl Iterator for IntoKeys { +impl Iterator for IntoKeys { type Item = K; fn next(&mut self) -> Option { @@ -55,7 +55,7 @@ impl Iterator for IntoKeys DoubleEndedIterator for IntoKeys { +impl DoubleEndedIterator for IntoKeys { fn next_back(&mut self) -> Option { Some(self.0.next_back()?.0) } @@ -67,15 +67,15 @@ impl DoubleEndedIterator for IntoKeys(IntoIter); +pub struct IntoValues(IntoIter); -impl IntoValues { +impl IntoValues { pub(crate) fn new(tree: TreeMap) -> Self { IntoValues(IntoIter::new(tree)) } } -impl Iterator for IntoValues { +impl Iterator for IntoValues { type Item = V; fn next(&mut self) -> Option { @@ -83,7 +83,7 @@ impl Iterator for IntoValues DoubleEndedIterator for IntoValues { +impl DoubleEndedIterator for IntoValues { fn next_back(&mut self) -> Option { Some(self.0.next_back()?.1) } diff --git a/src/collections/map/iterators/iterator.rs b/src/collections/map/iterators/iterator.rs index d71bc2fc..7a8edf9d 100644 --- a/src/collections/map/iterators/iterator.rs +++ b/src/collections/map/iterators/iterator.rs @@ -1,16 +1,16 @@ -use crate::{AsBytes, ConcreteNodePtr, InnerNode, NodePtr, OpaqueNodePtr, TreeMap}; +use crate::{ConcreteNodePtr, InnerNode, NodePtr, OpaqueNodePtr, TreeMap}; use std::{collections::VecDeque, iter::FusedIterator}; macro_rules! gen_iter { ($name:ident, $tree:ty, $ret:ty, $op:ident) => { /// An iterator over all the `LeafNode`s - pub struct $name<'a, K: AsBytes, V, const PREFIX_LEN: usize> { + pub struct $name<'a, K, V, const PREFIX_LEN: usize> { nodes: VecDeque>, size: usize, _tree: $tree, } - impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> $name<'a, K, V, PREFIX_LEN> { + impl<'a, K, V, const PREFIX_LEN: usize> $name<'a, K, V, PREFIX_LEN> { /// Create a new iterator that will visit all leaf nodes descended from the /// given node. pub(crate) fn new(tree: $tree) -> Self { @@ -51,7 +51,7 @@ macro_rules! gen_iter { } } - impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> Iterator for $name<'a, K, V, PREFIX_LEN> { + impl<'a, K, V, const PREFIX_LEN: usize> Iterator for $name<'a, K, V, PREFIX_LEN> { type Item = $ret; fn next(&mut self) -> Option { @@ -83,7 +83,7 @@ macro_rules! gen_iter { } } - impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> DoubleEndedIterator + impl<'a, K, V, const PREFIX_LEN: usize> DoubleEndedIterator for $name<'a, K, V, PREFIX_LEN> { fn next_back(&mut self) -> Option { @@ -104,14 +104,9 @@ macro_rules! gen_iter { } } - impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> FusedIterator - for $name<'a, K, V, PREFIX_LEN> - { - } + impl<'a, K, V, const PREFIX_LEN: usize> FusedIterator for $name<'a, K, V, PREFIX_LEN> {} - impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> ExactSizeIterator - for $name<'a, K, V, PREFIX_LEN> - { + impl<'a, K, V, const PREFIX_LEN: usize> ExactSizeIterator for $name<'a, K, V, PREFIX_LEN> { fn len(&self) -> usize { self.size } diff --git a/src/collections/map/iterators/prefix.rs b/src/collections/map/iterators/prefix.rs index 37372ffe..39779515 100644 --- a/src/collections/map/iterators/prefix.rs +++ b/src/collections/map/iterators/prefix.rs @@ -65,7 +65,7 @@ macro_rules! gen_add_children { macro_rules! gen_iter { ($name:ident, $tree:ty, $ret:ty, $op:ident) => { /// An iterator over all the `LeafNode`s with a specific prefix - pub struct $name<'a, 'b, K: AsBytes, V, const PREFIX_LEN: usize> { + pub struct $name<'a, 'b, K, V, const PREFIX_LEN: usize> { nodes: VecDeque<(OpaqueNodePtr, usize)>, size: usize, _tree: $tree, diff --git a/src/nodes/operations.rs b/src/nodes/operations.rs index 04fd7bfb..90e09efd 100644 --- a/src/nodes/operations.rs +++ b/src/nodes/operations.rs @@ -1,6 +1,6 @@ //! Trie node lookup and manipulation -use crate::{AsBytes, ConcreteNodePtr, InnerNode, NodePtr, OpaqueNodePtr}; +use crate::{ConcreteNodePtr, InnerNode, NodePtr, OpaqueNodePtr}; mod insert; pub(crate) use insert::*; @@ -21,10 +21,10 @@ pub(crate) use delete::*; /// # Safety /// - This function must only be called once for this root node and all /// descendants, otherwise a double-free could result. -pub unsafe fn deallocate_tree( +pub unsafe fn deallocate_tree( root: OpaqueNodePtr, ) { - fn deallocate_inner_node( + fn deallocate_inner_node( stack: &mut Vec>, inner_ptr: NodePtr, ) where diff --git a/src/nodes/operations/delete.rs b/src/nodes/operations/delete.rs index 57f0788e..755ca738 100644 --- a/src/nodes/operations/delete.rs +++ b/src/nodes/operations/delete.rs @@ -110,7 +110,7 @@ unsafe fn remove_child_from_inner_node_and_compress< /// have any other mutable references. /// - `leaf_node_ptr` must be a unique pointer to the node and not have any /// other mutable references. -unsafe fn inner_delete_non_root_unchecked( +unsafe fn inner_delete_non_root_unchecked( leaf_node_ptr: NodePtr>, (parent_node_ptr, parent_key_byte): (OpaqueNodePtr, u8), grandparent_node_ptr: Option<(OpaqueNodePtr, u8)>, @@ -193,7 +193,7 @@ unsafe fn inner_delete_non_root_unchecked { +pub struct DeleteResult { /// The new root node for the tree, after the delete has been applied. /// /// If `None`, that means the tree is now empty. @@ -202,7 +202,7 @@ pub struct DeleteResult { pub deleted_leaf: LeafNode, } -pub struct DeletePoint { +pub struct DeletePoint { /// The grandparent node of the leaf that will be deleted and the key byte /// that was used to continue search. /// @@ -219,7 +219,7 @@ pub struct DeletePoint { pub leaf_node_ptr: NodePtr>, } -impl std::fmt::Debug for DeletePoint { +impl std::fmt::Debug for DeletePoint { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("DeleteSearchResult") .field( @@ -232,7 +232,7 @@ impl std::fmt::Debug for DeletePoint DeletePoint { +impl DeletePoint { /// Handle the logic of deleting a leaf node from the tree, after it has /// been found. /// @@ -368,7 +368,7 @@ where /// on `root` or any child node of `root`. This function will arbitrarily /// read to any child in the given tree. #[inline(always)] -pub unsafe fn find_minimum_to_delete( +pub unsafe fn find_minimum_to_delete( root: OpaqueNodePtr, ) -> DeletePoint { let mut current_grandparent = None; @@ -406,7 +406,7 @@ pub unsafe fn find_minimum_to_delete( /// on `root` or any child node of `root`. This function will arbitrarily /// read to any child in the given tree. #[inline(always)] -pub unsafe fn find_maximum_to_delete( +pub unsafe fn find_maximum_to_delete( root: OpaqueNodePtr, ) -> DeletePoint { let mut current_grandparent = None; diff --git a/src/nodes/operations/insert.rs b/src/nodes/operations/insert.rs index ef7dda10..64b46cc8 100644 --- a/src/nodes/operations/insert.rs +++ b/src/nodes/operations/insert.rs @@ -7,7 +7,7 @@ use std::{borrow::Borrow, error::Error, fmt, marker::PhantomData, ops::ControlFl /// The results of a successful tree insert #[derive(Debug)] -pub struct InsertResult<'a, K: AsBytes, V, const PREFIX_LEN: usize> { +pub struct InsertResult<'a, K, V, const PREFIX_LEN: usize> { /// Pointer to the leaf pub leaf_node_ptr: NodePtr>, /// The existing leaf referenced by the insert key, if present @@ -44,7 +44,7 @@ impl Error for InsertPrefixError {} /// /// It contains all the relevant information needed to perform the insert /// and update the tree. -pub struct InsertPoint { +pub struct InsertPoint { /// The grandparent node pointer and key byte that points to the parent node /// insert point. /// @@ -71,7 +71,7 @@ pub struct InsertPoint { pub root: OpaqueNodePtr, } -impl InsertPoint { +impl InsertPoint { pub fn apply<'a>(self, key: K, value: V) -> InsertResult<'a, K, V, PREFIX_LEN> where K: AsBytes + 'a, @@ -386,7 +386,7 @@ impl InsertPoint { } /// The type of insert -pub enum InsertSearchResultType { +pub enum InsertSearchResultType { /// An insert where an inner node had a differing prefix from the key. /// /// This insert type will create a new inner node with the portion of diff --git a/src/nodes/operations/minmax.rs b/src/nodes/operations/minmax.rs index 846e04aa..c78673c9 100644 --- a/src/nodes/operations/minmax.rs +++ b/src/nodes/operations/minmax.rs @@ -1,4 +1,4 @@ -use crate::{AsBytes, ConcreteNodePtr, InnerNode, LeafNode, NodePtr, OpaqueNodePtr}; +use crate::{ConcreteNodePtr, InnerNode, LeafNode, NodePtr, OpaqueNodePtr}; /// Search for the leaf with the minimum key, by lexicographic ordering. /// @@ -7,7 +7,7 @@ use crate::{AsBytes, ConcreteNodePtr, InnerNode, LeafNode, NodePtr, OpaqueNodePt /// on `root` or any child node of `root`. This function will arbitrarily /// read to any child in the given tree. #[inline(always)] -pub unsafe fn minimum_unchecked( +pub unsafe fn minimum_unchecked( root: OpaqueNodePtr, ) -> NodePtr> { let mut current_node = root; @@ -32,7 +32,7 @@ pub unsafe fn minimum_unchecked( /// on `root` or any child node of `root`. This function will arbitrarily /// read to any child in the given tree. #[inline(always)] -pub unsafe fn maximum_unchecked( +pub unsafe fn maximum_unchecked( root: OpaqueNodePtr, ) -> NodePtr> { let mut current_node = root; diff --git a/src/nodes/representation.rs b/src/nodes/representation.rs index 84480dd1..b10eec0d 100644 --- a/src/nodes/representation.rs +++ b/src/nodes/representation.rs @@ -104,46 +104,46 @@ struct OpaqueValue; /// Could be any one of the NodeTypes, need to perform check on the runtime type /// and then cast to a [`NodePtr`]. #[repr(transparent)] -pub struct OpaqueNodePtr( +pub struct OpaqueNodePtr( TaggedPointer, PhantomData<(K, V)>, ); -impl Copy for OpaqueNodePtr {} +impl Copy for OpaqueNodePtr {} -impl Clone for OpaqueNodePtr { +impl Clone for OpaqueNodePtr { fn clone(&self) -> Self { *self } } -impl fmt::Debug for OpaqueNodePtr { +impl fmt::Debug for OpaqueNodePtr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("OpaqueNodePtr").field(&self.0).finish() } } -impl fmt::Pointer for OpaqueNodePtr { +impl fmt::Pointer for OpaqueNodePtr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.0, f) } } -impl Eq for OpaqueNodePtr {} +impl Eq for OpaqueNodePtr {} -impl PartialEq for OpaqueNodePtr { +impl PartialEq for OpaqueNodePtr { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } -impl Hash for OpaqueNodePtr { +impl Hash for OpaqueNodePtr { fn hash(&self, state: &mut H) { self.0.hash(state); } } -impl OpaqueNodePtr { +impl OpaqueNodePtr { /// Construct a new opaque node pointer from an existing non-null node /// pointer. pub fn new(pointer: NonNull) -> Self @@ -262,7 +262,7 @@ impl OpaqueNodePtr { } /// An enum that encapsulates pointers to every type of Node -pub enum ConcreteNodePtr { +pub enum ConcreteNodePtr { /// Node that references between 2 and 4 children Node4(NodePtr>), /// Node that references between 5 and 16 children @@ -289,7 +289,7 @@ impl fmt::Debug for ConcreteNodePtr>(NonNull); +pub struct NodePtr(NonNull); impl> NodePtr { /// Create a safe pointer to a [`Node`]. @@ -396,7 +396,7 @@ impl> NodePtr { } } -impl NodePtr> { +impl NodePtr> { /// Returns a shared reference to the key and value of the pointed to /// [`LeafNode`]. /// @@ -490,12 +490,12 @@ impl NodePtr> Clone for NodePtr { +impl Clone for NodePtr { fn clone(&self) -> Self { *self } } -impl> Copy for NodePtr {} +impl Copy for NodePtr {} impl> From<&mut N> for NodePtr { fn from(node_ref: &mut N) -> Self { @@ -505,38 +505,36 @@ impl> From<&mut N> for NodePtr> PartialEq for NodePtr { +impl PartialEq for NodePtr { fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } -impl> Eq for NodePtr {} +impl Eq for NodePtr {} -impl> fmt::Debug for NodePtr { +impl fmt::Debug for NodePtr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_tuple("NodePtr").field(&self.0).finish() } } -impl> fmt::Pointer for NodePtr { +impl fmt::Pointer for NodePtr { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Pointer::fmt(&self.0, f) } } pub(crate) mod private { - use crate::AsBytes; - /// This trait is used to seal other traits, such that they cannot be /// implemented outside of the crate. pub trait Sealed {} - impl Sealed for super::InnerNode4 {} - impl Sealed for super::InnerNode16 {} - impl Sealed for super::InnerNode48 {} - impl Sealed for super::InnerNode256 {} - impl Sealed for super::LeafNode {} + impl Sealed for super::InnerNode4 {} + impl Sealed for super::InnerNode16 {} + impl Sealed for super::InnerNode48 {} + impl Sealed for super::InnerNode256 {} + impl Sealed for super::LeafNode {} } /// All nodes which contain a runtime tag that validates their type. @@ -545,7 +543,7 @@ pub trait Node: private::Sealed { const TYPE: NodeType; /// The key type carried by the leaf nodes - type Key: AsBytes; + type Key; /// The value type carried by the leaf nodes type Value; @@ -553,7 +551,7 @@ pub trait Node: private::Sealed { /// Result of prefix match #[derive(Debug)] -pub enum MatchPrefixResult { +pub enum MatchPrefixResult { /// If prefixes don't match Mismatch { /// Mismatch object @@ -568,7 +566,7 @@ pub enum MatchPrefixResult { /// Represents a prefix mismatch #[derive(Debug)] -pub struct Mismatch { +pub struct Mismatch { /// How many bytes were matched pub matched_bytes: usize, /// Value of the byte that made it not match @@ -671,8 +669,7 @@ pub trait InnerNode: Node + Sized { fn range( &self, bound: impl RangeBounds, - ) -> impl Iterator)> - + DoubleEndedIterator + ) -> impl DoubleEndedIterator)> + FusedIterator; /// Compares the compressed path of a node with the key and returns the @@ -685,7 +682,10 @@ pub trait InnerNode: Node + Sized { &self, key: &[u8], current_depth: usize, - ) -> MatchPrefixResult { + ) -> MatchPrefixResult + where + Self::Key: AsBytes, + { #[allow(unused_unsafe)] unsafe { // SAFETY: Since we are iterating the key and prefixes, we @@ -724,7 +724,10 @@ pub trait InnerNode: Node + Sized { ) -> ( &[u8], Option>>, - ) { + ) + where + Self::Key: AsBytes, + { self.header().inner_read_full_prefix(self, current_depth) } @@ -813,7 +816,7 @@ impl LeafNode { } } -impl Node for LeafNode { +impl Node for LeafNode { type Key = K; type Value = V; diff --git a/src/nodes/representation/header.rs b/src/nodes/representation/header.rs index 1e930817..d9ddbade 100644 --- a/src/nodes/representation/header.rs +++ b/src/nodes/representation/header.rs @@ -174,7 +174,10 @@ impl Header { ) -> ( &'a [u8], Option>>, - ) { + ) + where + N::Key: AsBytes, + { let len = self.prefix_len(); if likely!(len <= PREFIX_LEN) { (self.read_prefix(), None) diff --git a/src/nodes/representation/inner_node_256.rs b/src/nodes/representation/inner_node_256.rs index 3ac239b6..3b022ad9 100644 --- a/src/nodes/representation/inner_node_256.rs +++ b/src/nodes/representation/inner_node_256.rs @@ -1,6 +1,6 @@ use crate::{ - rust_nightly_apis::maybe_uninit_uninit_array, AsBytes, Header, InnerNode, InnerNode48, Node, - NodePtr, NodeType, OpaqueNodePtr, RestrictedNodeIndex, + rust_nightly_apis::maybe_uninit_uninit_array, Header, InnerNode, InnerNode48, Node, NodePtr, + NodeType, OpaqueNodePtr, RestrictedNodeIndex, }; use std::{ fmt, @@ -16,14 +16,14 @@ use std::{ /// Node that references between 49 and 256 children #[repr(C, align(8))] -pub struct InnerNode256 { +pub struct InnerNode256 { /// The common node fields. pub header: Header, /// An array that directly maps a key byte (as index) to a child node. pub child_pointers: [Option>; 256], } -impl fmt::Debug for InnerNode256 { +impl fmt::Debug for InnerNode256 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("InnerNode256") .field("header", &self.header) @@ -32,7 +32,7 @@ impl fmt::Debug for InnerNode256 Clone for InnerNode256 { +impl Clone for InnerNode256 { fn clone(&self) -> Self { Self { header: self.header.clone(), @@ -41,16 +41,14 @@ impl Clone for InnerNode256 Node for InnerNode256 { +impl Node for InnerNode256 { type Key = K; type Value = V; const TYPE: NodeType = NodeType::Node256; } -impl InnerNode - for InnerNode256 -{ +impl InnerNode for InnerNode256 { type GrownNode = Self; #[cfg(not(feature = "nightly"))] type Iter<'a> = Node256Iter<'a, K, V, PREFIX_LEN> where Self: 'a; @@ -144,8 +142,7 @@ impl InnerNode fn range( &self, bound: impl std::ops::RangeBounds, - ) -> impl Iterator)> - + DoubleEndedIterator + ) -> impl DoubleEndedIterator)> + FusedIterator { let start = bound.start_bound().map(|val| usize::from(*val)); let key_offset = match bound.start_bound() { @@ -155,7 +152,7 @@ impl InnerNode }; let end = bound.end_bound().map(|val| usize::from(*val)); - (&self.child_pointers[(start, end)]) + self.child_pointers[(start, end)] .iter() .enumerate() .filter_map(move |(key, child)| { @@ -293,12 +290,12 @@ impl InnerNode /// TODO #[cfg(not(feature = "nightly"))] -pub struct Node256Iter<'a, K: AsBytes, V, const PREFIX_LEN: usize> { +pub struct Node256Iter<'a, K, V, const PREFIX_LEN: usize> { pub(crate) it: Enumerate>>>, } #[cfg(not(feature = "nightly"))] -impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> Iterator for Node256Iter<'a, K, V, PREFIX_LEN> { +impl<'a, K, V, const PREFIX_LEN: usize> Iterator for Node256Iter<'a, K, V, PREFIX_LEN> { type Item = (u8, OpaqueNodePtr); fn next(&mut self) -> Option { @@ -313,9 +310,7 @@ impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> Iterator for Node256Iter<'a, K, } #[cfg(not(feature = "nightly"))] -impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> DoubleEndedIterator - for Node256Iter<'a, K, V, PREFIX_LEN> -{ +impl<'a, K, V, const PREFIX_LEN: usize> DoubleEndedIterator for Node256Iter<'a, K, V, PREFIX_LEN> { fn next_back(&mut self) -> Option { while let Some((key, node)) = self.it.next_back() { match node { @@ -328,10 +323,7 @@ impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> DoubleEndedIterator } #[cfg(not(feature = "nightly"))] -impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> FusedIterator - for Node256Iter<'a, K, V, PREFIX_LEN> -{ -} +impl<'a, K, V, const PREFIX_LEN: usize> FusedIterator for Node256Iter<'a, K, V, PREFIX_LEN> {} #[cfg(test)] mod tests { diff --git a/src/nodes/representation/inner_node_48.rs b/src/nodes/representation/inner_node_48.rs index 1db6ad77..725626b4 100644 --- a/src/nodes/representation/inner_node_48.rs +++ b/src/nodes/representation/inner_node_48.rs @@ -3,8 +3,8 @@ use crate::{ assume, maybe_uninit_slice_assume_init_mut, maybe_uninit_slice_assume_init_ref, maybe_uninit_uninit_array, }, - AsBytes, Header, InnerNode, InnerNode16, InnerNode256, InnerNodeCompressed, Node, NodePtr, - NodeType, OpaqueNodePtr, + Header, InnerNode, InnerNode16, InnerNode256, InnerNodeCompressed, Node, NodePtr, NodeType, + OpaqueNodePtr, }; use std::{ cmp::Ordering, @@ -102,7 +102,7 @@ impl Error for TryFromByteError {} /// Node that references between 17 and 49 children #[repr(C, align(8))] -pub struct InnerNode48 { +pub struct InnerNode48 { /// The common node fields. pub header: Header, /// An array that maps key bytes (as the index) to the index value in @@ -117,7 +117,7 @@ pub struct InnerNode48 { pub child_pointers: [MaybeUninit>; 48], } -impl fmt::Debug for InnerNode48 { +impl fmt::Debug for InnerNode48 { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("InnerNode48") .field("header", &self.header) @@ -127,7 +127,7 @@ impl fmt::Debug for InnerNode48 Clone for InnerNode48 { +impl Clone for InnerNode48 { fn clone(&self) -> Self { Self { header: self.header.clone(), @@ -137,7 +137,7 @@ impl Clone for InnerNode48 InnerNode48 { +impl InnerNode48 { /// Return the initialized portions of the child pointer array. pub fn initialized_child_pointers(&self) -> &[OpaqueNodePtr] { unsafe { @@ -149,16 +149,14 @@ impl InnerNode48 { } } -impl Node for InnerNode48 { +impl Node for InnerNode48 { type Key = K; type Value = V; const TYPE: NodeType = NodeType::Node48; } -impl InnerNode - for InnerNode48 -{ +impl InnerNode for InnerNode48 { type GrownNode = InnerNode256; #[cfg(not(feature = "nightly"))] type Iter<'a> = Node48Iter<'a, K, V, PREFIX_LEN> where Self: 'a; @@ -378,8 +376,7 @@ impl InnerNode fn range( &self, bound: impl std::ops::RangeBounds, - ) -> impl Iterator)> - + DoubleEndedIterator + ) -> impl DoubleEndedIterator)> + FusedIterator { let child_pointers = self.initialized_child_pointers(); @@ -391,7 +388,7 @@ impl InnerNode }; let end = bound.end_bound().map(|val| usize::from(*val)); - (&self.child_indices[(start, end)]) + self.child_indices[(start, end)] .iter() .enumerate() .filter_map(|(key, idx)| { @@ -565,13 +562,13 @@ impl InnerNode /// TODO #[cfg(not(feature = "nightly"))] -pub struct Node48Iter<'a, K: AsBytes, V, const PREFIX_LEN: usize> { +pub struct Node48Iter<'a, K, V, const PREFIX_LEN: usize> { pub(crate) it: Enumerate>>, pub(crate) child_pointers: &'a [OpaqueNodePtr], } #[cfg(not(feature = "nightly"))] -impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> Iterator for Node48Iter<'a, K, V, PREFIX_LEN> { +impl<'a, K, V, const PREFIX_LEN: usize> Iterator for Node48Iter<'a, K, V, PREFIX_LEN> { type Item = (u8, OpaqueNodePtr); fn next(&mut self) -> Option { @@ -590,9 +587,7 @@ impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> Iterator for Node48Iter<'a, K, } #[cfg(not(feature = "nightly"))] -impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> DoubleEndedIterator - for Node48Iter<'a, K, V, PREFIX_LEN> -{ +impl<'a, K, V, const PREFIX_LEN: usize> DoubleEndedIterator for Node48Iter<'a, K, V, PREFIX_LEN> { fn next_back(&mut self) -> Option { while let Some((key, idx)) = self.it.next_back() { if idx.is_empty() { @@ -609,10 +604,7 @@ impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> DoubleEndedIterator } #[cfg(not(feature = "nightly"))] -impl<'a, K: AsBytes, V, const PREFIX_LEN: usize> FusedIterator - for Node48Iter<'a, K, V, PREFIX_LEN> -{ -} +impl<'a, K, V, const PREFIX_LEN: usize> FusedIterator for Node48Iter<'a, K, V, PREFIX_LEN> {} #[cfg(test)] mod tests { diff --git a/src/nodes/representation/inner_node_compressed.rs b/src/nodes/representation/inner_node_compressed.rs index eacaaf85..56d86b32 100644 --- a/src/nodes/representation/inner_node_compressed.rs +++ b/src/nodes/representation/inner_node_compressed.rs @@ -1,7 +1,6 @@ use crate::{ rust_nightly_apis::{assume, maybe_uninit_slice_assume_init_ref, maybe_uninit_uninit_array}, - AsBytes, Header, InnerNode, InnerNode48, Node, NodePtr, NodeType, OpaqueNodePtr, - RestrictedNodeIndex, + Header, InnerNode, InnerNode48, Node, NodePtr, NodeType, OpaqueNodePtr, RestrictedNodeIndex, }; use std::{ fmt, @@ -39,7 +38,7 @@ trait SearchInnerNodeCompressed { /// Node type that has a compact representation for key bytes and children /// pointers. #[repr(C, align(8))] -pub struct InnerNodeCompressed { +pub struct InnerNodeCompressed { /// The common node fields. pub header: Header, /// An array that contains single key bytes in the same index as the @@ -55,7 +54,7 @@ pub struct InnerNodeCompressed>; SIZE], } -impl Clone +impl Clone for InnerNodeCompressed { fn clone(&self) -> Self { @@ -67,7 +66,7 @@ impl Clone } } -impl fmt::Debug +impl fmt::Debug for InnerNodeCompressed { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -85,9 +84,7 @@ impl fmt::Debug pub type InnerNodeCompressedIter<'a, K, V, const PREFIX_LEN: usize> = Zip>, Copied>>>; -impl - InnerNodeCompressed -{ +impl InnerNodeCompressed { /// Return the initialized portions of the keys and child pointer arrays. pub fn initialized_portion(&self) -> (&[u8], &[OpaqueNodePtr]) { // SAFETY: The array prefix with length `header.num_children` is guaranteed to @@ -382,9 +379,7 @@ impl /// Node that references between 2 and 4 children pub type InnerNode4 = InnerNodeCompressed; -impl SearchInnerNodeCompressed - for InnerNode4 -{ +impl SearchInnerNodeCompressed for InnerNode4 { fn lookup_child_index(&self, key_fragment: u8) -> Option { let (keys, _) = self.initialized_portion(); for (child_index, key) in keys.iter().enumerate() { @@ -413,16 +408,14 @@ impl SearchInnerNodeCompressed } } -impl Node for InnerNode4 { +impl Node for InnerNode4 { type Key = K; type Value = V; const TYPE: NodeType = NodeType::Node4; } -impl InnerNode - for InnerNode4 -{ +impl InnerNode for InnerNode4 { type GrownNode = InnerNode16; type Iter<'a> = InnerNodeCompressedIter<'a, K, V, PREFIX_LEN> where Self: 'a; type ShrunkNode = InnerNode4; @@ -466,8 +459,7 @@ impl InnerNode fn range( &self, bound: impl RangeBounds, - ) -> impl Iterator)> - + DoubleEndedIterator + ) -> impl DoubleEndedIterator)> + std::iter::FusedIterator { self.inner_range_iter(bound) } @@ -507,9 +499,7 @@ impl InnerNode /// Node that references between 5 and 16 children pub type InnerNode16 = InnerNodeCompressed; -impl SearchInnerNodeCompressed - for InnerNode16 -{ +impl SearchInnerNodeCompressed for InnerNode16 { #[cfg(feature = "nightly")] fn lookup_child_index(&self, key_fragment: u8) -> Option { // SAFETY: Even though the type is marked is uninit data, when @@ -581,16 +571,14 @@ impl SearchInnerNodeCompressed } } -impl Node for InnerNode16 { +impl Node for InnerNode16 { type Key = K; type Value = V; const TYPE: NodeType = NodeType::Node16; } -impl InnerNode - for InnerNode16 -{ +impl InnerNode for InnerNode16 { type GrownNode = InnerNode48; type Iter<'a> = InnerNodeCompressedIter<'a, K, V, PREFIX_LEN> where Self: 'a; type ShrunkNode = InnerNode4; @@ -634,8 +622,7 @@ impl InnerNode fn range( &self, bound: impl RangeBounds, - ) -> impl Iterator)> - + DoubleEndedIterator + ) -> impl DoubleEndedIterator)> + std::iter::FusedIterator { self.inner_range_iter(bound) } diff --git a/src/nodes/visitor.rs b/src/nodes/visitor.rs index 49773414..d9196e92 100644 --- a/src/nodes/visitor.rs +++ b/src/nodes/visitor.rs @@ -5,8 +5,8 @@ mod tree_stats; mod well_formed; use crate::{ - AsBytes, ConcreteNodePtr, InnerNode, InnerNode16, InnerNode256, InnerNode4, InnerNode48, - LeafNode, Node, NodePtr, OpaqueNodePtr, + ConcreteNodePtr, InnerNode, InnerNode16, InnerNode256, InnerNode4, InnerNode48, LeafNode, Node, + NodePtr, OpaqueNodePtr, }; pub use pretty_printer::*; pub use tree_stats::*; @@ -14,7 +14,7 @@ pub use well_formed::*; /// The `Visitable` trait allows [`Visitor`]s to traverse the structure of the /// implementing type and produce some output. -pub trait Visitable { +pub trait Visitable { /// This function provides the default traversal behavior for the /// implementing type. /// @@ -47,7 +47,7 @@ pub trait Visitable { } } -impl Visitable +impl Visitable for OpaqueNodePtr { fn super_visit_with>(&self, visitor: &mut V) -> V::Output { @@ -61,7 +61,7 @@ impl Visitable } } -impl + Visitable> +impl + Visitable> Visitable for NodePtr { fn super_visit_with>(&self, visitor: &mut V) -> V::Output { @@ -70,9 +70,7 @@ impl + Visitable Visitable - for InnerNode4 -{ +impl Visitable for InnerNode4 { fn super_visit_with>(&self, visitor: &mut V) -> V::Output { combine_inner_node_child_output(self.iter(), visitor) } @@ -82,9 +80,7 @@ impl Visitable } } -impl Visitable - for InnerNode16 -{ +impl Visitable for InnerNode16 { fn super_visit_with>(&self, visitor: &mut V) -> V::Output { combine_inner_node_child_output(self.iter(), visitor) } @@ -94,9 +90,7 @@ impl Visitable } } -impl Visitable - for InnerNode48 -{ +impl Visitable for InnerNode48 { fn super_visit_with>(&self, visitor: &mut V) -> V::Output { combine_inner_node_child_output(self.iter(), visitor) } @@ -106,9 +100,7 @@ impl Visitable } } -impl Visitable - for InnerNode256 -{ +impl Visitable for InnerNode256 { fn super_visit_with>(&self, visitor: &mut V) -> V::Output { combine_inner_node_child_output(self.iter(), visitor) } @@ -118,9 +110,7 @@ impl Visitable } } -impl Visitable - for LeafNode -{ +impl Visitable for LeafNode { fn super_visit_with>(&self, visitor: &mut V) -> V::Output { visitor.default_output() } @@ -132,7 +122,7 @@ impl Visitable /// The `Visitor` trait allows creating new operations on the radix tree by /// overriding specific handling methods for each of the node types. -pub trait Visitor: Sized { +pub trait Visitor: Sized { /// The type of value that the visitor produces. type Output; @@ -168,12 +158,7 @@ pub trait Visitor: Sized { } } -fn combine_inner_node_child_output< - K: AsBytes, - T, - const PREFIX_LEN: usize, - V: Visitor, ->( +fn combine_inner_node_child_output>( mut iter: impl Iterator)>, visitor: &mut V, ) -> V::Output {