123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- // Copyright 2020 Joshua J Baker. All rights reserved.
- // Use of this source code is governed by an MIT-style
- // license that can be found in the LICENSE file.
- package btree
- type BTree struct {
- base *BTreeG[any]
- }
- // New returns a new BTree
- func New(less func(a, b any) bool) *BTree {
- if less == nil {
- panic("nil less")
- }
- return &BTree{
- base: NewBTreeG(less),
- }
- }
- // NewNonConcurrent returns a new BTree which is not safe for concurrent
- // write operations by multiple goroutines.
- //
- // This is useful for when you do not need the BTree to manage the locking,
- // but would rather do it yourself.
- func NewNonConcurrent(less func(a, b any) bool) *BTree {
- if less == nil {
- panic("nil less")
- }
- return &BTree{
- base: NewBTreeGOptions(less,
- Options{
- NoLocks: true,
- }),
- }
- }
- // Less is a convenience function that performs a comparison of two items
- // using the same "less" function provided to New.
- func (tr *BTree) Less(a, b any) bool {
- return tr.base.Less(a, b)
- }
- // Set or replace a value for a key
- // Returns the value for the replaced item or nil if the key was not found.
- func (tr *BTree) Set(item any) (prev any) {
- return tr.SetHint(item, nil)
- }
- // SetHint sets or replace a value for a key using a path hint
- // Returns the value for the replaced item or nil if the key was not found.
- func (tr *BTree) SetHint(item any, hint *PathHint) (prev any) {
- if item == nil {
- panic("nil item")
- }
- v, ok := tr.base.SetHint(item, hint)
- if !ok {
- return nil
- }
- return v
- }
- // Get a value for key.
- // Returns nil if the key was not found.
- func (tr *BTree) Get(key any) any {
- return tr.GetHint(key, nil)
- }
- // GetHint gets a value for key using a path hint.
- // Returns nil if the item was not found.
- func (tr *BTree) GetHint(key any, hint *PathHint) (value any) {
- if key == nil {
- return nil
- }
- v, ok := tr.base.GetHint(key, hint)
- if !ok {
- return nil
- }
- return v
- }
- // Len returns the number of items in the tree
- func (tr *BTree) Len() int {
- return tr.base.Len()
- }
- // Delete an item for a key.
- // Returns the deleted value or nil if the key was not found.
- func (tr *BTree) Delete(key any) (prev any) {
- return tr.DeleteHint(key, nil)
- }
- // DeleteHint deletes a value for a key using a path hint
- // Returns the deleted value or nil if the key was not found.
- func (tr *BTree) DeleteHint(key any, hint *PathHint) (prev any) {
- if key == nil {
- return nil
- }
- v, ok := tr.base.DeleteHint(key, nil)
- if !ok {
- return nil
- }
- return v
- }
- // Ascend the tree within the range [pivot, last]
- // Pass nil for pivot to scan all item in ascending order
- // Return false to stop iterating
- func (tr *BTree) Ascend(pivot any, iter func(item any) bool) {
- if pivot == nil {
- tr.base.Scan(iter)
- } else {
- tr.base.Ascend(pivot, iter)
- }
- }
- // Descend the tree within the range [pivot, first]
- // Pass nil for pivot to scan all item in descending order
- // Return false to stop iterating
- func (tr *BTree) Descend(pivot any, iter func(item any) bool) {
- if pivot == nil {
- tr.base.Reverse(iter)
- } else {
- tr.base.Descend(pivot, iter)
- }
- }
- // Load is for bulk loading pre-sorted items
- // If the load replaces and existing item then the value for the replaced item
- // is returned.
- func (tr *BTree) Load(item any) (prev any) {
- if item == nil {
- panic("nil item")
- }
- v, ok := tr.base.Load(item)
- if !ok {
- return nil
- }
- return v
- }
- // Min returns the minimum item in tree.
- // Returns nil if the tree has no items.
- func (tr *BTree) Min() any {
- v, ok := tr.base.Min()
- if !ok {
- return nil
- }
- return v
- }
- // Max returns the maximum item in tree.
- // Returns nil if the tree has no items.
- func (tr *BTree) Max() any {
- v, ok := tr.base.Max()
- if !ok {
- return nil
- }
- return v
- }
- // PopMin removes the minimum item in tree and returns it.
- // Returns nil if the tree has no items.
- func (tr *BTree) PopMin() any {
- v, ok := tr.base.PopMin()
- if !ok {
- return nil
- }
- return v
- }
- // PopMax removes the maximum item in tree and returns it.
- // Returns nil if the tree has no items.
- func (tr *BTree) PopMax() any {
- v, ok := tr.base.PopMax()
- if !ok {
- return nil
- }
- return v
- }
- // GetAt returns the value at index.
- // Return nil if the tree is empty or the index is out of bounds.
- func (tr *BTree) GetAt(index int) any {
- v, ok := tr.base.GetAt(index)
- if !ok {
- return nil
- }
- return v
- }
- // DeleteAt deletes the item at index.
- // Return nil if the tree is empty or the index is out of bounds.
- func (tr *BTree) DeleteAt(index int) any {
- v, ok := tr.base.DeleteAt(index)
- if !ok {
- return nil
- }
- return v
- }
- // Height returns the height of the tree.
- // Returns zero if tree has no items.
- func (tr *BTree) Height() int {
- return tr.base.Height()
- }
- // Walk iterates over all items in tree, in order.
- // The items param will contain one or more items.
- func (tr *BTree) Walk(iter func(items []any)) {
- tr.base.Walk(func(items []any) bool {
- iter(items)
- return true
- })
- }
- // Copy the tree. This is a copy-on-write operation and is very fast because
- // it only performs a shadowed copy.
- func (tr *BTree) Copy() *BTree {
- return &BTree{base: tr.base.Copy()}
- }
- type Iter struct {
- base GenericIter[any]
- }
- // Iter returns a read-only iterator.
- // The Release method must be called finished with iterator.
- func (tr *BTree) Iter() Iter {
- return Iter{tr.base.Iter()}
- }
- // Seek to item greater-or-equal-to key.
- // Returns false if there was no item found.
- func (iter *Iter) Seek(key any) bool {
- return iter.base.Seek(key)
- }
- // First moves iterator to first item in tree.
- // Returns false if the tree is empty.
- func (iter *Iter) First() bool {
- return iter.base.First()
- }
- // Last moves iterator to last item in tree.
- // Returns false if the tree is empty.
- func (iter *Iter) Last() bool {
- return iter.base.Last()
- }
- // First moves iterator to first item in tree.
- // Returns false if the tree is empty.
- func (iter *Iter) Release() {
- iter.base.Release()
- }
- // Next moves iterator to the next item in iterator.
- // Returns false if the tree is empty or the iterator is at the end of
- // the tree.
- func (iter *Iter) Next() bool {
- return iter.base.Next()
- }
- // Prev moves iterator to the previous item in iterator.
- // Returns false if the tree is empty or the iterator is at the beginning of
- // the tree.
- func (iter *Iter) Prev() bool {
- return iter.base.Prev()
- }
- // Item returns the current iterator item.
- func (iter *Iter) Item() any {
- return iter.base.Item()
- }
|