From 5c28d02d0bb47171a1922ffa03bafcda5d995d00 Mon Sep 17 00:00:00 2001 From: Maksym Arutyunyan Date: Wed, 4 Jun 2025 14:41:36 +0200 Subject: [PATCH 1/4] optimize swapping value --- src/btreemap.rs | 14 ++++++-------- src/btreemap/node.rs | 9 +++++++++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/btreemap.rs b/src/btreemap.rs index b0a86620..25164ddf 100644 --- a/src/btreemap.rs +++ b/src/btreemap.rs @@ -506,8 +506,8 @@ where // Check if the key already exists in the root. if let Ok(idx) = root.search(&key, self.memory()) { - // The key exists. Overwrite it and return the previous value. - let (_, previous_value) = root.swap_entry(idx, (key, value), self.memory()); + // Key found, replace its value and return the old one. + let previous_value = root.swap_value(idx, value, self.memory()); self.save_node(&mut root); return Some(V::from_bytes(Cow::Owned(previous_value))); } @@ -550,9 +550,8 @@ where // Look for the key in the node. match node.search(&key, self.memory()) { Ok(idx) => { - // The key is already in the node. - // Overwrite it and return the previous value. - let (_, previous_value) = node.swap_entry(idx, (key, value), self.memory()); + // Key found, replace its value and return the old one. + let previous_value = node.swap_value(idx, value, self.memory()); self.save_node(&mut node); Some(previous_value) @@ -582,9 +581,8 @@ where if child.is_full() { // Check if the key already exists in the child. if let Ok(idx) = child.search(&key, self.memory()) { - // The key exists. Overwrite it and return the previous value. - let (_, previous_value) = - child.swap_entry(idx, (key, value), self.memory()); + // Key found, replace its value and return the old one. + let previous_value = child.swap_value(idx, value, self.memory()); self.save_node(&mut child); return Some(previous_value); } diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index d4096918..d01b8c38 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -156,6 +156,15 @@ impl Node { self.keys_and_encoded_values.len() >= CAPACITY } + /// Replaces the value at `idx` and returns the old one. + pub fn swap_value(&mut self, idx: usize, new: Vec, memory: &M) -> Vec { + let old = core::mem::replace( + &mut self.keys_and_encoded_values[idx].1, + LazyValue::by_value(new), + ); + self.extract_value(old, memory) + } + /// Swaps the entry at index `idx` with the given entry, returning the old entry. pub fn swap_entry( &mut self, From 784634f6e2ea0a8ab22ed1c06000cc8811c69ccf Mon Sep 17 00:00:00 2001 From: Maksym Arutyunyan Date: Wed, 4 Jun 2025 14:57:34 +0200 Subject: [PATCH 2/4] . --- src/btreemap.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/btreemap.rs b/src/btreemap.rs index 25164ddf..794c2c4c 100644 --- a/src/btreemap.rs +++ b/src/btreemap.rs @@ -507,9 +507,9 @@ where // Check if the key already exists in the root. if let Ok(idx) = root.search(&key, self.memory()) { // Key found, replace its value and return the old one. - let previous_value = root.swap_value(idx, value, self.memory()); - self.save_node(&mut root); - return Some(V::from_bytes(Cow::Owned(previous_value))); + return Some(V::from_bytes(Cow::Owned( + self.swap_value(&mut root, idx, value), + ))); } // If the root is full, we need to introduce a new node as the root. @@ -551,10 +551,7 @@ where match node.search(&key, self.memory()) { Ok(idx) => { // Key found, replace its value and return the old one. - let previous_value = node.swap_value(idx, value, self.memory()); - - self.save_node(&mut node); - Some(previous_value) + Some(self.swap_value(&mut node, idx, value)) } Err(idx) => { // The key isn't in the node. `idx` is where that key should be inserted. @@ -582,9 +579,7 @@ where // Check if the key already exists in the child. if let Ok(idx) = child.search(&key, self.memory()) { // Key found, replace its value and return the old one. - let previous_value = child.swap_value(idx, value, self.memory()); - self.save_node(&mut child); - return Some(previous_value); + return Some(self.swap_value(&mut child, idx, value)); } // The child is full. Split the child. @@ -1279,6 +1274,12 @@ where node.save(self.allocator_mut()); } + fn swap_value(&mut self, node: &mut Node, idx: usize, new_value: Vec) -> Vec { + let old_value = node.swap_value(idx, new_value, self.memory()); + self.save_node(node); + old_value + } + /// Saves the map to memory. fn save_header(&self) { let header = BTreeHeader { From 221694b1ff4c19803564ecb843e7966791939239 Mon Sep 17 00:00:00 2001 From: Maksym Arutyunyan Date: Wed, 4 Jun 2025 14:59:01 +0200 Subject: [PATCH 3/4] . --- src/btreemap.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/btreemap.rs b/src/btreemap.rs index 794c2c4c..0b3ab2dc 100644 --- a/src/btreemap.rs +++ b/src/btreemap.rs @@ -508,7 +508,7 @@ where if let Ok(idx) = root.search(&key, self.memory()) { // Key found, replace its value and return the old one. return Some(V::from_bytes(Cow::Owned( - self.swap_value(&mut root, idx, value), + self.update_value(&mut root, idx, value), ))); } @@ -551,7 +551,7 @@ where match node.search(&key, self.memory()) { Ok(idx) => { // Key found, replace its value and return the old one. - Some(self.swap_value(&mut node, idx, value)) + Some(self.update_value(&mut node, idx, value)) } Err(idx) => { // The key isn't in the node. `idx` is where that key should be inserted. @@ -579,7 +579,7 @@ where // Check if the key already exists in the child. if let Ok(idx) = child.search(&key, self.memory()) { // Key found, replace its value and return the old one. - return Some(self.swap_value(&mut child, idx, value)); + return Some(self.update_value(&mut child, idx, value)); } // The child is full. Split the child. @@ -1274,7 +1274,7 @@ where node.save(self.allocator_mut()); } - fn swap_value(&mut self, node: &mut Node, idx: usize, new_value: Vec) -> Vec { + fn update_value(&mut self, node: &mut Node, idx: usize, new_value: Vec) -> Vec { let old_value = node.swap_value(idx, new_value, self.memory()); self.save_node(node); old_value From 658491c61fdc4b86502de1a382ed38f3f22b4505 Mon Sep 17 00:00:00 2001 From: Maksym Arutyunyan Date: Wed, 4 Jun 2025 16:59:40 +0200 Subject: [PATCH 4/4] . --- src/btreemap.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/btreemap.rs b/src/btreemap.rs index 0b3ab2dc..179ecb4e 100644 --- a/src/btreemap.rs +++ b/src/btreemap.rs @@ -1274,6 +1274,7 @@ where node.save(self.allocator_mut()); } + /// Replaces the value at `idx` in the node, saves the node, and returns the old value. fn update_value(&mut self, node: &mut Node, idx: usize, new_value: Vec) -> Vec { let old_value = node.swap_value(idx, new_value, self.memory()); self.save_node(node);