MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / split_and_insert

Method split_and_insert

cranelift/bforest/src/path.rs:291–374  ·  view source on GitHub ↗

Split the current leaf node and then insert `key, value`. This should only be used if `try_leaf_insert()` fails.

(
        &mut self,
        mut key: F::Key,
        value: F::Value,
        pool: &mut NodePool<F>,
    )

Source from the content-addressed store, hash-verified

289 /// Split the current leaf node and then insert `key, value`.
290 /// This should only be used if `try_leaf_insert()` fails.
291 fn split_and_insert(
292 &mut self,
293 mut key: F::Key,
294 value: F::Value,
295 pool: &mut NodePool<F>,
296 ) -> Result<(), OutOfMemory> {
297 let orig_root = self.node[0];
298
299 // Loop invariant: We need to split the node at `level` and then retry a failed insertion.
300 // The items to insert are either `(key, ins_node)` or `(key, value)`.
301 let mut ins_node = None;
302 let mut split;
303 for level in (0..self.size).rev() {
304 // Split the current node.
305 let mut node = self.node[level];
306 let mut entry = self.entry[level].into();
307 split = pool[node].split(entry);
308 let rhs_node = pool.alloc_node(split.rhs_data)?;
309
310 // Should the path be moved to the new RHS node?
311 // Prefer the smaller node if we're right in the middle.
312 // Prefer to append to LHS all other things being equal.
313 //
314 // When inserting into an inner node (`ins_node.is_some()`), we must point to a valid
315 // entry in the current node since the new entry is inserted *after* the insert
316 // location.
317 if entry > split.lhs_entries
318 || (entry == split.lhs_entries
319 && (split.lhs_entries > split.rhs_entries || ins_node.is_some()))
320 {
321 node = rhs_node;
322 entry -= split.lhs_entries;
323 self.node[level] = node;
324 self.entry[level] = entry as u8;
325 }
326
327 // Now that we have a not-full node, it must be possible to insert.
328 match ins_node {
329 None => {
330 let inserted = pool[node].try_leaf_insert(entry, key, value);
331 debug_assert!(inserted);
332 // If we inserted at the front of the new rhs_node leaf, we need to propagate
333 // the inserted key as the critical key instead of the previous front key.
334 if entry == 0 && node == rhs_node {
335 split.crit_key = key;
336 }
337 }
338 Some(n) => {
339 let inserted = pool[node].try_inner_insert(entry, key, n);
340 debug_assert!(inserted);
341 // The lower level was moved to the new RHS node, so make sure that is
342 // reflected here.
343 if n == self.node[level + 1] {
344 self.entry[level] += 1;
345 }
346 }
347 }
348

Callers 1

insertMethod · 0.80

Calls 9

OkFunction · 0.85
innerFunction · 0.85
slice_insertFunction · 0.85
splitMethod · 0.80
alloc_nodeMethod · 0.80
try_inner_insertMethod · 0.80
is_someMethod · 0.45
try_leaf_insertMethod · 0.45
expectMethod · 0.45

Tested by

no test coverage detected