1+ //! Core types and data structures for BPlusTreeMap.
2+ //!
3+ //! This module contains all the fundamental data structures, type definitions,
4+ //! and constants used throughout the B+ tree implementation.
5+
6+ use std:: marker:: PhantomData ;
7+ use crate :: compact_arena:: CompactArena ;
8+
9+ // ============================================================================
10+ // CONSTANTS
11+ // ============================================================================
12+
13+ /// Minimum capacity for any B+ tree node
14+ pub ( crate ) const MIN_CAPACITY : usize = 4 ;
15+
16+ // ============================================================================
17+ // TYPE DEFINITIONS
18+ // ============================================================================
19+
20+ /// Node ID type for arena-based allocation
21+ pub type NodeId = u32 ;
22+
23+ /// Special node ID constants
24+ pub const NULL_NODE : NodeId = u32:: MAX ;
25+ pub const ROOT_NODE : NodeId = 0 ;
26+
27+ // ============================================================================
28+ // CORE DATA STRUCTURES
29+ // ============================================================================
30+
31+ /// B+ Tree implementation with Rust dict-like API.
32+ ///
33+ /// A B+ tree is a self-balancing tree data structure that maintains sorted data
34+ /// and allows searches, sequential access, insertions, and deletions in O(log n).
35+ /// Unlike B trees, all values are stored in leaf nodes, making range queries
36+ /// and sequential access very efficient.
37+ ///
38+ /// # Type Parameters
39+ ///
40+ /// * `K` - Key type that must implement `Ord + Clone + Debug`
41+ /// * `V` - Value type that must implement `Clone + Debug`
42+ ///
43+ /// # Examples
44+ ///
45+ /// ```
46+ /// use bplustree::BPlusTreeMap;
47+ ///
48+ /// let mut tree = BPlusTreeMap::new(16).unwrap();
49+ /// tree.insert(1, "one");
50+ /// tree.insert(2, "two");
51+ /// tree.insert(3, "three");
52+ ///
53+ /// assert_eq!(tree.get(&2), Some(&"two"));
54+ /// assert_eq!(tree.len(), 3);
55+ ///
56+ /// // Range queries
57+ /// let range: Vec<_> = tree.items_range(Some(&1), Some(&3)).collect();
58+ /// assert_eq!(range, [(&1, &"one"), (&2, &"two")]);
59+ /// ```
60+ ///
61+ /// # Performance Characteristics
62+ ///
63+ /// - **Insertion**: O(log n)
64+ /// - **Lookup**: O(log n)
65+ /// - **Deletion**: O(log n)
66+ /// - **Range queries**: O(log n + k) where k is the number of items in range
67+ /// - **Iteration**: O(n)
68+ ///
69+ /// # Capacity Guidelines
70+ ///
71+ /// - Minimum capacity: 4 (enforced)
72+ /// - Recommended capacity: 16-128 depending on use case
73+ /// - Higher capacity = fewer tree levels but larger nodes
74+ /// - Lower capacity = more tree levels but smaller nodes
75+ #[ derive( Debug ) ]
76+ pub struct BPlusTreeMap < K , V > {
77+ /// Maximum number of keys per node.
78+ pub ( crate ) capacity : usize ,
79+ /// The root node of the tree.
80+ pub ( crate ) root : NodeRef < K , V > ,
81+
82+ // Compact arena-based allocation for better performance
83+ /// Compact arena storage for leaf nodes (eliminates Option wrapper overhead).
84+ pub ( crate ) leaf_arena : CompactArena < LeafNode < K , V > > ,
85+ /// Compact arena storage for branch nodes (eliminates Option wrapper overhead).
86+ pub ( crate ) branch_arena : CompactArena < BranchNode < K , V > > ,
87+ }
88+
89+ /// Leaf node containing key-value pairs.
90+ #[ derive( Debug , Clone ) ]
91+ pub struct LeafNode < K , V > {
92+ /// Maximum number of keys this node can hold.
93+ pub ( crate ) capacity : usize ,
94+ /// Sorted list of keys.
95+ pub ( crate ) keys : Vec < K > ,
96+ /// List of values corresponding to keys.
97+ pub ( crate ) values : Vec < V > ,
98+ /// Next leaf node in the linked list (for range queries).
99+ pub ( crate ) next : NodeId ,
100+ }
101+
102+ /// Internal (branch) node containing keys and child pointers.
103+ #[ derive( Debug , Clone ) ]
104+ pub struct BranchNode < K , V > {
105+ /// Maximum number of keys this node can hold.
106+ pub ( crate ) capacity : usize ,
107+ /// Sorted list of separator keys.
108+ pub ( crate ) keys : Vec < K > ,
109+ /// List of child nodes (leaves or other branches).
110+ pub ( crate ) children : Vec < NodeRef < K , V > > ,
111+ }
112+
113+ // ============================================================================
114+ // ENUMS AND RESULT TYPES
115+ // ============================================================================
116+
117+ /// Node reference that can be either a leaf or branch node
118+ #[ derive( Debug , Clone ) ]
119+ pub enum NodeRef < K , V > {
120+ Leaf ( NodeId , PhantomData < ( K , V ) > ) ,
121+ Branch ( NodeId , PhantomData < ( K , V ) > ) ,
122+ }
123+
124+ impl < K , V > NodeRef < K , V > {
125+ /// Return the raw node ID.
126+ pub fn id ( & self ) -> NodeId {
127+ match * self {
128+ NodeRef :: Leaf ( id, _) => id,
129+ NodeRef :: Branch ( id, _) => id,
130+ }
131+ }
132+
133+ /// Returns true if this reference points to a leaf node.
134+ pub fn is_leaf ( & self ) -> bool {
135+ matches ! ( self , NodeRef :: Leaf ( _, _) )
136+ }
137+ }
138+
139+ /// Node data that can be allocated in the arena after a split.
140+ pub enum SplitNodeData < K , V > {
141+ Leaf ( LeafNode < K , V > ) ,
142+ Branch ( BranchNode < K , V > ) ,
143+ }
144+
145+ /// Result of an insertion operation on a node.
146+ pub enum InsertResult < K , V > {
147+ /// Insertion completed without splitting. Contains the old value if key existed.
148+ Updated ( Option < V > ) ,
149+ /// Insertion caused a split with arena allocation needed.
150+ Split {
151+ old_value : Option < V > ,
152+ new_node_data : SplitNodeData < K , V > ,
153+ separator_key : K ,
154+ } ,
155+ /// Internal error occurred during insertion.
156+ Error ( crate :: error:: BPlusTreeError ) ,
157+ }
158+
159+ /// Result of a removal operation on a node.
160+ pub enum RemoveResult < V > {
161+ /// Removal completed. Contains the removed value if key existed.
162+ /// The bool indicates if this node is now underfull and needs rebalancing.
163+ Updated ( Option < V > , bool ) ,
164+ }
0 commit comments