1+ //! Construction and initialization logic for BPlusTreeMap and nodes.
2+ //!
3+ //! This module contains all the construction, initialization, and setup logic
4+ //! for the B+ tree and its nodes. This includes capacity validation,
5+ //! arena initialization, and default implementations.
6+
7+ use crate :: error:: { BPlusTreeError , BTreeResult } ;
8+ use crate :: types:: { BPlusTreeMap , LeafNode , BranchNode , NodeRef , MIN_CAPACITY , NULL_NODE } ;
9+ use crate :: compact_arena:: CompactArena ;
10+ use std:: marker:: PhantomData ;
11+
12+ /// Result type for initialization operations
13+ pub type InitResult < T > = BTreeResult < T > ;
14+
15+ /// Default capacity for B+ tree nodes
16+ pub const DEFAULT_CAPACITY : usize = 16 ;
17+
18+ impl < K , V > BPlusTreeMap < K , V > {
19+ /// Create a B+ tree with specified node capacity.
20+ ///
21+ /// # Arguments
22+ ///
23+ /// * `capacity` - Maximum number of keys per node (minimum 8)
24+ ///
25+ /// # Returns
26+ ///
27+ /// Returns `Ok(BPlusTreeMap)` if capacity is valid, `Err(BPlusTreeError)` otherwise.
28+ ///
29+ /// # Examples
30+ ///
31+ /// ```
32+ /// use bplustree::BPlusTreeMap;
33+ ///
34+ /// let tree = BPlusTreeMap::<i32, String>::new(16).unwrap();
35+ /// assert!(tree.is_empty());
36+ /// ```
37+ pub fn new ( capacity : usize ) -> InitResult < Self > {
38+ if capacity < MIN_CAPACITY {
39+ return Err ( BPlusTreeError :: invalid_capacity ( capacity, MIN_CAPACITY ) ) ;
40+ }
41+
42+ // Initialize compact arena with the first leaf at id=0
43+ let mut leaf_arena = CompactArena :: new ( ) ;
44+ let root_id = leaf_arena. allocate ( LeafNode :: new ( capacity) ) ;
45+
46+ // Initialize compact branch arena (starts empty)
47+ let branch_arena = CompactArena :: new ( ) ;
48+
49+ Ok ( Self {
50+ capacity,
51+ root : NodeRef :: Leaf ( root_id, PhantomData ) ,
52+ leaf_arena,
53+ branch_arena,
54+ } )
55+ }
56+
57+ /// Create a B+ tree with default capacity.
58+ ///
59+ /// This is equivalent to calling `new(DEFAULT_CAPACITY)`.
60+ ///
61+ /// # Examples
62+ ///
63+ /// ```
64+ /// use bplustree::BPlusTreeMap;
65+ ///
66+ /// let tree = BPlusTreeMap::<i32, String>::with_default_capacity().unwrap();
67+ /// assert_eq!(tree.capacity(), 16);
68+ /// ```
69+ pub fn with_default_capacity ( ) -> InitResult < Self > {
70+ Self :: new ( DEFAULT_CAPACITY )
71+ }
72+
73+ /// Create an empty B+ tree with specified capacity.
74+ ///
75+ /// Unlike `new()`, this creates a completely empty tree with no root node.
76+ /// This is useful for advanced use cases where you want to build the tree
77+ /// structure manually.
78+ ///
79+ /// # Arguments
80+ ///
81+ /// * `capacity` - Maximum number of keys per node (minimum 8)
82+ ///
83+ /// # Examples
84+ ///
85+ /// ```
86+ /// use bplustree::BPlusTreeMap;
87+ ///
88+ /// let tree = BPlusTreeMap::<i32, String>::empty(16).unwrap();
89+ /// assert!(tree.is_empty());
90+ /// assert!(tree.root().is_none());
91+ /// ```
92+ pub fn empty ( capacity : usize ) -> InitResult < Self > {
93+ if capacity < MIN_CAPACITY {
94+ return Err ( BPlusTreeError :: invalid_capacity ( capacity, MIN_CAPACITY ) ) ;
95+ }
96+
97+ // For empty tree, we still need a root - create an empty leaf
98+ let mut leaf_arena = CompactArena :: new ( ) ;
99+ let root_id = leaf_arena. allocate ( LeafNode :: new ( capacity) ) ;
100+
101+ Ok ( Self {
102+ capacity,
103+ root : NodeRef :: Leaf ( root_id, PhantomData ) ,
104+ leaf_arena,
105+ branch_arena : CompactArena :: new ( ) ,
106+ } )
107+ }
108+ }
109+
110+ impl < K , V > LeafNode < K , V > {
111+ /// Creates a new leaf node with the specified capacity.
112+ ///
113+ /// # Arguments
114+ ///
115+ /// * `capacity` - Maximum number of keys this node can hold
116+ ///
117+ /// # Examples
118+ ///
119+ /// ```
120+ /// use bplustree::LeafNode;
121+ ///
122+ /// let leaf: LeafNode<i32, String> = LeafNode::new(16);
123+ /// assert!(leaf.is_empty());
124+ /// assert_eq!(leaf.capacity(), 16);
125+ /// ```
126+ pub fn new ( capacity : usize ) -> Self {
127+ Self {
128+ capacity,
129+ keys : Vec :: new ( ) ,
130+ values : Vec :: new ( ) ,
131+ next : NULL_NODE ,
132+ }
133+ }
134+
135+ /// Creates a new leaf node with default capacity.
136+ ///
137+ /// # Examples
138+ ///
139+ /// ```
140+ /// use bplustree::LeafNode;
141+ ///
142+ /// let leaf: LeafNode<i32, String> = LeafNode::with_default_capacity();
143+ /// assert_eq!(leaf.capacity(), 16);
144+ /// ```
145+ pub fn with_default_capacity ( ) -> Self {
146+ Self :: new ( DEFAULT_CAPACITY )
147+ }
148+
149+ /// Creates a new leaf node with pre-allocated capacity.
150+ ///
151+ /// This pre-allocates the internal vectors to the specified capacity,
152+ /// which can improve performance when you know the expected size.
153+ ///
154+ /// # Arguments
155+ ///
156+ /// * `capacity` - Maximum number of keys this node can hold
157+ ///
158+ /// # Examples
159+ ///
160+ /// ```
161+ /// use bplustree::LeafNode;
162+ ///
163+ /// let leaf: LeafNode<i32, String> = LeafNode::with_reserved_capacity(16);
164+ /// assert_eq!(leaf.keys().capacity(), 16);
165+ /// ```
166+ pub fn with_reserved_capacity ( capacity : usize ) -> Self {
167+ Self {
168+ capacity,
169+ keys : Vec :: with_capacity ( capacity) ,
170+ values : Vec :: with_capacity ( capacity) ,
171+ next : NULL_NODE ,
172+ }
173+ }
174+ }
175+
176+ impl < K , V > BranchNode < K , V > {
177+ /// Creates a new branch node with the specified capacity.
178+ ///
179+ /// # Arguments
180+ ///
181+ /// * `capacity` - Maximum number of keys this node can hold
182+ ///
183+ /// # Examples
184+ ///
185+ /// ```
186+ /// use bplustree::BranchNode;
187+ ///
188+ /// let branch: BranchNode<i32, String> = BranchNode::new(16);
189+ /// assert!(branch.is_empty());
190+ /// assert_eq!(branch.capacity(), 16);
191+ /// ```
192+ pub fn new ( capacity : usize ) -> Self {
193+ Self {
194+ capacity,
195+ keys : Vec :: new ( ) ,
196+ children : Vec :: new ( ) ,
197+ }
198+ }
199+
200+ /// Creates a new branch node with default capacity.
201+ ///
202+ /// # Examples
203+ ///
204+ /// ```
205+ /// use bplustree::BranchNode;
206+ ///
207+ /// let branch: BranchNode<i32, String> = BranchNode::with_default_capacity();
208+ /// assert_eq!(branch.capacity(), 16);
209+ /// ```
210+ pub fn with_default_capacity ( ) -> Self {
211+ Self :: new ( DEFAULT_CAPACITY )
212+ }
213+
214+ /// Creates a new branch node with pre-allocated capacity.
215+ ///
216+ /// This pre-allocates the internal vectors to the specified capacity,
217+ /// which can improve performance when you know the expected size.
218+ ///
219+ /// # Arguments
220+ ///
221+ /// * `capacity` - Maximum number of keys this node can hold
222+ ///
223+ /// # Examples
224+ ///
225+ /// ```
226+ /// use bplustree::BranchNode;
227+ ///
228+ /// let branch: BranchNode<i32, String> = BranchNode::with_reserved_capacity(16);
229+ /// assert_eq!(branch.keys().capacity(), 16);
230+ /// ```
231+ pub fn with_reserved_capacity ( capacity : usize ) -> Self {
232+ Self {
233+ capacity,
234+ keys : Vec :: with_capacity ( capacity) ,
235+ children : Vec :: with_capacity ( capacity + 1 ) , // Branch nodes have one more child than keys
236+ }
237+ }
238+ }
239+
240+ // Default implementations
241+ impl < K : Ord + Clone , V : Clone > Default for BPlusTreeMap < K , V > {
242+ /// Create a B+ tree with default capacity.
243+ fn default ( ) -> Self {
244+ Self :: with_default_capacity ( ) . unwrap ( )
245+ }
246+ }
247+
248+ impl < K , V > Default for LeafNode < K , V > {
249+ /// Create a leaf node with default capacity.
250+ fn default ( ) -> Self {
251+ Self :: with_default_capacity ( )
252+ }
253+ }
254+
255+ impl < K , V > Default for BranchNode < K , V > {
256+ /// Create a branch node with default capacity.
257+ fn default ( ) -> Self {
258+ Self :: with_default_capacity ( )
259+ }
260+ }
261+
262+ /// Validation utilities for construction
263+ pub mod validation {
264+ use super :: * ;
265+
266+ /// Validate that a capacity is suitable for B+ tree nodes.
267+ ///
268+ /// # Arguments
269+ ///
270+ /// * `capacity` - The capacity to validate
271+ ///
272+ /// # Returns
273+ ///
274+ /// Returns `Ok(())` if valid, `Err(BPlusTreeError)` otherwise.
275+ pub fn validate_capacity ( capacity : usize ) -> BTreeResult < ( ) > {
276+ if capacity < MIN_CAPACITY {
277+ Err ( BPlusTreeError :: invalid_capacity ( capacity, MIN_CAPACITY ) )
278+ } else {
279+ Ok ( ( ) )
280+ }
281+ }
282+
283+ /// Get the recommended capacity for a given expected number of elements.
284+ ///
285+ /// This uses heuristics to suggest an optimal node capacity based on
286+ /// the expected tree size.
287+ ///
288+ /// # Arguments
289+ ///
290+ /// * `expected_elements` - Expected number of elements in the tree
291+ ///
292+ /// # Returns
293+ ///
294+ /// Recommended capacity (always >= MIN_CAPACITY)
295+ pub fn recommended_capacity ( expected_elements : usize ) -> usize {
296+ if expected_elements < 100 {
297+ MIN_CAPACITY
298+ } else if expected_elements < 10_000 {
299+ 16
300+ } else if expected_elements < 1_000_000 {
301+ 32
302+ } else {
303+ 64
304+ }
305+ }
306+ }
307+
308+ #[ cfg( test) ]
309+ mod tests {
310+ use super :: * ;
311+
312+ #[ test]
313+ fn test_btree_construction ( ) {
314+ let tree = BPlusTreeMap :: < i32 , String > :: new ( 16 ) . unwrap ( ) ;
315+ assert_eq ! ( tree. capacity, 16 ) ;
316+ // Note: is_empty() and len() methods need to be implemented in the main module
317+ }
318+
319+ #[ test]
320+ fn test_btree_invalid_capacity ( ) {
321+ let result = BPlusTreeMap :: < i32 , String > :: new ( 2 ) ; // Below MIN_CAPACITY (4)
322+ assert ! ( result. is_err( ) ) ;
323+ // Note: is_capacity_error() method needs to be implemented in error module
324+ }
325+
326+ #[ test]
327+ fn test_btree_default ( ) {
328+ let tree = BPlusTreeMap :: < i32 , String > :: default ( ) ;
329+ assert_eq ! ( tree. capacity, DEFAULT_CAPACITY ) ;
330+ }
331+
332+ #[ test]
333+ fn test_btree_empty ( ) {
334+ let tree = BPlusTreeMap :: < i32 , String > :: empty ( 16 ) . unwrap ( ) ;
335+ // Note: is_empty() method needs to be implemented in the main module
336+ // For now, just check that it was created successfully
337+ assert_eq ! ( tree. capacity, 16 ) ;
338+ }
339+
340+ #[ test]
341+ fn test_leaf_construction ( ) {
342+ let leaf = LeafNode :: < i32 , String > :: new ( 16 ) ;
343+ assert_eq ! ( leaf. capacity, 16 ) ;
344+ assert ! ( leaf. keys. is_empty( ) ) ;
345+ }
346+
347+ #[ test]
348+ fn test_leaf_with_reserved_capacity ( ) {
349+ let leaf = LeafNode :: < i32 , String > :: with_reserved_capacity ( 16 ) ;
350+ // Note: We can't directly test Vec capacity without accessing private fields
351+ assert_eq ! ( leaf. capacity, 16 ) ;
352+ }
353+
354+ #[ test]
355+ fn test_branch_construction ( ) {
356+ let branch = BranchNode :: < i32 , String > :: new ( 16 ) ;
357+ assert_eq ! ( branch. capacity, 16 ) ;
358+ assert ! ( branch. keys. is_empty( ) ) ;
359+ }
360+
361+ #[ test]
362+ fn test_validation ( ) {
363+ assert ! ( validation:: validate_capacity( 16 ) . is_ok( ) ) ;
364+ assert ! ( validation:: validate_capacity( 4 ) . is_ok( ) ) ; // MIN_CAPACITY is 4
365+ assert ! ( validation:: validate_capacity( 2 ) . is_err( ) ) ; // Below MIN_CAPACITY
366+ }
367+
368+ #[ test]
369+ fn test_recommended_capacity ( ) {
370+ assert_eq ! ( validation:: recommended_capacity( 50 ) , MIN_CAPACITY ) ;
371+ assert_eq ! ( validation:: recommended_capacity( 5000 ) , 16 ) ;
372+ assert_eq ! ( validation:: recommended_capacity( 500_000 ) , 32 ) ;
373+ assert_eq ! ( validation:: recommended_capacity( 5_000_000 ) , 64 ) ;
374+ }
375+ }
0 commit comments