123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945 |
- // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
- //
- // This Source Code Form is subject to the terms of the MIT License.
- // If a copy of the MIT was not distributed with this file,
- // You can obtain one at https://github.com/gogf/gf.
- package gtree
- import (
- "bytes"
- "fmt"
- "github.com/gogf/gf/internal/json"
- "strings"
- "github.com/gogf/gf/util/gconv"
- "github.com/gogf/gf/container/gvar"
- "github.com/gogf/gf/internal/rwmutex"
- )
- // BTree holds elements of the B-tree.
- type BTree struct {
- mu rwmutex.RWMutex
- root *BTreeNode
- comparator func(v1, v2 interface{}) int
- size int // Total number of keys in the tree
- m int // order (maximum number of children)
- }
- // BTreeNode is a single element within the tree.
- type BTreeNode struct {
- Parent *BTreeNode
- Entries []*BTreeEntry // Contained keys in node
- Children []*BTreeNode // Children nodes
- }
- // BTreeEntry represents the key-value pair contained within nodes.
- type BTreeEntry struct {
- Key interface{}
- Value interface{}
- }
- // NewBTree instantiates a B-tree with <m> (maximum number of children) and a custom key comparator.
- // The parameter <safe> is used to specify whether using tree in concurrent-safety,
- // which is false in default.
- // Note that the <m> must be greater or equal than 3, or else it panics.
- func NewBTree(m int, comparator func(v1, v2 interface{}) int, safe ...bool) *BTree {
- if m < 3 {
- panic("Invalid order, should be at least 3")
- }
- return &BTree{
- comparator: comparator,
- mu: rwmutex.Create(safe...),
- m: m,
- }
- }
- // NewBTreeFrom instantiates a B-tree with <m> (maximum number of children), a custom key comparator and data map.
- // The parameter <safe> is used to specify whether using tree in concurrent-safety,
- // which is false in default.
- func NewBTreeFrom(m int, comparator func(v1, v2 interface{}) int, data map[interface{}]interface{}, safe ...bool) *BTree {
- tree := NewBTree(m, comparator, safe...)
- for k, v := range data {
- tree.doSet(k, v)
- }
- return tree
- }
- // Clone returns a new tree with a copy of current tree.
- func (tree *BTree) Clone() *BTree {
- newTree := NewBTree(tree.m, tree.comparator, tree.mu.IsSafe())
- newTree.Sets(tree.Map())
- return newTree
- }
- // Set inserts key-value item into the tree.
- func (tree *BTree) Set(key interface{}, value interface{}) {
- tree.mu.Lock()
- defer tree.mu.Unlock()
- tree.doSet(key, value)
- }
- // doSet inserts key-value pair node into the tree.
- // If key already exists, then its value is updated with the new value.
- func (tree *BTree) doSet(key interface{}, value interface{}) {
- entry := &BTreeEntry{Key: key, Value: value}
- if tree.root == nil {
- tree.root = &BTreeNode{Entries: []*BTreeEntry{entry}, Children: []*BTreeNode{}}
- tree.size++
- return
- }
- if tree.insert(tree.root, entry) {
- tree.size++
- }
- }
- // Sets batch sets key-values to the tree.
- func (tree *BTree) Sets(data map[interface{}]interface{}) {
- tree.mu.Lock()
- defer tree.mu.Unlock()
- for k, v := range data {
- tree.doSet(k, v)
- }
- }
- // Get searches the node in the tree by <key> and returns its value or nil if key is not found in tree.
- func (tree *BTree) Get(key interface{}) (value interface{}) {
- value, _ = tree.Search(key)
- return
- }
- // doSetWithLockCheck checks whether value of the key exists with mutex.Lock,
- // if not exists, set value to the map with given <key>,
- // or else just return the existing value.
- //
- // When setting value, if <value> is type of <func() interface {}>,
- // it will be executed with mutex.Lock of the hash map,
- // and its return value will be set to the map with <key>.
- //
- // It returns value with given <key>.
- func (tree *BTree) doSetWithLockCheck(key interface{}, value interface{}) interface{} {
- tree.mu.Lock()
- defer tree.mu.Unlock()
- if entry := tree.doSearch(key); entry != nil {
- return entry.Value
- }
- if f, ok := value.(func() interface{}); ok {
- value = f()
- }
- if value != nil {
- tree.doSet(key, value)
- }
- return value
- }
- // GetOrSet returns the value by key,
- // or sets value with given <value> if it does not exist and then returns this value.
- func (tree *BTree) GetOrSet(key interface{}, value interface{}) interface{} {
- if v, ok := tree.Search(key); !ok {
- return tree.doSetWithLockCheck(key, value)
- } else {
- return v
- }
- }
- // GetOrSetFunc returns the value by key,
- // or sets value with returned value of callback function <f> if it does not exist
- // and then returns this value.
- func (tree *BTree) GetOrSetFunc(key interface{}, f func() interface{}) interface{} {
- if v, ok := tree.Search(key); !ok {
- return tree.doSetWithLockCheck(key, f())
- } else {
- return v
- }
- }
- // GetOrSetFuncLock returns the value by key,
- // or sets value with returned value of callback function <f> if it does not exist
- // and then returns this value.
- //
- // GetOrSetFuncLock differs with GetOrSetFunc function is that it executes function <f>
- // with mutex.Lock of the hash map.
- func (tree *BTree) GetOrSetFuncLock(key interface{}, f func() interface{}) interface{} {
- if v, ok := tree.Search(key); !ok {
- return tree.doSetWithLockCheck(key, f)
- } else {
- return v
- }
- }
- // GetVar returns a gvar.Var with the value by given <key>.
- // The returned gvar.Var is un-concurrent safe.
- func (tree *BTree) GetVar(key interface{}) *gvar.Var {
- return gvar.New(tree.Get(key))
- }
- // GetVarOrSet returns a gvar.Var with result from GetVarOrSet.
- // The returned gvar.Var is un-concurrent safe.
- func (tree *BTree) GetVarOrSet(key interface{}, value interface{}) *gvar.Var {
- return gvar.New(tree.GetOrSet(key, value))
- }
- // GetVarOrSetFunc returns a gvar.Var with result from GetOrSetFunc.
- // The returned gvar.Var is un-concurrent safe.
- func (tree *BTree) GetVarOrSetFunc(key interface{}, f func() interface{}) *gvar.Var {
- return gvar.New(tree.GetOrSetFunc(key, f))
- }
- // GetVarOrSetFuncLock returns a gvar.Var with result from GetOrSetFuncLock.
- // The returned gvar.Var is un-concurrent safe.
- func (tree *BTree) GetVarOrSetFuncLock(key interface{}, f func() interface{}) *gvar.Var {
- return gvar.New(tree.GetOrSetFuncLock(key, f))
- }
- // SetIfNotExist sets <value> to the map if the <key> does not exist, and then returns true.
- // It returns false if <key> exists, and <value> would be ignored.
- func (tree *BTree) SetIfNotExist(key interface{}, value interface{}) bool {
- if !tree.Contains(key) {
- tree.doSetWithLockCheck(key, value)
- return true
- }
- return false
- }
- // SetIfNotExistFunc sets value with return value of callback function <f>, and then returns true.
- // It returns false if <key> exists, and <value> would be ignored.
- func (tree *BTree) SetIfNotExistFunc(key interface{}, f func() interface{}) bool {
- if !tree.Contains(key) {
- tree.doSetWithLockCheck(key, f())
- return true
- }
- return false
- }
- // SetIfNotExistFuncLock sets value with return value of callback function <f>, and then returns true.
- // It returns false if <key> exists, and <value> would be ignored.
- //
- // SetIfNotExistFuncLock differs with SetIfNotExistFunc function is that
- // it executes function <f> with mutex.Lock of the hash map.
- func (tree *BTree) SetIfNotExistFuncLock(key interface{}, f func() interface{}) bool {
- if !tree.Contains(key) {
- tree.doSetWithLockCheck(key, f)
- return true
- }
- return false
- }
- // Contains checks whether <key> exists in the tree.
- func (tree *BTree) Contains(key interface{}) bool {
- _, ok := tree.Search(key)
- return ok
- }
- // Remove remove the node from the tree by key.
- // Key should adhere to the comparator's type assertion, otherwise method panics.
- func (tree *BTree) doRemove(key interface{}) (value interface{}) {
- node, index, found := tree.searchRecursively(tree.root, key)
- if found {
- value = node.Entries[index].Value
- tree.delete(node, index)
- tree.size--
- }
- return
- }
- // Remove removes the node from the tree by <key>.
- func (tree *BTree) Remove(key interface{}) (value interface{}) {
- tree.mu.Lock()
- defer tree.mu.Unlock()
- return tree.doRemove(key)
- }
- // Removes batch deletes values of the tree by <keys>.
- func (tree *BTree) Removes(keys []interface{}) {
- tree.mu.Lock()
- defer tree.mu.Unlock()
- for _, key := range keys {
- tree.doRemove(key)
- }
- }
- // Empty returns true if tree does not contain any nodes
- func (tree *BTree) IsEmpty() bool {
- return tree.Size() == 0
- }
- // Size returns number of nodes in the tree.
- func (tree *BTree) Size() int {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- return tree.size
- }
- // Keys returns all keys in asc order.
- func (tree *BTree) Keys() []interface{} {
- keys := make([]interface{}, tree.Size())
- index := 0
- tree.IteratorAsc(func(key, value interface{}) bool {
- keys[index] = key
- index++
- return true
- })
- return keys
- }
- // Values returns all values in asc order based on the key.
- func (tree *BTree) Values() []interface{} {
- values := make([]interface{}, tree.Size())
- index := 0
- tree.IteratorAsc(func(key, value interface{}) bool {
- values[index] = value
- index++
- return true
- })
- return values
- }
- // Map returns all key-value items as map.
- func (tree *BTree) Map() map[interface{}]interface{} {
- m := make(map[interface{}]interface{}, tree.Size())
- tree.IteratorAsc(func(key, value interface{}) bool {
- m[key] = value
- return true
- })
- return m
- }
- // MapStrAny returns all key-value items as map[string]interface{}.
- func (tree *BTree) MapStrAny() map[string]interface{} {
- m := make(map[string]interface{}, tree.Size())
- tree.IteratorAsc(func(key, value interface{}) bool {
- m[gconv.String(key)] = value
- return true
- })
- return m
- }
- // Clear removes all nodes from the tree.
- func (tree *BTree) Clear() {
- tree.mu.Lock()
- defer tree.mu.Unlock()
- tree.root = nil
- tree.size = 0
- }
- // Replace the data of the tree with given <data>.
- func (tree *BTree) Replace(data map[interface{}]interface{}) {
- tree.mu.Lock()
- defer tree.mu.Unlock()
- tree.root = nil
- tree.size = 0
- for k, v := range data {
- tree.doSet(k, v)
- }
- }
- // Height returns the height of the tree.
- func (tree *BTree) Height() int {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- return tree.root.height()
- }
- // Left returns the left-most (min) entry or nil if tree is empty.
- func (tree *BTree) Left() *BTreeEntry {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- node := tree.left(tree.root)
- return node.Entries[0]
- }
- // Right returns the right-most (max) entry or nil if tree is empty.
- func (tree *BTree) Right() *BTreeEntry {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- node := tree.right(tree.root)
- return node.Entries[len(node.Entries)-1]
- }
- // String returns a string representation of container (for debugging purposes)
- func (tree *BTree) String() string {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- var buffer bytes.Buffer
- if tree.size != 0 {
- tree.output(&buffer, tree.root, 0, true)
- }
- return buffer.String()
- }
- // Search searches the tree with given <key>.
- // Second return parameter <found> is true if key was found, otherwise false.
- func (tree *BTree) Search(key interface{}) (value interface{}, found bool) {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- node, index, found := tree.searchRecursively(tree.root, key)
- if found {
- return node.Entries[index].Value, true
- }
- return nil, false
- }
- // Search searches the tree with given <key> without mutex.
- // It returns the entry if found or otherwise nil.
- func (tree *BTree) doSearch(key interface{}) *BTreeEntry {
- node, index, found := tree.searchRecursively(tree.root, key)
- if found {
- return node.Entries[index]
- }
- return nil
- }
- // Print prints the tree to stdout.
- func (tree *BTree) Print() {
- fmt.Println(tree.String())
- }
- // Iterator is alias of IteratorAsc.
- func (tree *BTree) Iterator(f func(key, value interface{}) bool) {
- tree.IteratorAsc(f)
- }
- // IteratorFrom is alias of IteratorAscFrom.
- func (tree *BTree) IteratorFrom(key interface{}, match bool, f func(key, value interface{}) bool) {
- tree.IteratorAscFrom(key, match, f)
- }
- // IteratorAsc iterates the tree readonly in ascending order with given callback function <f>.
- // If <f> returns true, then it continues iterating; or false to stop.
- func (tree *BTree) IteratorAsc(f func(key, value interface{}) bool) {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- node := tree.left(tree.root)
- if node == nil {
- return
- }
- tree.doIteratorAsc(node, node.Entries[0], 0, f)
- }
- // IteratorAscFrom iterates the tree readonly in ascending order with given callback function <f>.
- // The parameter <key> specifies the start entry for iterating. The <match> specifies whether
- // starting iterating if the <key> is fully matched, or else using index searching iterating.
- // If <f> returns true, then it continues iterating; or false to stop.
- func (tree *BTree) IteratorAscFrom(key interface{}, match bool, f func(key, value interface{}) bool) {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- node, index, found := tree.searchRecursively(tree.root, key)
- if match {
- if found {
- tree.doIteratorAsc(node, node.Entries[index], index, f)
- }
- } else {
- tree.doIteratorAsc(node, node.Entries[index], index, f)
- }
- }
- func (tree *BTree) doIteratorAsc(node *BTreeNode, entry *BTreeEntry, index int, f func(key, value interface{}) bool) {
- first := true
- loop:
- if entry == nil {
- return
- }
- if !f(entry.Key, entry.Value) {
- return
- }
- // Find current entry position in current node
- if !first {
- index, _ = tree.search(node, entry.Key)
- } else {
- first = false
- }
- // Try to go down to the child right of the current entry
- if index+1 < len(node.Children) {
- node = node.Children[index+1]
- // Try to go down to the child left of the current node
- for len(node.Children) > 0 {
- node = node.Children[0]
- }
- // Return the left-most entry
- entry = node.Entries[0]
- goto loop
- }
- // Above assures that we have reached a leaf node, so return the next entry in current node (if any)
- if index+1 < len(node.Entries) {
- entry = node.Entries[index+1]
- goto loop
- }
- // Reached leaf node and there are no entries to the right of the current entry, so go up to the parent
- for node.Parent != nil {
- node = node.Parent
- // Find next entry position in current node (note: search returns the first equal or bigger than entry)
- index, _ = tree.search(node, entry.Key)
- // Check that there is a next entry position in current node
- if index < len(node.Entries) {
- entry = node.Entries[index]
- goto loop
- }
- }
- }
- // IteratorDesc iterates the tree readonly in descending order with given callback function <f>.
- // If <f> returns true, then it continues iterating; or false to stop.
- func (tree *BTree) IteratorDesc(f func(key, value interface{}) bool) {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- node := tree.right(tree.root)
- if node == nil {
- return
- }
- index := len(node.Entries) - 1
- entry := node.Entries[index]
- tree.doIteratorDesc(node, entry, index, f)
- }
- // IteratorDescFrom iterates the tree readonly in descending order with given callback function <f>.
- // The parameter <key> specifies the start entry for iterating. The <match> specifies whether
- // starting iterating if the <key> is fully matched, or else using index searching iterating.
- // If <f> returns true, then it continues iterating; or false to stop.
- func (tree *BTree) IteratorDescFrom(key interface{}, match bool, f func(key, value interface{}) bool) {
- tree.mu.RLock()
- defer tree.mu.RUnlock()
- node, index, found := tree.searchRecursively(tree.root, key)
- if match {
- if found {
- tree.doIteratorDesc(node, node.Entries[index], index, f)
- }
- } else {
- tree.doIteratorDesc(node, node.Entries[index], index, f)
- }
- }
- // IteratorDesc iterates the tree readonly in descending order with given callback function <f>.
- // If <f> returns true, then it continues iterating; or false to stop.
- func (tree *BTree) doIteratorDesc(node *BTreeNode, entry *BTreeEntry, index int, f func(key, value interface{}) bool) {
- first := true
- loop:
- if entry == nil {
- return
- }
- if !f(entry.Key, entry.Value) {
- return
- }
- // Find current entry position in current node
- if !first {
- index, _ = tree.search(node, entry.Key)
- } else {
- first = false
- }
- // Try to go down to the child left of the current entry
- if index < len(node.Children) {
- node = node.Children[index]
- // Try to go down to the child right of the current node
- for len(node.Children) > 0 {
- node = node.Children[len(node.Children)-1]
- }
- // Return the right-most entry
- entry = node.Entries[len(node.Entries)-1]
- goto loop
- }
- // Above assures that we have reached a leaf node, so return the previous entry in current node (if any)
- if index-1 >= 0 {
- entry = node.Entries[index-1]
- goto loop
- }
- // Reached leaf node and there are no entries to the left of the current entry, so go up to the parent
- for node.Parent != nil {
- node = node.Parent
- // Find previous entry position in current node (note: search returns the first equal or bigger than entry)
- index, _ = tree.search(node, entry.Key)
- // Check that there is a previous entry position in current node
- if index-1 >= 0 {
- entry = node.Entries[index-1]
- goto loop
- }
- }
- }
- func (tree *BTree) output(buffer *bytes.Buffer, node *BTreeNode, level int, isTail bool) {
- for e := 0; e < len(node.Entries)+1; e++ {
- if e < len(node.Children) {
- tree.output(buffer, node.Children[e], level+1, true)
- }
- if e < len(node.Entries) {
- if _, err := buffer.WriteString(strings.Repeat(" ", level)); err != nil {
- }
- if _, err := buffer.WriteString(fmt.Sprintf("%v", node.Entries[e].Key) + "\n"); err != nil {
- }
- }
- }
- }
- func (node *BTreeNode) height() int {
- h := 0
- n := node
- for ; n != nil; n = n.Children[0] {
- h++
- if len(n.Children) == 0 {
- break
- }
- }
- return h
- }
- func (tree *BTree) isLeaf(node *BTreeNode) bool {
- return len(node.Children) == 0
- }
- //func (tree *BTree) isFull(node *BTreeNode) bool {
- // return len(node.Entries) == tree.maxEntries()
- //}
- func (tree *BTree) shouldSplit(node *BTreeNode) bool {
- return len(node.Entries) > tree.maxEntries()
- }
- func (tree *BTree) maxChildren() int {
- return tree.m
- }
- func (tree *BTree) minChildren() int {
- return (tree.m + 1) / 2 // ceil(m/2)
- }
- func (tree *BTree) maxEntries() int {
- return tree.maxChildren() - 1
- }
- func (tree *BTree) minEntries() int {
- return tree.minChildren() - 1
- }
- func (tree *BTree) middle() int {
- // "-1" to favor right nodes to have more keys when splitting
- return (tree.m - 1) / 2
- }
- // search searches only within the single node among its entries
- func (tree *BTree) search(node *BTreeNode, key interface{}) (index int, found bool) {
- low, mid, high := 0, 0, len(node.Entries)-1
- for low <= high {
- mid = low + int((high-low)/2)
- compare := tree.getComparator()(key, node.Entries[mid].Key)
- switch {
- case compare > 0:
- low = mid + 1
- case compare < 0:
- high = mid - 1
- case compare == 0:
- return mid, true
- }
- }
- return low, false
- }
- // searchRecursively searches recursively down the tree starting at the startNode
- func (tree *BTree) searchRecursively(startNode *BTreeNode, key interface{}) (node *BTreeNode, index int, found bool) {
- if tree.size == 0 {
- return nil, -1, false
- }
- node = startNode
- for {
- index, found = tree.search(node, key)
- if found {
- return node, index, true
- }
- if tree.isLeaf(node) {
- return node, index, false
- }
- node = node.Children[index]
- }
- }
- func (tree *BTree) insert(node *BTreeNode, entry *BTreeEntry) (inserted bool) {
- if tree.isLeaf(node) {
- return tree.insertIntoLeaf(node, entry)
- }
- return tree.insertIntoInternal(node, entry)
- }
- func (tree *BTree) insertIntoLeaf(node *BTreeNode, entry *BTreeEntry) (inserted bool) {
- insertPosition, found := tree.search(node, entry.Key)
- if found {
- node.Entries[insertPosition] = entry
- return false
- }
- // Insert entry's key in the middle of the node
- node.Entries = append(node.Entries, nil)
- copy(node.Entries[insertPosition+1:], node.Entries[insertPosition:])
- node.Entries[insertPosition] = entry
- tree.split(node)
- return true
- }
- func (tree *BTree) insertIntoInternal(node *BTreeNode, entry *BTreeEntry) (inserted bool) {
- insertPosition, found := tree.search(node, entry.Key)
- if found {
- node.Entries[insertPosition] = entry
- return false
- }
- return tree.insert(node.Children[insertPosition], entry)
- }
- func (tree *BTree) split(node *BTreeNode) {
- if !tree.shouldSplit(node) {
- return
- }
- if node == tree.root {
- tree.splitRoot()
- return
- }
- tree.splitNonRoot(node)
- }
- func (tree *BTree) splitNonRoot(node *BTreeNode) {
- middle := tree.middle()
- parent := node.Parent
- left := &BTreeNode{Entries: append([]*BTreeEntry(nil), node.Entries[:middle]...), Parent: parent}
- right := &BTreeNode{Entries: append([]*BTreeEntry(nil), node.Entries[middle+1:]...), Parent: parent}
- // Move children from the node to be split into left and right nodes
- if !tree.isLeaf(node) {
- left.Children = append([]*BTreeNode(nil), node.Children[:middle+1]...)
- right.Children = append([]*BTreeNode(nil), node.Children[middle+1:]...)
- setParent(left.Children, left)
- setParent(right.Children, right)
- }
- insertPosition, _ := tree.search(parent, node.Entries[middle].Key)
- // Insert middle key into parent
- parent.Entries = append(parent.Entries, nil)
- copy(parent.Entries[insertPosition+1:], parent.Entries[insertPosition:])
- parent.Entries[insertPosition] = node.Entries[middle]
- // Set child left of inserted key in parent to the created left node
- parent.Children[insertPosition] = left
- // Set child right of inserted key in parent to the created right node
- parent.Children = append(parent.Children, nil)
- copy(parent.Children[insertPosition+2:], parent.Children[insertPosition+1:])
- parent.Children[insertPosition+1] = right
- tree.split(parent)
- }
- func (tree *BTree) splitRoot() {
- middle := tree.middle()
- left := &BTreeNode{Entries: append([]*BTreeEntry(nil), tree.root.Entries[:middle]...)}
- right := &BTreeNode{Entries: append([]*BTreeEntry(nil), tree.root.Entries[middle+1:]...)}
- // Move children from the node to be split into left and right nodes
- if !tree.isLeaf(tree.root) {
- left.Children = append([]*BTreeNode(nil), tree.root.Children[:middle+1]...)
- right.Children = append([]*BTreeNode(nil), tree.root.Children[middle+1:]...)
- setParent(left.Children, left)
- setParent(right.Children, right)
- }
- // Root is a node with one entry and two children (left and right)
- newRoot := &BTreeNode{
- Entries: []*BTreeEntry{tree.root.Entries[middle]},
- Children: []*BTreeNode{left, right},
- }
- left.Parent = newRoot
- right.Parent = newRoot
- tree.root = newRoot
- }
- func setParent(nodes []*BTreeNode, parent *BTreeNode) {
- for _, node := range nodes {
- node.Parent = parent
- }
- }
- func (tree *BTree) left(node *BTreeNode) *BTreeNode {
- if tree.size == 0 {
- return nil
- }
- current := node
- for {
- if tree.isLeaf(current) {
- return current
- }
- current = current.Children[0]
- }
- }
- func (tree *BTree) right(node *BTreeNode) *BTreeNode {
- if tree.size == 0 {
- return nil
- }
- current := node
- for {
- if tree.isLeaf(current) {
- return current
- }
- current = current.Children[len(current.Children)-1]
- }
- }
- // leftSibling returns the node's left sibling and child index (in parent) if it exists, otherwise (nil,-1)
- // key is any of keys in node (could even be deleted).
- func (tree *BTree) leftSibling(node *BTreeNode, key interface{}) (*BTreeNode, int) {
- if node.Parent != nil {
- index, _ := tree.search(node.Parent, key)
- index--
- if index >= 0 && index < len(node.Parent.Children) {
- return node.Parent.Children[index], index
- }
- }
- return nil, -1
- }
- // rightSibling returns the node's right sibling and child index (in parent) if it exists, otherwise (nil,-1)
- // key is any of keys in node (could even be deleted).
- func (tree *BTree) rightSibling(node *BTreeNode, key interface{}) (*BTreeNode, int) {
- if node.Parent != nil {
- index, _ := tree.search(node.Parent, key)
- index++
- if index < len(node.Parent.Children) {
- return node.Parent.Children[index], index
- }
- }
- return nil, -1
- }
- // delete deletes an entry in node at entries' index
- // ref.: https://en.wikipedia.org/wiki/B-tree#Deletion
- func (tree *BTree) delete(node *BTreeNode, index int) {
- // deleting from a leaf node
- if tree.isLeaf(node) {
- deletedKey := node.Entries[index].Key
- tree.deleteEntry(node, index)
- tree.rebalance(node, deletedKey)
- if len(tree.root.Entries) == 0 {
- tree.root = nil
- }
- return
- }
- // deleting from an internal node
- leftLargestNode := tree.right(node.Children[index]) // largest node in the left sub-tree (assumed to exist)
- leftLargestEntryIndex := len(leftLargestNode.Entries) - 1
- node.Entries[index] = leftLargestNode.Entries[leftLargestEntryIndex]
- deletedKey := leftLargestNode.Entries[leftLargestEntryIndex].Key
- tree.deleteEntry(leftLargestNode, leftLargestEntryIndex)
- tree.rebalance(leftLargestNode, deletedKey)
- }
- // rebalance rebalances the tree after deletion if necessary and returns true, otherwise false.
- // Note that we first delete the entry and then call rebalance, thus the passed deleted key as reference.
- func (tree *BTree) rebalance(node *BTreeNode, deletedKey interface{}) {
- // check if rebalancing is needed
- if node == nil || len(node.Entries) >= tree.minEntries() {
- return
- }
- // try to borrow from left sibling
- leftSibling, leftSiblingIndex := tree.leftSibling(node, deletedKey)
- if leftSibling != nil && len(leftSibling.Entries) > tree.minEntries() {
- // rotate right
- node.Entries = append([]*BTreeEntry{node.Parent.Entries[leftSiblingIndex]}, node.Entries...) // prepend parent's separator entry to node's entries
- node.Parent.Entries[leftSiblingIndex] = leftSibling.Entries[len(leftSibling.Entries)-1]
- tree.deleteEntry(leftSibling, len(leftSibling.Entries)-1)
- if !tree.isLeaf(leftSibling) {
- leftSiblingRightMostChild := leftSibling.Children[len(leftSibling.Children)-1]
- leftSiblingRightMostChild.Parent = node
- node.Children = append([]*BTreeNode{leftSiblingRightMostChild}, node.Children...)
- tree.deleteChild(leftSibling, len(leftSibling.Children)-1)
- }
- return
- }
- // try to borrow from right sibling
- rightSibling, rightSiblingIndex := tree.rightSibling(node, deletedKey)
- if rightSibling != nil && len(rightSibling.Entries) > tree.minEntries() {
- // rotate left
- node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1]) // append parent's separator entry to node's entries
- node.Parent.Entries[rightSiblingIndex-1] = rightSibling.Entries[0]
- tree.deleteEntry(rightSibling, 0)
- if !tree.isLeaf(rightSibling) {
- rightSiblingLeftMostChild := rightSibling.Children[0]
- rightSiblingLeftMostChild.Parent = node
- node.Children = append(node.Children, rightSiblingLeftMostChild)
- tree.deleteChild(rightSibling, 0)
- }
- return
- }
- // merge with siblings
- if rightSibling != nil {
- // merge with right sibling
- node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1])
- node.Entries = append(node.Entries, rightSibling.Entries...)
- deletedKey = node.Parent.Entries[rightSiblingIndex-1].Key
- tree.deleteEntry(node.Parent, rightSiblingIndex-1)
- tree.appendChildren(node.Parent.Children[rightSiblingIndex], node)
- tree.deleteChild(node.Parent, rightSiblingIndex)
- } else if leftSibling != nil {
- // merge with left sibling
- entries := append([]*BTreeEntry(nil), leftSibling.Entries...)
- entries = append(entries, node.Parent.Entries[leftSiblingIndex])
- node.Entries = append(entries, node.Entries...)
- deletedKey = node.Parent.Entries[leftSiblingIndex].Key
- tree.deleteEntry(node.Parent, leftSiblingIndex)
- tree.prependChildren(node.Parent.Children[leftSiblingIndex], node)
- tree.deleteChild(node.Parent, leftSiblingIndex)
- }
- // make the merged node the root if its parent was the root and the root is empty
- if node.Parent == tree.root && len(tree.root.Entries) == 0 {
- tree.root = node
- node.Parent = nil
- return
- }
- // parent might underflow, so try to rebalance if necessary
- tree.rebalance(node.Parent, deletedKey)
- }
- func (tree *BTree) prependChildren(fromNode *BTreeNode, toNode *BTreeNode) {
- children := append([]*BTreeNode(nil), fromNode.Children...)
- toNode.Children = append(children, toNode.Children...)
- setParent(fromNode.Children, toNode)
- }
- func (tree *BTree) appendChildren(fromNode *BTreeNode, toNode *BTreeNode) {
- toNode.Children = append(toNode.Children, fromNode.Children...)
- setParent(fromNode.Children, toNode)
- }
- func (tree *BTree) deleteEntry(node *BTreeNode, index int) {
- copy(node.Entries[index:], node.Entries[index+1:])
- node.Entries[len(node.Entries)-1] = nil
- node.Entries = node.Entries[:len(node.Entries)-1]
- }
- func (tree *BTree) deleteChild(node *BTreeNode, index int) {
- if index >= len(node.Children) {
- return
- }
- copy(node.Children[index:], node.Children[index+1:])
- node.Children[len(node.Children)-1] = nil
- node.Children = node.Children[:len(node.Children)-1]
- }
- // MarshalJSON implements the interface MarshalJSON for json.Marshal.
- func (tree *BTree) MarshalJSON() ([]byte, error) {
- return json.Marshal(tree.Map())
- }
- // getComparator returns the comparator if it's previously set,
- // or else it panics.
- func (tree *BTree) getComparator() func(a, b interface{}) int {
- if tree.comparator == nil {
- panic("comparator is missing for tree")
- }
- return tree.comparator
- }
|