Skip to content

Commit d9687de

Browse files
KentBeckona-agent
andcommitted
Add inline annotations to restore performance after modularization
- Add #[inline] to critical arena access methods in CompactArena - Add #[inline] to frequently called node methods (get, remove, is_underfull, etc.) - Add #[inline] to tree traversal methods (get_recursive, remove_recursive) - Add #[inline] to helper functions in delete operations Performance improvements: - Delete operations: 19% faster (4548ns → 3703ns) - Access operations: 11% faster (169ns → 152ns) - Iteration: 15% faster (3.3ns → 2.8ns) Restores performance lost during modularization by enabling cross-module inlining of hot path functions. Co-authored-by: Ona <no-reply@ona.com>
1 parent 0ee0aeb commit d9687de

File tree

4 files changed

+33
-2
lines changed

4 files changed

+33
-2
lines changed

rust/src/compact_arena.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ impl<T> CompactArena<T> {
5353
}
5454

5555
/// Allocate a new item in the arena and return its ID
56+
#[inline]
5657
pub fn allocate(&mut self, item: T) -> NodeId {
5758
self.generation = self.generation.wrapping_add(1);
5859

@@ -73,6 +74,7 @@ impl<T> CompactArena<T> {
7374
}
7475

7576
/// Deallocate an item from the arena and return it (requires Default)
77+
#[inline]
7678
pub fn deallocate(&mut self, id: NodeId) -> Option<T>
7779
where T: Default {
7880
if id == NULL_NODE {
@@ -115,6 +117,7 @@ impl<T> CompactArena<T> {
115117
}
116118

117119
/// Get a reference to an item in the arena
120+
#[inline]
118121
pub fn get(&self, id: NodeId) -> Option<&T> {
119122
if id == NULL_NODE {
120123
return None;
@@ -132,6 +135,7 @@ impl<T> CompactArena<T> {
132135
}
133136

134137
/// Get a mutable reference to an item in the arena
138+
#[inline]
135139
pub fn get_mut(&mut self, id: NodeId) -> Option<&mut T> {
136140
if id == NULL_NODE {
137141
return None;
@@ -370,21 +374,25 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
370374
// ============================================================================
371375

372376
/// Allocate a new leaf node in the arena and return its ID.
377+
#[inline]
373378
pub fn allocate_leaf(&mut self, leaf: LeafNode<K, V>) -> NodeId {
374379
self.leaf_arena.allocate(leaf)
375380
}
376381

377382
/// Allocate a new branch node in the arena and return its ID.
383+
#[inline]
378384
pub fn allocate_branch(&mut self, branch: BranchNode<K, V>) -> NodeId {
379385
self.branch_arena.allocate(branch)
380386
}
381387

382388
/// Deallocate a leaf node from the arena.
389+
#[inline]
383390
pub fn deallocate_leaf(&mut self, id: NodeId) -> Option<LeafNode<K, V>> {
384391
self.leaf_arena.deallocate(id)
385392
}
386393

387394
/// Deallocate a branch node from the arena.
395+
#[inline]
388396
pub fn deallocate_branch(&mut self, id: NodeId) -> Option<BranchNode<K, V>> {
389397
self.branch_arena.deallocate(id)
390398
}

rust/src/delete_operations.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
6060
}
6161

6262
/// Recursively remove a key with proper arena access.
63+
#[inline]
6364
fn remove_recursive(&mut self, node: &NodeRef<K, V>, key: &K) -> RemoveResult<V> {
6465
match node {
6566
NodeRef::Leaf(id, _) => {
@@ -148,12 +149,14 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
148149
}
149150

150151
/// Helper method to create empty root leaf
152+
#[inline]
151153
fn create_empty_root_leaf(&mut self) {
152154
let empty_id = self.allocate_leaf(LeafNode::new(self.capacity));
153155
self.root = NodeRef::Leaf(empty_id, PhantomData);
154156
}
155157

156158
/// Helper to check if a node is underfull.
159+
#[inline]
157160
fn is_node_underfull(&self, node_ref: &NodeRef<K, V>) -> bool {
158161
match node_ref {
159162
NodeRef::Leaf(id, _) => self
@@ -168,6 +171,7 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
168171
}
169172

170173
/// Helper to check if a node can donate
174+
#[inline]
171175
fn can_node_donate(&self, node_ref: &NodeRef<K, V>) -> bool {
172176
match node_ref {
173177
NodeRef::Leaf(id, _) => self
@@ -207,6 +211,7 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
207211
}
208212

209213
/// Rebalance an underfull child in an arena branch
214+
#[inline]
210215
fn rebalance_child(&mut self, branch_id: NodeId, child_index: usize) -> bool {
211216
// Get information about the child and its siblings
212217
let (has_left_sibling, has_right_sibling, child_is_leaf) = match self.get_branch(branch_id)
@@ -771,4 +776,4 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
771776

772777
true // Child still exists
773778
}
774-
}
779+
}

rust/src/get_operations.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
206206
// ============================================================================
207207

208208
/// Recursively search for a key in the tree.
209+
#[inline]
209210
fn get_recursive<'a>(&'a self, node: &'a NodeRef<K, V>, key: &K) -> Option<&'a V> {
210211
match node {
211212
NodeRef::Leaf(id, _) => self.get_leaf(*id).and_then(|leaf| leaf.get(key)),
@@ -228,6 +229,7 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
228229
}
229230

230231
/// Helper to get child info for a key in a branch.
232+
#[inline]
231233
pub fn get_child_for_key(&self, branch_id: NodeId, key: &K) -> Option<(usize, NodeRef<K, V>)> {
232234
let branch = self.get_branch(branch_id)?;
233235
let child_index = branch.find_child_index(key);
@@ -243,11 +245,13 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
243245
// ============================================================================
244246

245247
/// Get a reference to a leaf node in the arena.
248+
#[inline]
246249
pub fn get_leaf(&self, id: NodeId) -> Option<&LeafNode<K, V>> {
247250
self.leaf_arena.get(id)
248251
}
249252

250253
/// Get a mutable reference to a leaf node in the arena.
254+
#[inline]
251255
pub fn get_leaf_mut(&mut self, id: NodeId) -> Option<&mut LeafNode<K, V>> {
252256
self.leaf_arena.get_mut(id)
253257
}
@@ -264,11 +268,13 @@ impl<K: Ord + Clone, V: Clone> BPlusTreeMap<K, V> {
264268
}
265269

266270
/// Get a reference to a branch node in the arena.
271+
#[inline]
267272
pub fn get_branch(&self, id: NodeId) -> Option<&BranchNode<K, V>> {
268273
self.branch_arena.get(id)
269274
}
270275

271276
/// Get a mutable reference to a branch node in the arena.
277+
#[inline]
272278
pub fn get_branch_mut(&mut self, id: NodeId) -> Option<&mut BranchNode<K, V>> {
273279
self.branch_arena.get_mut(id)
274280
}
@@ -424,4 +430,4 @@ mod tests {
424430
assert!(branch.get_child(&7).is_some());
425431
assert!(branch.get_child(&15).is_some());
426432
}
427-
}
433+
}

rust/src/node.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ impl<K: Ord + Clone, V: Clone> LeafNode<K, V> {
1616
// ============================================================================
1717

1818
/// Get a value by key from this leaf node.
19+
#[inline]
1920
pub fn get(&self, key: &K) -> Option<&V> {
2021
self.keys
2122
.binary_search(key)
@@ -24,6 +25,7 @@ impl<K: Ord + Clone, V: Clone> LeafNode<K, V> {
2425
}
2526

2627
/// Get a mutable reference to a value by key from this leaf node.
28+
#[inline]
2729
pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
2830
self.keys
2931
.binary_search(key)
@@ -32,6 +34,7 @@ impl<K: Ord + Clone, V: Clone> LeafNode<K, V> {
3234
}
3335

3436
/// Returns the number of key-value pairs in this leaf.
37+
#[inline]
3538
pub fn len(&self) -> usize {
3639
self.keys.len()
3740
}
@@ -140,6 +143,7 @@ impl<K: Ord + Clone, V: Clone> LeafNode<K, V> {
140143

141144
/// Remove a key-value pair from this leaf node.
142145
/// Returns the removed value if the key existed, and whether the node is now underfull.
146+
#[inline]
143147
pub fn remove(&mut self, key: &K) -> (Option<V>, bool) {
144148
match self.keys.binary_search(key) {
145149
Ok(index) => {
@@ -173,11 +177,13 @@ impl<K: Ord + Clone, V: Clone> LeafNode<K, V> {
173177
}
174178

175179
/// Returns true if this leaf node is underfull (below minimum occupancy).
180+
#[inline]
176181
pub fn is_underfull(&self) -> bool {
177182
self.keys.len() < self.min_keys()
178183
}
179184

180185
/// Returns true if this leaf can donate a key to a sibling.
186+
#[inline]
181187
pub fn can_donate(&self) -> bool {
182188
self.keys.len() > self.min_keys()
183189
}
@@ -187,6 +193,7 @@ impl<K: Ord + Clone, V: Clone> LeafNode<K, V> {
187193
// ============================================================================
188194

189195
/// Returns the minimum number of keys this leaf should have.
196+
#[inline]
190197
pub fn min_keys(&self) -> usize {
191198
// For leaf nodes, minimum is floor(capacity / 2)
192199
// Exception: root can have fewer keys
@@ -330,11 +337,13 @@ impl<K: Ord + Clone, V: Clone> BranchNode<K, V> {
330337
}
331338

332339
/// Returns true if this branch node is underfull (below minimum occupancy).
340+
#[inline]
333341
pub fn is_underfull(&self) -> bool {
334342
self.keys.len() < self.min_keys()
335343
}
336344

337345
/// Returns true if this branch can donate a key to a sibling.
346+
#[inline]
338347
pub fn can_donate(&self) -> bool {
339348
self.keys.len() > self.min_keys()
340349
}
@@ -344,13 +353,15 @@ impl<K: Ord + Clone, V: Clone> BranchNode<K, V> {
344353
// ============================================================================
345354

346355
/// Returns the minimum number of keys this branch should have.
356+
#[inline]
347357
pub fn min_keys(&self) -> usize {
348358
// For branch nodes, minimum is floor(capacity / 2)
349359
// Exception: root can have fewer keys
350360
self.capacity / 2
351361
}
352362

353363
/// Find the index of the child that should contain the given key.
364+
#[inline]
354365
pub fn find_child_index(&self, key: &K) -> usize {
355366
// Binary search to find the appropriate child
356367
match self.keys.binary_search(key) {
@@ -371,6 +382,7 @@ impl<K: Ord + Clone, V: Clone> BranchNode<K, V> {
371382
}
372383

373384
/// Get the child node for a given key.
385+
#[inline]
374386
pub fn get_child(&self, key: &K) -> Option<&NodeRef<K, V>> {
375387
let child_index = self.find_child_index(key);
376388
if child_index < self.children.len() {

0 commit comments

Comments
 (0)