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>,
)
| 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 |
no test coverage detected