cubefs/metanode/btree.go
Victor1319 abe516dbfc enhance: support to bind target ip when start start service
Signed-off-by: Victor1319 <834863182@qq.com>
2023-03-06 11:39:42 +08:00

175 lines
3.8 KiB
Go

// Copyright 2018 The CubeFS Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.
package metanode
import (
"sync"
"github.com/cubefs/cubefs/util/btree"
)
const defaultBTreeDegree = 32
type (
// BtreeItem type alias google btree Item
BtreeItem = btree.Item
)
// BTree is the wrapper of Google's btree.
type BTree struct {
sync.RWMutex
tree *btree.BTree
}
// NewBtree creates a new btree.
func NewBtree() *BTree {
return &BTree{
tree: btree.New(defaultBTreeDegree),
}
}
// Get returns the object of the given key in the btree.
func (b *BTree) Get(key BtreeItem) (item BtreeItem) {
b.RLock()
item = b.tree.Get(key)
b.RUnlock()
return
}
func (b *BTree) CopyGet(key BtreeItem) (item BtreeItem) {
b.Lock()
item = b.tree.CopyGet(key)
b.Unlock()
return
}
// Find searches for the given key in the btree.
func (b *BTree) Find(key BtreeItem, fn func(i BtreeItem)) {
b.RLock()
item := b.tree.Get(key)
b.RUnlock()
if item == nil {
return
}
fn(item)
}
func (b *BTree) CopyFind(key BtreeItem, fn func(i BtreeItem)) {
b.Lock()
item := b.tree.CopyGet(key)
fn(item)
b.Unlock()
}
// Has checks if the key exists in the btree.
func (b *BTree) Has(key BtreeItem) (ok bool) {
b.RLock()
ok = b.tree.Has(key)
b.RUnlock()
return
}
// Delete deletes the object by the given key.
func (b *BTree) Delete(key BtreeItem) (item BtreeItem) {
b.Lock()
item = b.tree.Delete(key)
b.Unlock()
return
}
func (b *BTree) Execute(fn func(tree *btree.BTree) interface{}) interface{} {
b.Lock()
defer b.Unlock()
return fn(b.tree)
}
// ReplaceOrInsert is the wrapper of google's btree ReplaceOrInsert.
func (b *BTree) ReplaceOrInsert(key BtreeItem, replace bool) (item BtreeItem, ok bool) {
b.Lock()
if replace {
item = b.tree.ReplaceOrInsert(key)
b.Unlock()
ok = true
return
}
item = b.tree.Get(key)
if item == nil {
item = b.tree.ReplaceOrInsert(key)
b.Unlock()
ok = true
return
}
ok = false
b.Unlock()
return
}
// Ascend is the wrapper of the google's btree Ascend.
// This function scans the entire btree. When the data is huge, it is not recommended to use this function online.
// Instead, it is recommended to call GetTree to obtain the snapshot of the current btree, and then do the scan on the snapshot.
func (b *BTree) Ascend(fn func(i BtreeItem) bool) {
b.RLock()
b.tree.Ascend(fn)
b.RUnlock()
}
// AscendRange is the wrapper of the google's btree AscendRange.
func (b *BTree) AscendRange(greaterOrEqual, lessThan BtreeItem, iterator func(i BtreeItem) bool) {
b.RLock()
b.tree.AscendRange(greaterOrEqual, lessThan, iterator)
b.RUnlock()
}
// AscendGreaterOrEqual is the wrapper of the google's btree AscendGreaterOrEqual
func (b *BTree) AscendGreaterOrEqual(pivot BtreeItem, iterator func(i BtreeItem) bool) {
b.RLock()
b.tree.AscendGreaterOrEqual(pivot, iterator)
b.RUnlock()
}
// GetTree returns the snapshot of a btree.
func (b *BTree) GetTree() *BTree {
b.Lock()
t := b.tree.Clone()
b.Unlock()
nb := NewBtree()
nb.tree = t
return nb
}
// Reset resets the current btree.
func (b *BTree) Reset() {
b.Lock()
b.tree.Clear(true)
b.Unlock()
}
// Len returns the total number of items in the btree.
func (b *BTree) Len() (size int) {
b.RLock()
size = b.tree.Len()
b.RUnlock()
return
}
// MaxItem returns the largest item in the btree.
func (b *BTree) MaxItem() BtreeItem {
b.RLock()
item := b.tree.Max()
b.RUnlock()
return item
}