From 129b4870c1fe6035e4ac1b1df4cf66695bba538f Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 14:20:59 +0000 Subject: [PATCH 01/10] opt: Refactor the internal Value data structure and make some performance improvements --- canbench_results.yml | 198 ++++++++++++++++++++-------------------- src/btreemap.rs | 6 +- src/btreemap/iter.rs | 4 +- src/btreemap/node.rs | 143 ++++++++++++++++------------- src/btreemap/node/v1.rs | 2 +- src/btreemap/node/v2.rs | 4 +- 6 files changed, 188 insertions(+), 169 deletions(-) diff --git a/canbench_results.yml b/canbench_results.yml index bd1995fe..f258d814 100644 --- a/canbench_results.yml +++ b/canbench_results.yml @@ -1,595 +1,595 @@ benches: btreemap_get_blob_128_1024: total: - instructions: 893670424 + instructions: 878971005 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_128_1024_v2: total: - instructions: 995207241 + instructions: 983275221 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_16_1024: total: - instructions: 337648227 + instructions: 319715805 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_16_1024_v2: total: - instructions: 444217122 + instructions: 421675594 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_256_1024: total: - instructions: 1415511747 + instructions: 1409036248 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_256_1024_v2: total: - instructions: 1514168820 + instructions: 1512445162 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_32_1024: total: - instructions: 381907680 + instructions: 354512789 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_32_1024_v2: total: - instructions: 488487485 + instructions: 464817510 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_4_1024: total: - instructions: 227261128 + instructions: 204222773 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_4_1024_v2: total: - instructions: 325869733 + instructions: 301681937 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_512_1024: total: - instructions: 2450115183 + instructions: 2464167895 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_512_1024_v2: total: - instructions: 2550121969 + instructions: 2568814123 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_64_1024: total: - instructions: 628111428 + instructions: 615732256 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_64_1024_v2: total: - instructions: 741635543 + instructions: 724621733 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_1024: total: - instructions: 268581241 + instructions: 238997734 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_1024_v2: total: - instructions: 361655931 + instructions: 335085670 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_u64: total: - instructions: 225674655 + instructions: 214388698 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_u64_v2: total: - instructions: 327541207 + instructions: 323735788 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_blob_8: total: - instructions: 206115900 + instructions: 196972163 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_blob_8_v2: total: - instructions: 284748710 + instructions: 282503263 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_u64: total: - instructions: 209460964 + instructions: 198616877 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_u64_v2: total: - instructions: 292825246 + instructions: 289147774 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_insert_10mib_values: total: - instructions: 143780576 + instructions: 143524464 heap_increase: 0 stable_memory_increase: 32 scopes: {} btreemap_insert_blob_1024_128: total: - instructions: 5164808652 + instructions: 5154751286 heap_increase: 0 stable_memory_increase: 262 scopes: {} btreemap_insert_blob_1024_128_v2: total: - instructions: 5281950728 + instructions: 5276383944 heap_increase: 0 stable_memory_increase: 196 scopes: {} btreemap_insert_blob_1024_16: total: - instructions: 5121789897 + instructions: 5111707232 heap_increase: 0 stable_memory_increase: 241 scopes: {} btreemap_insert_blob_1024_16_v2: total: - instructions: 5240004829 + instructions: 5234434737 heap_increase: 0 stable_memory_increase: 181 scopes: {} btreemap_insert_blob_1024_256: total: - instructions: 5191598730 + instructions: 5181536987 heap_increase: 0 stable_memory_increase: 292 scopes: {} btreemap_insert_blob_1024_256_v2: total: - instructions: 5307930234 + instructions: 5302343627 heap_increase: 0 stable_memory_increase: 219 scopes: {} btreemap_insert_blob_1024_32: total: - instructions: 5130230816 + instructions: 5120199769 heap_increase: 0 stable_memory_increase: 239 scopes: {} btreemap_insert_blob_1024_32_v2: total: - instructions: 5250490862 + instructions: 5244961058 heap_increase: 0 stable_memory_increase: 180 scopes: {} btreemap_insert_blob_1024_4: total: - instructions: 5020410565 + instructions: 5010408736 heap_increase: 0 stable_memory_increase: 235 scopes: {} btreemap_insert_blob_1024_4_v2: total: - instructions: 5138630598 + instructions: 5133121206 heap_increase: 0 stable_memory_increase: 176 scopes: {} btreemap_insert_blob_1024_512: total: - instructions: 5313901374 + instructions: 5303873413 heap_increase: 0 stable_memory_increase: 348 scopes: {} btreemap_insert_blob_1024_512_v2: total: - instructions: 5431298131 + instructions: 5425701813 heap_increase: 0 stable_memory_increase: 261 scopes: {} btreemap_insert_blob_1024_64: total: - instructions: 5162795781 + instructions: 5152698868 heap_increase: 0 stable_memory_increase: 250 scopes: {} btreemap_insert_blob_1024_64_v2: total: - instructions: 5281814406 + instructions: 5276217130 heap_increase: 0 stable_memory_increase: 188 scopes: {} btreemap_insert_blob_1024_8: total: - instructions: 5104330157 + instructions: 5094277619 heap_increase: 0 stable_memory_increase: 237 scopes: {} btreemap_insert_blob_1024_8_v2: total: - instructions: 5221951548 + instructions: 5216394108 heap_increase: 0 stable_memory_increase: 178 scopes: {} btreemap_insert_blob_128_1024: total: - instructions: 1472048001 + instructions: 1465681050 heap_increase: 0 stable_memory_increase: 260 scopes: {} btreemap_insert_blob_128_1024_v2: total: - instructions: 1581626427 + instructions: 1576065772 heap_increase: 0 stable_memory_increase: 195 scopes: {} btreemap_insert_blob_16_1024: total: - instructions: 851823832 + instructions: 844178311 heap_increase: 0 stable_memory_increase: 215 scopes: {} btreemap_insert_blob_16_1024_v2: total: - instructions: 965540836 + instructions: 960538799 heap_increase: 0 stable_memory_increase: 161 scopes: {} btreemap_insert_blob_256_1024: total: - instructions: 2043379400 + instructions: 2033378767 heap_increase: 0 stable_memory_increase: 292 scopes: {} btreemap_insert_blob_256_1024_v2: total: - instructions: 2156403366 + instructions: 2150869150 heap_increase: 0 stable_memory_increase: 219 scopes: {} btreemap_insert_blob_32_1024: total: - instructions: 903787236 + instructions: 893398508 heap_increase: 0 stable_memory_increase: 230 scopes: {} btreemap_insert_blob_32_1024_v2: total: - instructions: 1017622127 + instructions: 1012169794 heap_increase: 0 stable_memory_increase: 173 scopes: {} btreemap_insert_blob_4_1024: total: - instructions: 645314996 + instructions: 636086084 heap_increase: 0 stable_memory_increase: 123 scopes: {} btreemap_insert_blob_4_1024_v2: total: - instructions: 747132204 + instructions: 741816158 heap_increase: 0 stable_memory_increase: 92 scopes: {} btreemap_insert_blob_512_1024: total: - instructions: 3177514301 + instructions: 3167396877 heap_increase: 0 stable_memory_increase: 351 scopes: {} btreemap_insert_blob_512_1024_v2: total: - instructions: 3288704008 + instructions: 3283038853 heap_increase: 0 stable_memory_increase: 263 scopes: {} btreemap_insert_blob_64_1024: total: - instructions: 1170984032 + instructions: 1162571155 heap_increase: 0 stable_memory_increase: 245 scopes: {} btreemap_insert_blob_64_1024_v2: total: - instructions: 1292569627 + instructions: 1287172477 heap_increase: 0 stable_memory_increase: 183 scopes: {} btreemap_insert_blob_8_1024: total: - instructions: 770542808 + instructions: 761292027 heap_increase: 0 stable_memory_increase: 183 scopes: {} btreemap_insert_blob_8_1024_v2: total: - instructions: 876068225 + instructions: 870827127 heap_increase: 0 stable_memory_increase: 138 scopes: {} btreemap_insert_blob_8_u64: total: - instructions: 368655501 + instructions: 356978428 heap_increase: 0 stable_memory_increase: 6 scopes: {} btreemap_insert_blob_8_u64_v2: total: - instructions: 483666450 + instructions: 478190207 heap_increase: 0 stable_memory_increase: 4 scopes: {} btreemap_insert_u64_blob_8: total: - instructions: 377443641 + instructions: 367868021 heap_increase: 0 stable_memory_increase: 7 scopes: {} btreemap_insert_u64_blob_8_v2: total: - instructions: 460731804 + instructions: 455458927 heap_increase: 0 stable_memory_increase: 5 scopes: {} btreemap_insert_u64_u64: total: - instructions: 390178100 + instructions: 377745994 heap_increase: 0 stable_memory_increase: 7 scopes: {} btreemap_insert_u64_u64_v2: total: - instructions: 476655765 + instructions: 468129321 heap_increase: 0 stable_memory_increase: 6 scopes: {} btreemap_iter_10mib_values: total: - instructions: 25429011 + instructions: 17136200 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_count_10mib_values: total: - instructions: 523576 + instructions: 525330 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_count_small_values: total: - instructions: 9978843 + instructions: 10091613 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_rev_10mib_values: total: - instructions: 25428310 + instructions: 17134991 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_rev_small_values: total: - instructions: 15984294 + instructions: 15559069 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_small_values: total: - instructions: 15967493 + instructions: 15511022 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_10mib_values: total: - instructions: 513164 + instructions: 515148 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_rev_10mib_values: total: - instructions: 515517 + instructions: 517405 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_rev_small_values: total: - instructions: 10350635 + instructions: 10448446 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_small_values: total: - instructions: 10114798 + instructions: 10205367 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_read_every_third_value_from_range: total: - instructions: 160211242 + instructions: 113555174 heap_increase: 0 stable_memory_increase: 0 scopes: { } btreemap_read_keys_from_range: total: - instructions: 160211242 + instructions: 113555174 heap_increase: 0 stable_memory_increase: 0 scopes: { } btreemap_remove_blob_128_1024: total: - instructions: 1842207367 + instructions: 1824937397 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_128_1024_v2: total: - instructions: 2007214795 + instructions: 1994117833 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_16_1024: total: - instructions: 1069875544 + instructions: 1054914189 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_16_1024_v2: total: - instructions: 1227916080 + instructions: 1218347932 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_256_1024: total: - instructions: 2513310681 + instructions: 2493657315 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_256_1024_v2: total: - instructions: 2671355871 + instructions: 2658505339 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_32_1024: total: - instructions: 1149405495 + instructions: 1129011919 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_32_1024_v2: total: - instructions: 1312387688 + instructions: 1300344147 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_4_1024: total: - instructions: 653919477 + instructions: 643894586 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_4_1024_v2: total: - instructions: 775125688 + instructions: 768838198 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_512_1024: total: - instructions: 3913637896 + instructions: 3893165014 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_512_1024_v2: total: - instructions: 4074072942 + instructions: 4060789355 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_64_1024: total: - instructions: 1484708886 + instructions: 1465765610 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_64_1024_v2: total: - instructions: 1655573592 + instructions: 1642910591 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_1024: total: - instructions: 863066043 + instructions: 851762628 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_1024_v2: total: - instructions: 1003523478 + instructions: 994112119 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_u64: total: - instructions: 486533270 + instructions: 471125361 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_u64_v2: total: - instructions: 644099809 + instructions: 633929180 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_blob_8: total: - instructions: 541098489 + instructions: 521945040 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_blob_8_v2: total: - instructions: 659949359 + instructions: 647131002 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_u64: total: - instructions: 562530659 + instructions: 544152776 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_u64_v2: total: - instructions: 691055139 + instructions: 679241612 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_10mib_values: total: - instructions: 17139887 + instructions: 17134788 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_rev_10mib_values: total: - instructions: 17138678 + instructions: 17133579 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_rev_small_values: total: - instructions: 15685594 + instructions: 15488407 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_small_values: total: - instructions: 15644789 + instructions: 15440360 heap_increase: 0 stable_memory_increase: 0 scopes: {} diff --git a/src/btreemap.rs b/src/btreemap.rs index c1c76025..c7c77e5f 100644 --- a/src/btreemap.rs +++ b/src/btreemap.rs @@ -353,7 +353,7 @@ where /// key.to_bytes().len() <= max_size(Key) /// value.to_bytes().len() <= max_size(Value) pub fn insert(&mut self, key: K, value: V) -> Option { - let value = value.to_bytes_checked().to_vec(); + let value = value.to_bytes_checked().into_owned(); let root = if self.root_addr == NULL { // No root present. Allocate one. @@ -521,9 +521,9 @@ where } fn get_helper(&self, node_addr: Address, key: &K) -> Option> { - let node = self.load_node(node_addr); + let mut node = self.load_node(node_addr); match node.search(key) { - Ok(idx) => Some(node.value(idx, self.memory()).to_vec()), + Ok(idx) => Some(node.into_entry(idx, self.memory()).1), Err(idx) => { match node.node_type() { NodeType::Leaf => None, // Key not found. diff --git a/src/btreemap/iter.rs b/src/btreemap/iter.rs index 5c683585..7e2be235 100644 --- a/src/btreemap/iter.rs +++ b/src/btreemap/iter.rs @@ -455,7 +455,7 @@ where fn next(&mut self) -> Option { self.0.next_map(|node, entry_idx| { let (key, encoded_value) = node.entry(entry_idx, self.0.map.memory()); - (key, V::from_bytes(Cow::Owned(encoded_value))) + (key.clone(), V::from_bytes(Cow::Borrowed(encoded_value))) }) } @@ -476,7 +476,7 @@ where fn next_back(&mut self) -> Option { self.0.next_back_map(|node, entry_idx| { let (key, encoded_value) = node.entry(entry_idx, self.0.map.memory()); - (key, V::from_bytes(Cow::Owned(encoded_value))) + (key.clone(), V::from_bytes(Cow::Borrowed(encoded_value))) }) } } diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index 4df66600..155572ed 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -6,7 +6,7 @@ use crate::{ write, write_struct, write_u32, Memory, }; use std::borrow::{Borrow, Cow}; -use std::cell::{Ref, RefCell}; +use std::cell::{OnceCell, Ref, RefCell}; mod io; #[cfg(test)] @@ -37,6 +37,7 @@ pub enum NodeType { } pub type Entry = (K, Vec); +pub type EntryRef<'a, K> = (&'a K, &'a [u8]); /// A node of a B-Tree. /// @@ -53,7 +54,7 @@ pub struct Node { // Values are stored in a Refcell as they are loaded lazily. // A RefCell allows loading the value and caching it without requiring exterior mutability. // INVARIANT: the list is sorted by key. - keys_and_encoded_values: Vec<(K, RefCell)>, + keys_and_encoded_values: Vec<(K, Value)>, // For the key at position I, children[I] points to the left // child of this key and children[I + 1] points to the right child. children: Vec
, @@ -136,7 +137,8 @@ impl Node { match self.node_type { NodeType::Leaf => { // NOTE: a node can never be empty, so this access is safe. - self.entry(0, memory) + let entry = self.entry(0, memory); + (entry.0.clone(), entry.1.to_vec()) } NodeType::Internal => { let first_child = Self::load( @@ -164,66 +166,46 @@ impl Node { ) -> Entry { let (old_key, old_value) = core::mem::replace( &mut self.keys_and_encoded_values[idx], - (key, RefCell::new(Value::ByVal(value))), + (key, Value::from_value(value)), ); - ( - old_key, - self.resolve_value(RefCell::into_inner(old_value), memory), - ) + (old_key, self.value_into_vec(old_value, memory)) } - /// Returns a copy of the entry at the specified index. - pub fn entry(&self, idx: usize, memory: &M) -> Entry { + /// Returns a reference to the entry at the specified index. + pub fn entry(&self, idx: usize, memory: &M) -> EntryRef { ( - self.keys_and_encoded_values[idx].0.clone(), - self.value(idx, memory).to_vec(), + &self.keys_and_encoded_values[idx].0, + self.value(idx, memory), ) } /// Returns a reference to the encoded value at the specified index. - pub fn value(&self, idx: usize, memory: &M) -> Ref<[u8]> { + pub fn value(&self, idx: usize, memory: &M) -> &[u8] { // Load and cache the value from the underlying memory if needed. - let encoded_value = &self.keys_and_encoded_values[idx].1; - - // We borrow the value immutably first. We only borrow the value mutably if it hasn't been - // cached yet. This is to ensure that no references have been given out to the cached value - // when we call .borrow_mut(). - let encoded_value_borrow = encoded_value.borrow(); - if let Value::ByRef(offset) = *encoded_value_borrow { - // We drop the borrow explicitly because we want to borrow mutably on the next line. - drop(encoded_value_borrow); - *encoded_value.borrow_mut() = - Value::ByVal(self.resolve_value(Value::ByRef(offset), memory)); - } + self.keys_and_encoded_values[idx] + .1 + .get_or_load(|offset| self.load_value_from_memory(offset, memory)) + } - // Return a reference to the value. - Ref::map(encoded_value.borrow(), |value| match value { - Value::ByVal(v) => &v[..], - Value::ByRef(_) => { - unreachable!("value must have been loaded already in the code above.") - } - }) + /// Extracts the contents of value (by loading it first if it's not loaded yet). + fn value_into_vec(&self, mut value: Value, memory: &M) -> Vec { + value.take_or_else(|offset| self.load_value_from_memory(offset, memory)) } - fn resolve_value(&self, value: Value, memory: &M) -> Vec { - match value { - Value::ByRef(offset) => { - // Value isn't loaded yet. - let reader = NodeReader { - address: self.address, - overflows: &self.overflows, - page_size: self.page_size(), - memory, - }; + /// Loads a value from stable memory at the given offset. + fn load_value_from_memory(&self, offset: Bytes, memory: &M) -> Vec { + let reader = NodeReader { + address: self.address, + overflows: &self.overflows, + page_size: self.page_size(), + memory, + }; - let value_len = read_u32(&reader, Address::from(offset.get())) as usize; - let mut bytes = vec![0; value_len]; - reader.read((offset + U32_SIZE).get(), &mut bytes); + let value_len = read_u32(&reader, Address::from(offset.get())) as usize; + let mut bytes = vec![0; value_len]; + reader.read((offset + U32_SIZE).get(), &mut bytes); - bytes - } - Value::ByVal(bytes) => bytes, - } + bytes } fn page_size(&self) -> PageSize { @@ -268,19 +250,26 @@ impl Node { /// Inserts a new entry at the specified index. pub fn insert_entry(&mut self, idx: usize, (key, encoded_value): Entry) { self.keys_and_encoded_values - .insert(idx, (key, RefCell::new(Value::ByVal(encoded_value)))); + .insert(idx, (key, Value::from_value(encoded_value))); + } + + /// Returns the entry at the specified index while consuming this node. + pub fn into_entry(mut self, idx: usize, memory: &M) -> Entry { + let keys_and_encoded_values = core::mem::take(&mut self.keys_and_encoded_values); + let (key, value) = keys_and_encoded_values.into_iter().nth(idx).unwrap(); + (key, self.value_into_vec(value, memory)) } /// Removes the entry at the specified index. pub fn remove_entry(&mut self, idx: usize, memory: &M) -> Entry { let (key, value) = self.keys_and_encoded_values.remove(idx); - (key, self.resolve_value(RefCell::into_inner(value), memory)) + (key, self.value_into_vec(value, memory)) } /// Adds a new entry at the back of the node. pub fn push_entry(&mut self, (key, encoded_value): Entry) { self.keys_and_encoded_values - .push((key, RefCell::new(Value::ByVal(encoded_value)))); + .push((key, Value::from_value(encoded_value))); } /// Removes an entry from the back of the node. @@ -295,10 +284,7 @@ impl Node { .pop() .expect("node must not be empty"); - Some(( - key, - self.resolve_value(RefCell::into_inner(last_value), memory), - )) + Some((key, self.value_into_vec(last_value, memory))) } /// Merges the entries and children of the `source` node into self, along with the median entry. @@ -474,14 +460,47 @@ impl NodeHeader { } } -// The value in a K/V pair. +/// The value in a K/V pair. #[derive(Debug)] -enum Value { - // The value's encoded bytes. - ByVal(Vec), +pub(crate) struct Value { + /// The value's offset in the node. + /// When value.get().is_none(), the offset must be set. + offset: Option, - // The value's offset in the node. - ByRef(Bytes), + /// The value's encoded bytes. It can be loaded lazily using offset. + value: OnceCell>, +} + +impl Value { + pub fn from_offset(offset: Bytes) -> Self { + Self { + offset: Some(offset), + value: Default::default(), + } + } + + pub fn from_value(value: Vec) -> Self { + Self { + offset: None, + value: value.into(), + } + } + + /// Returns a reference to the value if the value has been loaded or runs the given function to + /// load the value. + pub fn get_or_load(&self, load: impl FnOnce(Bytes) -> Vec) -> &[u8] { + // The unwrap() must not fail because of the invariant (see in the struct def). + self.value.get_or_init(|| load(self.offset.unwrap())) + } + + /// Extracts the value while consuming self if the value has been loaded or runs the given + /// function to load the value. + pub fn take_or_else(self, load: impl FnOnce(Bytes) -> Vec) -> Vec { + self.value + .into_inner() + // The unwrap() must not fail because of the invariant (see in the struct def). + .unwrap_or_else(|| load(self.offset.unwrap())) + } } /// Stores version-specific data. diff --git a/src/btreemap/node/v1.rs b/src/btreemap/node/v1.rs index f65b3d28..8da4421c 100644 --- a/src/btreemap/node/v1.rs +++ b/src/btreemap/node/v1.rs @@ -77,7 +77,7 @@ impl Node { offset += Bytes::from(max_key_size); let key = K::from_bytes(Cow::Borrowed(&buf)); // Values are loaded lazily. Store a reference and skip loading it. - keys_encoded_values.push((key, RefCell::new(Value::ByRef(offset)))); + keys_encoded_values.push((key, Value::from_offset(offset))); offset += U32_SIZE + Bytes::from(max_value_size); } diff --git a/src/btreemap/node/v2.rs b/src/btreemap/node/v2.rs index 3a2c8cd4..f5cdc537 100644 --- a/src/btreemap/node/v2.rs +++ b/src/btreemap/node/v2.rs @@ -168,13 +168,13 @@ impl Node { reader.read(offset.get(), &mut buf); let key = K::from_bytes(Cow::Borrowed(&buf)); offset += Bytes::from(key_size); - keys_encoded_values.push((key, RefCell::new(Value::ByRef(Bytes::from(0usize))))); + keys_encoded_values.push((key, Value::from_offset(Bytes::from(0usize)))); } // Load the values for (_key, value) in keys_encoded_values.iter_mut() { // Load the values lazily. - *value = RefCell::new(Value::ByRef(Bytes::from(offset.get()))); + *value = Value::from_offset(Bytes::from(offset.get())); let value_size = read_u32(&reader, offset) as usize; offset += U32_SIZE + Bytes::from(value_size as u64); } From 83a36ea5a9fa9d0ccd1fcad1b5da434e27f4cce3 Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 14:52:12 +0000 Subject: [PATCH 02/10] no mut --- src/btreemap.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/btreemap.rs b/src/btreemap.rs index c7c77e5f..b06a7f65 100644 --- a/src/btreemap.rs +++ b/src/btreemap.rs @@ -521,7 +521,7 @@ where } fn get_helper(&self, node_addr: Address, key: &K) -> Option> { - let mut node = self.load_node(node_addr); + let node = self.load_node(node_addr); match node.search(key) { Ok(idx) => Some(node.into_entry(idx, self.memory()).1), Err(idx) => { From 592b784e8c97032dfc2964dd6cc65817837c0502 Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 14:54:40 +0000 Subject: [PATCH 03/10] Rename take_or_else -> take_or_load --- src/btreemap/node.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index 155572ed..585a3896 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -189,7 +189,7 @@ impl Node { /// Extracts the contents of value (by loading it first if it's not loaded yet). fn value_into_vec(&self, mut value: Value, memory: &M) -> Vec { - value.take_or_else(|offset| self.load_value_from_memory(offset, memory)) + value.take_or_load(|offset| self.load_value_from_memory(offset, memory)) } /// Loads a value from stable memory at the given offset. @@ -495,7 +495,7 @@ impl Value { /// Extracts the value while consuming self if the value has been loaded or runs the given /// function to load the value. - pub fn take_or_else(self, load: impl FnOnce(Bytes) -> Vec) -> Vec { + pub fn take_or_load(self, load: impl FnOnce(Bytes) -> Vec) -> Vec { self.value .into_inner() // The unwrap() must not fail because of the invariant (see in the struct def). From 67e16105e07c9a2368cdfe8db232a577b030652b Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 14:58:40 +0000 Subject: [PATCH 04/10] Rename by_ref and by_value --- src/btreemap/node.rs | 10 +++++----- src/btreemap/node/v1.rs | 2 +- src/btreemap/node/v2.rs | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index 585a3896..fe368e28 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -166,7 +166,7 @@ impl Node { ) -> Entry { let (old_key, old_value) = core::mem::replace( &mut self.keys_and_encoded_values[idx], - (key, Value::from_value(value)), + (key, Value::by_value(value)), ); (old_key, self.value_into_vec(old_value, memory)) } @@ -250,7 +250,7 @@ impl Node { /// Inserts a new entry at the specified index. pub fn insert_entry(&mut self, idx: usize, (key, encoded_value): Entry) { self.keys_and_encoded_values - .insert(idx, (key, Value::from_value(encoded_value))); + .insert(idx, (key, Value::by_value(encoded_value))); } /// Returns the entry at the specified index while consuming this node. @@ -269,7 +269,7 @@ impl Node { /// Adds a new entry at the back of the node. pub fn push_entry(&mut self, (key, encoded_value): Entry) { self.keys_and_encoded_values - .push((key, Value::from_value(encoded_value))); + .push((key, Value::by_value(encoded_value))); } /// Removes an entry from the back of the node. @@ -472,14 +472,14 @@ pub(crate) struct Value { } impl Value { - pub fn from_offset(offset: Bytes) -> Self { + pub fn by_ref(offset: Bytes) -> Self { Self { offset: Some(offset), value: Default::default(), } } - pub fn from_value(value: Vec) -> Self { + pub fn by_value(value: Vec) -> Self { Self { offset: None, value: value.into(), diff --git a/src/btreemap/node/v1.rs b/src/btreemap/node/v1.rs index 8da4421c..76eb465c 100644 --- a/src/btreemap/node/v1.rs +++ b/src/btreemap/node/v1.rs @@ -77,7 +77,7 @@ impl Node { offset += Bytes::from(max_key_size); let key = K::from_bytes(Cow::Borrowed(&buf)); // Values are loaded lazily. Store a reference and skip loading it. - keys_encoded_values.push((key, Value::from_offset(offset))); + keys_encoded_values.push((key, Value::by_ref(offset))); offset += U32_SIZE + Bytes::from(max_value_size); } diff --git a/src/btreemap/node/v2.rs b/src/btreemap/node/v2.rs index f5cdc537..d80e45a2 100644 --- a/src/btreemap/node/v2.rs +++ b/src/btreemap/node/v2.rs @@ -168,13 +168,13 @@ impl Node { reader.read(offset.get(), &mut buf); let key = K::from_bytes(Cow::Borrowed(&buf)); offset += Bytes::from(key_size); - keys_encoded_values.push((key, Value::from_offset(Bytes::from(0usize)))); + keys_encoded_values.push((key, Value::by_ref(Bytes::from(0usize)))); } // Load the values for (_key, value) in keys_encoded_values.iter_mut() { // Load the values lazily. - *value = Value::from_offset(Bytes::from(offset.get())); + *value = Value::by_ref(Bytes::from(offset.get())); let value_size = read_u32(&reader, offset) as usize; offset += U32_SIZE + Bytes::from(value_size as u64); } From 2fe2084b6d3e5565c819dddc45b023801522fa14 Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 15:01:21 +0000 Subject: [PATCH 05/10] Remove unused RefCell --- src/btreemap/node.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index fe368e28..080aa6a0 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -6,7 +6,7 @@ use crate::{ write, write_struct, write_u32, Memory, }; use std::borrow::{Borrow, Cow}; -use std::cell::{OnceCell, Ref, RefCell}; +use std::cell::OnceCell; mod io; #[cfg(test)] @@ -51,8 +51,6 @@ pub type EntryRef<'a, K> = (&'a K, &'a [u8]); pub struct Node { address: Address, // List of tuples consisting of a key and the encoded value. - // Values are stored in a Refcell as they are loaded lazily. - // A RefCell allows loading the value and caching it without requiring exterior mutability. // INVARIANT: the list is sorted by key. keys_and_encoded_values: Vec<(K, Value)>, // For the key at position I, children[I] points to the left @@ -456,7 +454,7 @@ struct NodeHeader { impl NodeHeader { fn size() -> Bytes { - Bytes::from(core::mem::size_of::() as u64) + Bytes::from(size_of::() as u64) } } From ee76ca8ac9d798a7fdba0ef30cb82467a75fa0ca Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 15:17:08 +0000 Subject: [PATCH 06/10] size_of --- src/btreemap/node.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index 080aa6a0..5efa9507 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -454,7 +454,7 @@ struct NodeHeader { impl NodeHeader { fn size() -> Bytes { - Bytes::from(size_of::() as u64) + Bytes::from(core::mem::size_of::() as u64) } } From 5c5ffd7317303fecb922dea7862931b3caf2748f Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 15:23:13 +0000 Subject: [PATCH 07/10] Clippy --- src/btreemap/iter.rs | 4 ++-- src/btreemap/node.rs | 10 +++++----- src/btreemap/node/v1.rs | 2 +- src/btreemap/node/v2.rs | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/btreemap/iter.rs b/src/btreemap/iter.rs index 7e2be235..82869508 100644 --- a/src/btreemap/iter.rs +++ b/src/btreemap/iter.rs @@ -537,7 +537,7 @@ where fn next(&mut self) -> Option { self.0.next_map(|node, entry_idx| { let encoded_value = node.value(entry_idx, self.0.map.memory()); - V::from_bytes(Cow::Borrowed(&encoded_value)) + V::from_bytes(Cow::Borrowed(encoded_value)) }) } @@ -558,7 +558,7 @@ where fn next_back(&mut self) -> Option { self.0.next_back_map(|node, entry_idx| { let encoded_value = node.value(entry_idx, self.0.map.memory()); - V::from_bytes(Cow::Borrowed(&encoded_value)) + V::from_bytes(Cow::Borrowed(encoded_value)) }) } } diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index 5efa9507..4033a5f6 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -166,7 +166,7 @@ impl Node { &mut self.keys_and_encoded_values[idx], (key, Value::by_value(value)), ); - (old_key, self.value_into_vec(old_value, memory)) + (old_key, self.extract_value(old_value, memory)) } /// Returns a reference to the entry at the specified index. @@ -186,7 +186,7 @@ impl Node { } /// Extracts the contents of value (by loading it first if it's not loaded yet). - fn value_into_vec(&self, mut value: Value, memory: &M) -> Vec { + fn extract_value(&self, value: Value, memory: &M) -> Vec { value.take_or_load(|offset| self.load_value_from_memory(offset, memory)) } @@ -255,13 +255,13 @@ impl Node { pub fn into_entry(mut self, idx: usize, memory: &M) -> Entry { let keys_and_encoded_values = core::mem::take(&mut self.keys_and_encoded_values); let (key, value) = keys_and_encoded_values.into_iter().nth(idx).unwrap(); - (key, self.value_into_vec(value, memory)) + (key, self.extract_value(value, memory)) } /// Removes the entry at the specified index. pub fn remove_entry(&mut self, idx: usize, memory: &M) -> Entry { let (key, value) = self.keys_and_encoded_values.remove(idx); - (key, self.value_into_vec(value, memory)) + (key, self.extract_value(value, memory)) } /// Adds a new entry at the back of the node. @@ -282,7 +282,7 @@ impl Node { .pop() .expect("node must not be empty"); - Some((key, self.value_into_vec(last_value, memory))) + Some((key, self.extract_value(last_value, memory))) } /// Merges the entries and children of the `source` node into self, along with the median entry. diff --git a/src/btreemap/node/v1.rs b/src/btreemap/node/v1.rs index 76eb465c..9bb5b411 100644 --- a/src/btreemap/node/v1.rs +++ b/src/btreemap/node/v1.rs @@ -180,7 +180,7 @@ impl Node { offset += U32_SIZE; // Write the value. - write(memory, (self.address + offset).get(), &value); + write(memory, (self.address + offset).get(), value); offset += Bytes::from(max_value_size); } diff --git a/src/btreemap/node/v2.rs b/src/btreemap/node/v2.rs index d80e45a2..5f8699ab 100644 --- a/src/btreemap/node/v2.rs +++ b/src/btreemap/node/v2.rs @@ -261,7 +261,7 @@ impl Node { offset += U32_SIZE; // Write the value. - writer.write(offset, &value); + writer.write(offset, value); offset += Bytes::from(value.len()); } From 566a417d8e652e22faff789b39b9a3d18201d673 Mon Sep 17 00:00:00 2001 From: David Frank Date: Tue, 19 Nov 2024 15:30:37 +0000 Subject: [PATCH 08/10] Clippy --- src/btreemap/node/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/btreemap/node/tests.rs b/src/btreemap/node/tests.rs index 11aee289..ff1158ca 100644 --- a/src/btreemap/node/tests.rs +++ b/src/btreemap/node/tests.rs @@ -307,5 +307,5 @@ fn can_call_node_value_multiple_times_on_same_index() { let value1 = node.value(0, &mem); let value2 = node.value(0, &mem); - assert_eq!(&value1[..], &value2[..]); + assert_eq!(value1, value2); } From 3830b93495751f90d5b71b498b90827f7e9e2506 Mon Sep 17 00:00:00 2001 From: David Frank Date: Mon, 18 Nov 2024 16:15:33 +0000 Subject: [PATCH 09/10] Make Value enum --- src/btreemap/node.rs | 48 ++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index 4033a5f6..57b450d7 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -460,44 +460,52 @@ impl NodeHeader { /// The value in a K/V pair. #[derive(Debug)] -pub(crate) struct Value { - /// The value's offset in the node. - /// When value.get().is_none(), the offset must be set. - offset: Option, - - /// The value's encoded bytes. It can be loaded lazily using offset. - value: OnceCell>, +enum Value { + /// The value's encoded bytes. + ByVal(Vec), + + ByRef { + /// The value's offset in the node. + offset: Bytes, + /// The lazily loaded encoded bytes. + loaded_value: OnceCell>, + }, } impl Value { pub fn by_ref(offset: Bytes) -> Self { - Self { - offset: Some(offset), - value: Default::default(), + Self::ByRef { + offset, + loaded_value: Default::default(), } } pub fn by_value(value: Vec) -> Self { - Self { - offset: None, - value: value.into(), - } + Self::ByVal(value) } /// Returns a reference to the value if the value has been loaded or runs the given function to /// load the value. pub fn get_or_load(&self, load: impl FnOnce(Bytes) -> Vec) -> &[u8] { - // The unwrap() must not fail because of the invariant (see in the struct def). - self.value.get_or_init(|| load(self.offset.unwrap())) + match self { + Value::ByVal(v) => &v[..], + Value::ByRef { + offset, + loaded_value: value, + } => value.get_or_init(|| load(*offset)), + } } /// Extracts the value while consuming self if the value has been loaded or runs the given /// function to load the value. pub fn take_or_load(self, load: impl FnOnce(Bytes) -> Vec) -> Vec { - self.value - .into_inner() - // The unwrap() must not fail because of the invariant (see in the struct def). - .unwrap_or_else(|| load(self.offset.unwrap())) + match self { + Value::ByVal(v) => v, + Value::ByRef { + offset, + loaded_value: mut value, + } => value.take().unwrap_or_else(|| load(offset)), + } } } From 0769346e1f9725ea29bdc388d203666c2455d5e4 Mon Sep 17 00:00:00 2001 From: David Frank Date: Wed, 20 Nov 2024 13:13:27 +0000 Subject: [PATCH 10/10] into_inner --- canbench_results.yml | 202 +++++++++++++++++++++---------------------- src/btreemap/node.rs | 4 +- 2 files changed, 103 insertions(+), 103 deletions(-) diff --git a/canbench_results.yml b/canbench_results.yml index f258d814..cd34e136 100644 --- a/canbench_results.yml +++ b/canbench_results.yml @@ -1,595 +1,595 @@ benches: btreemap_get_blob_128_1024: total: - instructions: 878971005 + instructions: 879302205 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_128_1024_v2: total: - instructions: 983275221 + instructions: 986234201 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_16_1024: total: - instructions: 319715805 + instructions: 315520793 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_16_1024_v2: total: - instructions: 421675594 + instructions: 424439334 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_256_1024: total: - instructions: 1409036248 + instructions: 1410478508 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_256_1024_v2: total: - instructions: 1512445162 + instructions: 1515420842 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_32_1024: total: - instructions: 354512789 + instructions: 359080553 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_32_1024_v2: total: - instructions: 464817510 + instructions: 467643018 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_4_1024: total: - instructions: 204222773 + instructions: 205936205 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_4_1024_v2: total: - instructions: 301681937 + instructions: 304383660 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_512_1024: total: - instructions: 2464167895 + instructions: 2465612866 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_512_1024_v2: total: - instructions: 2568814123 + instructions: 2571792093 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_64_1024: total: - instructions: 615732256 + instructions: 611173672 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_64_1024_v2: total: - instructions: 724621733 + instructions: 727594763 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_1024: total: - instructions: 238997734 + instructions: 242798942 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_1024_v2: total: - instructions: 335085670 + instructions: 337855918 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_u64: total: - instructions: 214388698 + instructions: 215475284 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_blob_8_u64_v2: total: - instructions: 323735788 + instructions: 326446044 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_blob_8: total: - instructions: 196972163 + instructions: 198160835 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_blob_8_v2: total: - instructions: 282503263 + instructions: 285194478 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_u64: total: - instructions: 198616877 + instructions: 199393722 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_get_u64_u64_v2: total: - instructions: 289147774 + instructions: 291906450 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_insert_10mib_values: total: - instructions: 143524464 + instructions: 143394599 heap_increase: 0 stable_memory_increase: 32 scopes: {} btreemap_insert_blob_1024_128: total: - instructions: 5154751286 + instructions: 5103816812 heap_increase: 0 stable_memory_increase: 262 scopes: {} btreemap_insert_blob_1024_128_v2: total: - instructions: 5276383944 + instructions: 5223665926 heap_increase: 0 stable_memory_increase: 196 scopes: {} btreemap_insert_blob_1024_16: total: - instructions: 5111707232 + instructions: 5060658098 heap_increase: 0 stable_memory_increase: 241 scopes: {} btreemap_insert_blob_1024_16_v2: total: - instructions: 5234434737 + instructions: 5181580835 heap_increase: 0 stable_memory_increase: 181 scopes: {} btreemap_insert_blob_1024_256: total: - instructions: 5181536987 + instructions: 5130558722 heap_increase: 0 stable_memory_increase: 292 scopes: {} btreemap_insert_blob_1024_256_v2: total: - instructions: 5302343627 + instructions: 5249596386 heap_increase: 0 stable_memory_increase: 219 scopes: {} btreemap_insert_blob_1024_32: total: - instructions: 5120199769 + instructions: 5069315515 heap_increase: 0 stable_memory_increase: 239 scopes: {} btreemap_insert_blob_1024_32_v2: total: - instructions: 5244961058 + instructions: 5192319151 heap_increase: 0 stable_memory_increase: 180 scopes: {} btreemap_insert_blob_1024_4: total: - instructions: 5010408736 + instructions: 4959470000 heap_increase: 0 stable_memory_increase: 235 scopes: {} btreemap_insert_blob_1024_4_v2: total: - instructions: 5133121206 + instructions: 5080388188 heap_increase: 0 stable_memory_increase: 176 scopes: {} btreemap_insert_blob_1024_512: total: - instructions: 5303873413 + instructions: 5252901073 heap_increase: 0 stable_memory_increase: 348 scopes: {} btreemap_insert_blob_1024_512_v2: total: - instructions: 5425701813 + instructions: 5373023593 heap_increase: 0 stable_memory_increase: 261 scopes: {} btreemap_insert_blob_1024_64: total: - instructions: 5152698868 + instructions: 5101699743 heap_increase: 0 stable_memory_increase: 250 scopes: {} btreemap_insert_blob_1024_64_v2: total: - instructions: 5276217130 + instructions: 5223434507 heap_increase: 0 stable_memory_increase: 188 scopes: {} btreemap_insert_blob_1024_8: total: - instructions: 5094277619 + instructions: 5043314359 heap_increase: 0 stable_memory_increase: 237 scopes: {} btreemap_insert_blob_1024_8_v2: total: - instructions: 5216394108 + instructions: 5163637162 heap_increase: 0 stable_memory_increase: 178 scopes: {} btreemap_insert_blob_128_1024: total: - instructions: 1465681050 + instructions: 1458078497 heap_increase: 0 stable_memory_increase: 260 scopes: {} btreemap_insert_blob_128_1024_v2: total: - instructions: 1576065772 + instructions: 1570349058 heap_increase: 0 stable_memory_increase: 195 scopes: {} btreemap_insert_blob_16_1024: total: - instructions: 844178311 + instructions: 839064490 heap_increase: 0 stable_memory_increase: 215 scopes: {} btreemap_insert_blob_16_1024_v2: total: - instructions: 960538799 + instructions: 955395829 heap_increase: 0 stable_memory_increase: 161 scopes: {} btreemap_insert_blob_256_1024: total: - instructions: 2033378767 + instructions: 2028664457 heap_increase: 0 stable_memory_increase: 292 scopes: {} btreemap_insert_blob_256_1024_v2: total: - instructions: 2150869150 + instructions: 2144398075 heap_increase: 0 stable_memory_increase: 219 scopes: {} btreemap_insert_blob_32_1024: total: - instructions: 893398508 + instructions: 890749049 heap_increase: 0 stable_memory_increase: 230 scopes: {} btreemap_insert_blob_32_1024_v2: total: - instructions: 1012169794 + instructions: 1007248566 heap_increase: 0 stable_memory_increase: 173 scopes: {} btreemap_insert_blob_4_1024: total: - instructions: 636086084 + instructions: 633932227 heap_increase: 0 stable_memory_increase: 123 scopes: {} btreemap_insert_blob_4_1024_v2: total: - instructions: 741816158 + instructions: 738087270 heap_increase: 0 stable_memory_increase: 92 scopes: {} btreemap_insert_blob_512_1024: total: - instructions: 3167396877 + instructions: 3161385472 heap_increase: 0 stable_memory_increase: 351 scopes: {} btreemap_insert_blob_512_1024_v2: total: - instructions: 3283038853 + instructions: 3275260995 heap_increase: 0 stable_memory_increase: 263 scopes: {} btreemap_insert_blob_64_1024: total: - instructions: 1162571155 + instructions: 1157359426 heap_increase: 0 stable_memory_increase: 245 scopes: {} btreemap_insert_blob_64_1024_v2: total: - instructions: 1287172477 + instructions: 1281618754 heap_increase: 0 stable_memory_increase: 183 scopes: {} btreemap_insert_blob_8_1024: total: - instructions: 761292027 + instructions: 758180070 heap_increase: 0 stable_memory_increase: 183 scopes: {} btreemap_insert_blob_8_1024_v2: total: - instructions: 870827127 + instructions: 866287942 heap_increase: 0 stable_memory_increase: 138 scopes: {} btreemap_insert_blob_8_u64: total: - instructions: 356978428 + instructions: 353807315 heap_increase: 0 stable_memory_increase: 6 scopes: {} btreemap_insert_blob_8_u64_v2: total: - instructions: 478190207 + instructions: 473686702 heap_increase: 0 stable_memory_increase: 4 scopes: {} btreemap_insert_u64_blob_8: total: - instructions: 367868021 + instructions: 364631146 heap_increase: 0 stable_memory_increase: 7 scopes: {} btreemap_insert_u64_blob_8_v2: total: - instructions: 455458927 + instructions: 450222711 heap_increase: 0 stable_memory_increase: 5 scopes: {} btreemap_insert_u64_u64: total: - instructions: 377745994 + instructions: 374696730 heap_increase: 0 stable_memory_increase: 7 scopes: {} btreemap_insert_u64_u64_v2: total: - instructions: 468129321 + instructions: 462904999 heap_increase: 0 stable_memory_increase: 6 scopes: {} btreemap_iter_10mib_values: total: - instructions: 17136200 + instructions: 17116720 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_count_10mib_values: total: - instructions: 525330 + instructions: 527176 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_count_small_values: total: - instructions: 10091613 + instructions: 10158843 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_rev_10mib_values: total: - instructions: 17134991 + instructions: 17114625 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_rev_small_values: total: - instructions: 15559069 + instructions: 14524294 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_iter_small_values: total: - instructions: 15511022 + instructions: 14527493 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_10mib_values: total: - instructions: 515148 + instructions: 516764 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_rev_10mib_values: total: - instructions: 517405 + instructions: 519117 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_rev_small_values: total: - instructions: 10448446 + instructions: 10530635 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_keys_small_values: total: - instructions: 10205367 + instructions: 10294798 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_read_every_third_value_from_range: total: - instructions: 113555174 + instructions: 113084618 heap_increase: 0 stable_memory_increase: 0 - scopes: { } + scopes: {} btreemap_read_keys_from_range: total: - instructions: 113555174 + instructions: 113084618 heap_increase: 0 stable_memory_increase: 0 - scopes: { } + scopes: {} btreemap_remove_blob_128_1024: total: - instructions: 1824937397 + instructions: 1814329611 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_128_1024_v2: total: - instructions: 1994117833 + instructions: 1982178501 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_16_1024: total: - instructions: 1054914189 + instructions: 1046555128 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_16_1024_v2: total: - instructions: 1218347932 + instructions: 1207409244 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_256_1024: total: - instructions: 2493657315 + instructions: 2484528504 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_256_1024_v2: total: - instructions: 2658505339 + instructions: 2645421668 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_32_1024: total: - instructions: 1129011919 + instructions: 1125110448 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_32_1024_v2: total: - instructions: 1300344147 + instructions: 1290917923 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_4_1024: total: - instructions: 643894586 + instructions: 639953529 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_4_1024_v2: total: - instructions: 768838198 + instructions: 763706218 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_512_1024: total: - instructions: 3893165014 + instructions: 3880456183 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_512_1024_v2: total: - instructions: 4060789355 + instructions: 4043734433 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_64_1024: total: - instructions: 1465765610 + instructions: 1458217613 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_64_1024_v2: total: - instructions: 1642910591 + instructions: 1631937179 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_1024: total: - instructions: 851762628 + instructions: 843328385 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_1024_v2: total: - instructions: 994112119 + instructions: 986540048 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_u64: total: - instructions: 471125361 + instructions: 465951671 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_blob_8_u64_v2: total: - instructions: 633929180 + instructions: 626297968 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_blob_8: total: - instructions: 521945040 + instructions: 516865037 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_blob_8_v2: total: - instructions: 647131002 + instructions: 637827582 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_u64: total: - instructions: 544152776 + instructions: 537895420 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_remove_u64_u64_v2: total: - instructions: 679241612 + instructions: 668544917 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_10mib_values: total: - instructions: 17134788 + instructions: 17140501 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_rev_10mib_values: total: - instructions: 17133579 + instructions: 17139292 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_rev_small_values: total: - instructions: 15488407 + instructions: 15756258 heap_increase: 0 stable_memory_increase: 0 scopes: {} btreemap_values_small_values: total: - instructions: 15440360 + instructions: 15715453 heap_increase: 0 stable_memory_increase: 0 scopes: {} diff --git a/src/btreemap/node.rs b/src/btreemap/node.rs index 57b450d7..ff70ccef 100644 --- a/src/btreemap/node.rs +++ b/src/btreemap/node.rs @@ -503,8 +503,8 @@ impl Value { Value::ByVal(v) => v, Value::ByRef { offset, - loaded_value: mut value, - } => value.take().unwrap_or_else(|| load(offset)), + loaded_value: value, + } => value.into_inner().unwrap_or_else(|| load(offset)), } } }