| use core::alloc::Allocator; |
| |
| use super::node::{self, Root}; |
| |
| impl<K, V> Root<K, V> { |
| /// Pushes all key-value pairs to the end of the tree, incrementing a |
| /// `length` variable along the way. The latter makes it easier for the |
| /// caller to avoid a leak when the iterator panicks. |
| pub(super) fn bulk_push<I, A: Allocator + Clone>( |
| &mut self, |
| iter: I, |
| length: &mut usize, |
| alloc: A, |
| ) where |
| I: Iterator<Item = (K, V)>, |
| { |
| let mut cur_node = self.borrow_mut().last_leaf_edge().into_node(); |
| // Iterate through all key-value pairs, pushing them into nodes at the right level. |
| for (key, value) in iter { |
| // Try to push key-value pair into the current leaf node. |
| if cur_node.len() < node::CAPACITY { |
| cur_node.push(key, value); |
| } else { |
| // No space left, go up and push there. |
| let mut open_node; |
| let mut test_node = cur_node.forget_type(); |
| loop { |
| match test_node.ascend() { |
| Ok(parent) => { |
| let parent = parent.into_node(); |
| if parent.len() < node::CAPACITY { |
| // Found a node with space left, push here. |
| open_node = parent; |
| break; |
| } else { |
| // Go up again. |
| test_node = parent.forget_type(); |
| } |
| } |
| Err(_) => { |
| // We are at the top, create a new root node and push there. |
| open_node = self.push_internal_level(alloc.clone()); |
| break; |
| } |
| } |
| } |
| |
| // Push key-value pair and new right subtree. |
| let tree_height = open_node.height() - 1; |
| let mut right_tree = Root::new(alloc.clone()); |
| for _ in 0..tree_height { |
| right_tree.push_internal_level(alloc.clone()); |
| } |
| open_node.push(key, value, right_tree); |
| |
| // Go down to the rightmost leaf again. |
| cur_node = open_node.forget_type().last_leaf_edge().into_node(); |
| } |
| |
| // Increment length every iteration, to make sure the map drops |
| // the appended elements even if advancing the iterator panicks. |
| *length += 1; |
| } |
| self.fix_right_border_of_plentiful(); |
| } |
| } |