Skip to content

Commit 8650404

Browse files
committed
nav: centralize find_leaf_for_key in tree_structure; refactor get/get_mut to use it; inline for hot path
1 parent d7ca26e commit 8650404

File tree

3 files changed

+60
-68
lines changed

3 files changed

+60
-68
lines changed

rust/src/get_operations.rs

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,16 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
3232
/// assert_eq!(tree.get(&2), None);
3333
/// ```
3434
pub fn get(&self, key: &K) -> Option<&V> {
35-
let node = &self.root;
36-
self.get_recursive(node, key)
35+
let (leaf_id, index) = self.find_leaf_for_key(key)?;
36+
let leaf = self.get_leaf(leaf_id)?;
37+
if index < leaf.keys_len() {
38+
if let Some(k) = leaf.get_key(index) {
39+
if k == key {
40+
return leaf.get_value(index);
41+
}
42+
}
43+
}
44+
None
3745
}
3846

3947
/// Check if key exists in the tree.
@@ -133,8 +141,16 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
133141
/// assert_eq!(tree.get(&1), Some(&"ONE"));
134142
/// ```
135143
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
136-
let root = self.root;
137-
self.get_mut_recursive(&root, key)
144+
let (leaf_id, index) = self.find_leaf_for_key(key)?;
145+
let leaf = self.get_leaf_mut(leaf_id)?;
146+
if index < leaf.keys_len() {
147+
if let Some(k) = leaf.get_key(index) {
148+
if k == key {
149+
return leaf.get_value_mut(index);
150+
}
151+
}
152+
}
153+
None
138154
}
139155

140156
/// Try to get a value, returning detailed error context on failure.
@@ -204,28 +220,7 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
204220
// PRIVATE HELPER METHODS FOR GET OPERATIONS
205221
// ============================================================================
206222

207-
/// Recursively search for a key in the tree.
208-
#[inline]
209-
fn get_recursive<'a>(&'a self, node: &'a NodeRef<K, V>, key: &K) -> Option<&'a V> {
210-
match node {
211-
NodeRef::Leaf(id, _) => self.get_leaf(*id).and_then(|leaf| leaf.get(key)),
212-
NodeRef::Branch(id, _) => self
213-
.get_branch(*id)
214-
.and_then(|branch| branch.get_child(key))
215-
.and_then(|child| self.get_recursive(child, key)),
216-
}
217-
}
218-
219-
/// Get mutable reference recursively.
220-
fn get_mut_recursive(&mut self, node: &NodeRef<K, V>, key: &K) -> Option<&mut V> {
221-
match node {
222-
NodeRef::Leaf(id, _) => self.get_leaf_mut(*id).and_then(|leaf| leaf.get_mut(key)),
223-
NodeRef::Branch(id, _) => {
224-
let (_child_index, child_ref) = self.get_child_for_key(*id, key)?;
225-
self.get_mut_recursive(&child_ref, key)
226-
}
227-
}
228-
}
223+
// Removed old recursive get helpers in favor of direct leaf-position lookup
229224

230225
/// Helper to get child info for a key in a branch.
231226
#[inline]

rust/src/range_queries.rs

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! bounds resolution, and range optimization algorithms.
55
66
use crate::iteration::RangeIterator;
7-
use crate::types::{BPlusTreeMap, NodeId, NodeRef};
7+
use crate::types::{BPlusTreeMap, NodeId};
88
use std::ops::{Bound, RangeBounds};
99

1010
/// Type alias for complex range analysis result
@@ -75,8 +75,8 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
7575
{
7676
// Optimize start bound resolution - eliminate redundant Option handling
7777
let (start_info, skip_first) = match range.start_bound() {
78-
Bound::Included(key) => (self.find_range_start(key), false),
79-
Bound::Excluded(key) => (self.find_range_start(key), true),
78+
Bound::Included(key) => (self.find_leaf_for_key(key), false),
79+
Bound::Excluded(key) => (self.find_leaf_for_key(key), true),
8080
Bound::Unbounded => (self.get_first_leaf_id().map(|id| (id, 0)), false),
8181
};
8282

@@ -90,45 +90,6 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
9090
(start_info, skip_first, end_info)
9191
}
9292

93-
/// Find the starting position for a range query.
94-
fn find_range_start(&self, key: &K) -> Option<(NodeId, usize)> {
95-
self.find_leaf_for_key(key)
96-
}
97-
98-
/// Find the leaf node and index where a key should be located.
99-
fn find_leaf_for_key(&self, key: &K) -> Option<(NodeId, usize)> {
100-
let mut current = &self.root;
101-
102-
loop {
103-
match current {
104-
NodeRef::Leaf(leaf_id, _) => {
105-
if let Some(leaf) = self.get_leaf(*leaf_id) {
106-
// Find the position where this key would be inserted
107-
let index = match leaf.binary_search_keys(key) {
108-
Ok(idx) => idx, // Key found at exact position
109-
Err(idx) => idx, // Key would be inserted at this position
110-
};
111-
return Some((*leaf_id, index));
112-
} else {
113-
return None;
114-
}
115-
}
116-
NodeRef::Branch(branch_id, _) => {
117-
if let Some(branch) = self.get_branch(*branch_id) {
118-
let child_index = branch.find_child_index(key);
119-
if let Some(child) = branch.children.get(child_index) {
120-
current = child;
121-
} else {
122-
return None;
123-
}
124-
} else {
125-
return None;
126-
}
127-
}
128-
}
129-
}
130-
}
131-
13293
// ============================================================================
13394
// RANGE OPTIMIZATION HELPERS
13495
// ============================================================================

rust/src/tree_structure.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,42 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
138138
}
139139
}
140140

141+
/// Find the leaf node and index where a key should be located.
142+
/// Returns the leaf `NodeId` and the insertion index within that leaf.
143+
#[inline]
144+
pub(crate) fn find_leaf_for_key(&self, key: &K) -> Option<(NodeId, usize)> {
145+
let mut current = &self.root;
146+
147+
loop {
148+
match current {
149+
NodeRef::Leaf(leaf_id, _) => {
150+
if let Some(leaf) = self.get_leaf(*leaf_id) {
151+
// Find the position where this key would be inserted
152+
let index = match leaf.binary_search_keys(key) {
153+
Ok(idx) => idx, // Key found at exact position
154+
Err(idx) => idx, // Key would be inserted at this position
155+
};
156+
return Some((*leaf_id, index));
157+
} else {
158+
return None;
159+
}
160+
}
161+
NodeRef::Branch(branch_id, _) => {
162+
if let Some(branch) = self.get_branch(*branch_id) {
163+
let child_index = branch.find_child_index(key);
164+
if let Some(child) = branch.children.get(child_index) {
165+
current = child;
166+
} else {
167+
return None;
168+
}
169+
} else {
170+
return None;
171+
}
172+
}
173+
}
174+
}
175+
}
176+
141177
// Arena statistics and management methods moved to arena.rs module
142178

143179
// ============================================================================

0 commit comments

Comments
 (0)