@@ -13,7 +13,7 @@ use crate::alloc::{Allocator, Global};
1313
1414use super::borrow::DormantMutRef;
1515use super::dedup_sorted_iter::DedupSortedIter;
16- use super::navigate::{LazyLeafRange, LeafRange};
16+ use super::navigate::{LazyLeafRange, LeafRange, RootVessel };
1717use super::node::{self, marker, ForceResult::*, Handle, NodeRef, Root};
1818use super::search::SearchResult::*;
1919
@@ -559,6 +559,7 @@ impl<K, V> BTreeMap<K, V> {
559559
560560impl<K, V, A: Allocator> BTreeMap<K, V, A> {
561561 /// Clears the map, removing all elements.
562+ /// Keeps a part of the allocated memory for reuse.
562563 ///
563564 /// # Examples
564565 ///
@@ -574,12 +575,18 @@ impl<K, V, A: Allocator> BTreeMap<K, V, A> {
574575 /// ```
575576 #[stable(feature = "rust1", since = "1.0.0")]
576577 pub fn clear(&mut self) {
577- // avoid moving the allocator
578- mem::drop(BTreeMap {
579- root: mem::replace(&mut self.root, None),
580- length: mem::replace(&mut self.length, 0),
581- alloc: ManuallyDrop::new(&*self.alloc),
582- });
578+ if let Some(root) = self.root.take() {
579+ let mut iter = IntoIter {
580+ range: root.into_dying().full_range(),
581+ length: self.length,
582+ alloc: unsafe { ManuallyDrop::take(&mut self.alloc) },
583+ };
584+ self.length = 0;
585+ while let Some(kv) = iter.dying_next(Some(&mut self.root)) {
586+ // SAFETY: we consume the dying handle immediately.
587+ unsafe { kv.drop_key_val() };
588+ }
589+ }
583590 }
584591
585592 /// Makes a new empty BTreeMap with a reasonable choice for B.
@@ -1606,14 +1613,14 @@ impl<K, V, A: Allocator> Drop for IntoIter<K, V, A> {
16061613 fn drop(&mut self) {
16071614 // Continue the same loop we perform below. This only runs when unwinding, so we
16081615 // don't have to care about panics this time (they'll abort).
1609- while let Some(kv) = self.0.dying_next() {
1616+ while let Some(kv) = self.0.dying_next(None ) {
16101617 // SAFETY: we consume the dying handle immediately.
16111618 unsafe { kv.drop_key_val() };
16121619 }
16131620 }
16141621 }
16151622
1616- while let Some(kv) = self.dying_next() {
1623+ while let Some(kv) = self.dying_next(None ) {
16171624 let guard = DropGuard(self);
16181625 // SAFETY: we don't touch the tree before consuming the dying handle.
16191626 unsafe { kv.drop_key_val() };
@@ -1625,11 +1632,15 @@ impl<K, V, A: Allocator> Drop for IntoIter<K, V, A> {
16251632impl<K, V, A: Allocator> IntoIter<K, V, A> {
16261633 /// Core of a `next` method returning a dying KV handle,
16271634 /// invalidated by further calls to this function and some others.
1635+ ///
1636+ /// If `root_recycling` is given some vessel, this method recycles the last
1637+ /// leaf and stores it as a fresh root in the vessel.
16281638 fn dying_next(
16291639 &mut self,
1640+ root_recycling: Option<&mut RootVessel<K, V>>,
16301641 ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
16311642 if self.length == 0 {
1632- self.range.deallocating_end(&self.alloc);
1643+ self.range.deallocating_end(&self.alloc, root_recycling );
16331644 None
16341645 } else {
16351646 self.length -= 1;
@@ -1643,7 +1654,7 @@ impl<K, V, A: Allocator> IntoIter<K, V, A> {
16431654 &mut self,
16441655 ) -> Option<Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>> {
16451656 if self.length == 0 {
1646- self.range.deallocating_end(&self.alloc);
1657+ self.range.deallocating_end(&self.alloc, None );
16471658 None
16481659 } else {
16491660 self.length -= 1;
@@ -1658,7 +1669,7 @@ impl<K, V, A: Allocator> Iterator for IntoIter<K, V, A> {
16581669
16591670 fn next(&mut self) -> Option<(K, V)> {
16601671 // SAFETY: we consume the dying handle immediately.
1661- self.dying_next().map(unsafe { |kv| kv.into_key_val() })
1672+ self.dying_next(None ).map(unsafe { |kv| kv.into_key_val() })
16621673 }
16631674
16641675 fn size_hint(&self) -> (usize, Option<usize>) {
0 commit comments