Skip to content

Commit af10f52

Browse files
committed
btree: keep only generic BTree implementation
1 parent 58c3a00 commit af10f52

2 files changed

Lines changed: 0 additions & 219 deletions

File tree

Lines changed: 0 additions & 219 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@
1616
// See the License for the specific language governing permissions and
1717
// limitations under the License.
1818

19-
// In Go 1.18 and beyond, a BTreeG generic is created, and BTree is a specific
20-
// instantiation of that generic for the Item interface, with a backwards-
21-
// compatible API. Before go1.18, generics are not supported,
22-
// and BTree is just an implementation based around the Item interface.
23-
2419
// Package btree implements in-memory B-Trees of arbitrary degree.
2520
//
2621
// btree implements an in-memory B-Tree for use as an ordered data structure.
@@ -57,28 +52,13 @@
5752
// Its functions, therefore, exactly mirror those of
5853
// llrb.LLRB where possible. Unlike gollrb, though, we currently don't
5954
// support storing multiple equivalent values.
60-
//
61-
// There are two implementations; those suffixed with 'G' are generics, usable
62-
// for any type, and require a passed-in "less" function to define their ordering.
63-
// Those without this prefix are specific to the 'Item' interface, and use
64-
// its 'Less' function for ordering.
6555
package btree
6656

6757
import (
6858
"sort"
6959
"sync"
7060
)
7161

72-
// Item represents a single object in the tree.
73-
type Item interface {
74-
// Less tests whether the current item is less than the given argument.
75-
//
76-
// This must provide a strict weak ordering.
77-
// If !a.Less(b) && !b.Less(a), we treat this to mean a == b (i.e. we can only
78-
// hold one of either a or b in the tree).
79-
Less(than Item) bool
80-
}
81-
8262
// DefaultFreeListSize is the default capacity of a BTree node free list.
8363
const DefaultFreeListSize = 32
8464

