@@ -675,6 +675,13 @@ func (e *List[T]) Scan(iter func(item T) bool) {
675675 }
676676}
677677
678+ func (e * List [T ]) Clear () {
679+ e .less = nil
680+ e .q = e .q [:0 ]
681+ e .count = 0
682+ e .np = 0
683+ }
684+
678685// Options for passing to the DeleteRange function
679686type DeleteRangeOptions struct {
680687 // Do not return the deleted items.
@@ -689,14 +696,22 @@ type DeleteRangeOptions struct {
689696// max (exclusive) sub-range.
690697// Returns the deleted items as an ordered list that can be iterated over using
691698// the list.Scan() method.
692- func (tr * BTreeG [T ]) DeleteRange (min , max T , opts * DeleteRangeOptions ) (
693- deleted List [T ],
694- ) {
699+ func (tr * BTreeG [T ]) DeleteRange (min , max T , opts * DeleteRangeOptions ) (deleted List [T ]) {
700+ return tr .DeleteRangeReuse (min , max , opts , List [T ]{})
701+ }
702+
703+ // DeleteRangeReuse is the same as DeleteRange, but it takes a List as an argument to
704+ // avoid allocating/growing a new List on each call to DeleteRange. It is unsafe to use
705+ // the same List across concurrent calls to DeleteRange.
706+ func (tr * BTreeG [T ]) DeleteRangeReuse (min , max T , opts * DeleteRangeOptions , deleted List [T ]) List [T ] {
695707 if tr .lock (true ) {
696708 defer tr .unlock (true )
697709 }
698710 extract := opts == nil || ! opts .NoReturn
699711 maxincl := opts != nil && opts .MaxInclusive
712+ // Clear just in case it hasn't been cleared yet.
713+ deleted .Clear ()
714+
700715 maxstop := func (item T ) bool {
701716 if maxincl {
702717 return tr .less (max , item )
@@ -715,7 +730,7 @@ func (tr *BTreeG[T]) DeleteRange(min, max T, opts *DeleteRangeOptions) (
715730 var stack []stackItem
716731restart:
717732 if tr .root == nil {
718- return
733+ return deleted
719734 }
720735 n := tr .isoLoad (& tr .root , true )
721736 stack = append (stack , stackItem {n , 0 })
@@ -751,7 +766,7 @@ restart:
751766 if found {
752767 if maxstop (n .items [i ]) {
753768 // stop
754- return
769+ return deleted
755770 }
756771 pivot = n .items [i ]
757772 if extract {
@@ -790,13 +805,13 @@ restart:
790805 }
791806 tr .count -= j
792807 if stop {
793- return
808+ return deleted
794809 }
795810 }
796811 for ; i < len (n .items ); i ++ {
797812 if maxstop (n .items [i ]) {
798813 // stop
799- return
814+ return deleted
800815 }
801816 if len (n .items ) > tr .min {
802817 if extract {
@@ -826,7 +841,7 @@ restart:
826841 stack = stack [:len (stack )- 1 ]
827842 if len (stack ) == 0 {
828843 // end of tree
829- return
844+ return deleted
830845 }
831846 n = stack [len (stack )- 1 ].node
832847 if i < len (n .items ) {
0 commit comments