@@ -878,202 +858,3 @@ func (n *node[T]) reset(c *copyOnWriteContext[T]) bool {
878858
}
879859
return c.freeNode(n) != ftFreelistFull
880860
}
881-
882-
// Int implements the Item interface for integers.
883-
type Int int
884-
885-
// Less returns true if int(a) < int(b).
886-
func (a Int) Less(b Item) bool {
887-
return a < b.(Int)
888-
}
889-
890-
// BTree is an implementation of a B-Tree.
891-
//
892-
// BTree stores Item instances in an ordered structure, allowing easy insertion,
893-
// removal, and iteration.
894-
//
895-
// Write operations are not safe for concurrent mutation by multiple
896-
// goroutines, but Read operations are.
897-
type BTree BTreeG[Item]
898-
899-
var itemLess LessFunc[Item] = func(a, b Item) bool {
900-
return a.Less(b)
901-
}
902-
903-
// New creates a new B-Tree with the given degree.
904-
//
905-
// New(2), for example, will create a 2-3-4 tree (each node contains 1-3 items
906-
// and 2-4 children).
907-
func New(degree int) *BTree {
908-
return (*BTree)(NewG[Item](degree, itemLess))
909-
}
910-
911-
// FreeList represents a free list of btree nodes. By default each
912-
// BTree has its own FreeList, but multiple BTrees can share the same
913-
// FreeList.
914-
// Two Btrees using the same freelist are safe for concurrent write access.
915-
type FreeList FreeListG[Item]
916-
917-
// NewFreeList creates a new free list.
918-
// size is the maximum size of the returned free list.
919-
func NewFreeList(size int) *FreeList {
920-
return (*FreeList)(NewFreeListG[Item](size))
921-
}
922-
923-
// NewWithFreeList creates a new B-Tree that uses the given node free list.
924-
func NewWithFreeList(degree int, f *FreeList) *BTree {
925-
return (*BTree)(NewWithFreeListG[Item](degree, itemLess, (*FreeListG[Item])(f)))
926-
}
927-
928-
// ItemIterator allows callers of Ascend* to iterate in-order over portions of
929-
// the tree. When this function returns false, iteration will stop and the
930-
// associated Ascend* function will immediately return.
931-
type ItemIterator ItemIteratorG[Item]
932-
933-
// Clone clones the btree, lazily. Clone should not be called concurrently,
934-
// but the original tree (t) and the new tree (t2) can be used concurrently
935-
// once the Clone call completes.
936-
//
937-
// The internal tree structure of b is marked read-only and shared between t and
938-
// t2. Writes to both t and t2 use copy-on-write logic, creating new nodes
939-
// whenever one of b's original nodes would have been modified. Read operations
940-
// should have no performance degredation. Write operations for both t and t2
941-
// will initially experience minor slow-downs caused by additional allocs and
942-
// copies due to the aforementioned copy-on-write logic, but should converge to
943-
// the original performance characteristics of the original tree.
944-
func (t *BTree) Clone() (t2 *BTree) {
945-
return (*BTree)((*BTreeG[Item])(t).Clone())
946-
}
947-
948-
// Delete removes an item equal to the passed in item from the tree, returning
949-
// it. If no such item exists, returns nil.
950-
func (t *BTree) Delete(item Item) Item {
951-
i, _ := (*BTreeG[Item])(t).Delete(item)
952-
return i
953-
}
954-
955-
// DeleteMax removes the largest item in the tree and returns it.
956-
// If no such item exists, returns nil.
957-
func (t *BTree) DeleteMax() Item {
958-
i, _ := (*BTreeG[Item])(t).DeleteMax()
959-
return i
960-
}
961-
962-
// DeleteMin removes the smallest item in the tree and returns it.
963-
// If no such item exists, returns nil.
964-
func (t *BTree) DeleteMin() Item {
965-
i, _ := (*BTreeG[Item])(t).DeleteMin()
966-
return i
967-
}
968-
969-
// Get looks for the key item in the tree, returning it. It returns nil if
970-
// unable to find that item.
971-
func (t *BTree) Get(key Item) Item {
972-
i, _ := (*BTreeG[Item])(t).Get(key)
973-
return i
974-
}
975-
976-
// Max returns the largest item in the tree, or nil if the tree is empty.
977-
func (t *BTree) Max() Item {
978-
i, _ := (*BTreeG[Item])(t).Max()
979-
return i
980-
}
981-
982-
// Min returns the smallest item in the tree, or nil if the tree is empty.
983-
func (t *BTree) Min() Item {
984-
i, _ := (*BTreeG[Item])(t).Min()
985-
return i
986-
}
987-
988-
// Has returns true if the given key is in the tree.
989-
func (t *BTree) Has(key Item) bool {
990-
return (*BTreeG[Item])(t).Has(key)
991-
}
992-
993-
// ReplaceOrInsert adds the given item to the tree. If an item in the tree
994-
// already equals the given one, it is removed from the tree and returned.
995-
// Otherwise, nil is returned.
996-
//
997-
// nil cannot be added to the tree (will panic).
998-
func (t *BTree) ReplaceOrInsert(item Item) Item {
999-
i, _ := (*BTreeG[Item])(t).ReplaceOrInsert(item)
1000-
return i
1001-
}
1002-
1003-
// AscendRange calls the iterator for every value in the tree within the range
1004-
// [greaterOrEqual, lessThan), until iterator returns false.
1005-
func (t *BTree) AscendRange(greaterOrEqual, lessThan Item, iterator ItemIterator) {
1006-
(*BTreeG[Item])(t).AscendRange(greaterOrEqual, lessThan, (ItemIteratorG[Item])(iterator))
1007-
}
1008-
1009-
// AscendLessThan calls the iterator for every value in the tree within the range
1010-
// [first, pivot), until iterator returns false.
1011-
func (t *BTree) AscendLessThan(pivot Item, iterator ItemIterator) {
1012-
(*BTreeG[Item])(t).AscendLessThan(pivot, (ItemIteratorG[Item])(iterator))
1013-
}
1014-
1015-
// AscendGreaterOrEqual calls the iterator for every value in the tree within
1016-
// the range [pivot, last], until iterator returns false.
1017-
func (t *BTree) AscendGreaterOrEqual(pivot Item, iterator ItemIterator) {
1018-
(*BTreeG[Item])(t).AscendGreaterOrEqual(pivot, (ItemIteratorG[Item])(iterator))
1019-
}
1020-
1021-
// Ascend calls the iterator for every value in the tree within the range
1022-
// [first, last], until iterator returns false.
1023-
func (t *BTree) Ascend(iterator ItemIterator) {
1024-
(*BTreeG[Item])(t).Ascend((ItemIteratorG[Item])(iterator))
1025-
}
1026-
1027-
// DescendRange calls the iterator for every value in the tree within the range
1028-
// [lessOrEqual, greaterThan), until iterator returns false.
1029-
func (t *BTree) DescendRange(lessOrEqual, greaterThan Item, iterator ItemIterator) {
1030-
(*BTreeG[Item])(t).DescendRange(lessOrEqual, greaterThan, (ItemIteratorG[Item])(iterator))
1031-
}
1032-
1033-
// DescendLessOrEqual calls the iterator for every value in the tree within the range
1034-
// [pivot, first], until iterator returns false.
1035-
func (t *BTree) DescendLessOrEqual(pivot Item, iterator ItemIterator) {
1036-
(*BTreeG[Item])(t).DescendLessOrEqual(pivot, (ItemIteratorG[Item])(iterator))
1037-
}
1038-
1039-
// DescendGreaterThan calls the iterator for every value in the tree within
1040-
// the range [last, pivot), until iterator returns false.
1041-
func (t *BTree) DescendGreaterThan(pivot Item, iterator ItemIterator) {
1042-
(*BTreeG[Item])(t).DescendGreaterThan(pivot, (ItemIteratorG[Item])(iterator))
1043-
}
1044-
1045-
// Descend calls the iterator for every value in the tree within the range
1046-
// [last, first], until iterator returns false.
1047-
func (t *BTree) Descend(iterator ItemIterator) {
1048-
(*BTreeG[Item])(t).Descend((ItemIteratorG[Item])(iterator))
1049-
}
1050-
1051-
// Len returns the number of items currently in the tree.
1052-
func (t *BTree) Len() int {
1053-
return (*BTreeG[Item])(t).Len()
1054-
}
1055-
1056-
// Clear removes all items from the btree. If addNodesToFreelist is true,
1057-
// t's nodes are added to its freelist as part of this call, until the freelist
1058-
// is full. Otherwise, the root node is simply dereferenced and the subtree
1059-
// left to Go's normal GC processes.
1060-
//
1061-
// This can be much faster
1062-
// than calling Delete on all elements, because that requires finding/removing
1063-
// each element in the tree and updating the tree accordingly. It also is
1064-
// somewhat faster than creating a new tree to replace the old one, because
1065-
// nodes from the old tree are reclaimed into the freelist for use by the new
1066-
// one, instead of being lost to the garbage collector.
1067-
//
1068-
// This call takes:
1069-
//
1070-
// O(1): when addNodesToFreelist is false, this is a single operation.
1071-
// O(1): when the freelist is already full, it breaks out immediately
1072-
// O(freelist size): when the freelist is empty and the nodes are all owned
1073-
// by this tree, nodes are added to the freelist until full.
1074-
// O(tree size): when all nodes are owned by another tree, all nodes are
1075-
// iterated over looking for nodes to add to the freelist, and due to
1076-
// ownership, none are.
1077-
func (t *BTree) Clear(addNodesToFreelist bool) {
1078-
(*BTreeG[Item])(t).Clear(addNodesToFreelist)
1079-
}

0 commit comments

Comments
 (0)