Chris Lu
3 years ago
6 changed files with 193 additions and 28 deletions
-
60weed/util/bptree/README.md
-
4weed/util/bptree/bpmap.go
-
12weed/util/bptree/bptree.go
-
43weed/util/bptree/bptree_node.go
-
34weed/util/bptree/bptree_store_test.go
-
44weed/util/bptree/getter_setter.go
@ -0,0 +1,60 @@ |
|||
This adapts one b+ tree implementation |
|||
https://sourcegraph.com/github.com/timtadh/data-structures@master/-/tree/tree/bptree |
|||
to persist changes to on disk. |
|||
|
|||
# When a node needs to persist itself? |
|||
|
|||
* A node changed its key or value |
|||
* When an item is added. |
|||
* When an item is updated. |
|||
* When an item is deleted. |
|||
|
|||
* When a node is split. |
|||
* 2 new nodes are created (they shoud persist themselves). |
|||
* Parent node need to point to the new nodes. |
|||
|
|||
* When a node is merged. |
|||
* delete one node |
|||
* persist the merged node |
|||
|
|||
|
|||
In general, if one node is returned from a function, the node should have already been persisted. |
|||
The parent node may need to delete the old node. |
|||
|
|||
BpTree |
|||
Add(key ItemKey, value ItemValue) |
|||
new_root = self.getRoot().put(key,value) |
|||
a, b, err := self.insert(key, value) |
|||
self.internal_insert(key, value) |
|||
self.internal_split(q.keys[0], q) |
|||
persist(a,b) |
|||
self.persist() // child add q node |
|||
self.maybePersist(child == p) |
|||
self.leaf_insert(key, value) |
|||
self.persist() // if dedup |
|||
self.leaf_split(key, value) |
|||
self.pure_leaf_split(key, value) |
|||
persist(a,b) |
|||
a.persist() |
|||
persist(a,b) |
|||
self.put_kv(key, value) |
|||
new_root.persist() |
|||
self.setRoot(new_root) |
|||
oldroot.destroy() |
|||
// maybe persist BpTree new root |
|||
|
|||
Replace(key ItemKey, where WhereFunc, value ItemValue) |
|||
leaf.persist() |
|||
RemoveWhere(key ItemKey, where WhereFunc) |
|||
self.getRoot().remove(key, where) |
|||
self.internal_remove(key, nil, where) |
|||
child.leaf_remove(key, nil, where) |
|||
child.leaf_remove(key, sibling.keys[0], where) |
|||
l.destroy() // when the node is empty |
|||
a.maybePersist(hasChange) |
|||
self.destroy() // when no keys left |
|||
self.persist() // when some keys are left |
|||
self.leaf_remove(key, self.keys[len(self.keys)-1], where) |
|||
new_root.persist() // when new root is added |
|||
// maybe persist BpTree new root |
|||
|
@ -0,0 +1,34 @@ |
|||
package bptree |
|||
|
|||
import ( |
|||
"fmt" |
|||
"testing" |
|||
) |
|||
|
|||
func TestAddRemove(t *testing.T) { |
|||
tree := NewBpTree(32) |
|||
PersistFn = func(node *BpNode) error { |
|||
println("saving", node.protoNodeId) |
|||
return nil |
|||
} |
|||
DestroyFn = func(node *BpNode) error { |
|||
println("delete", node.protoNodeId) |
|||
return nil |
|||
} |
|||
for i:=0;i<1024;i++{ |
|||
println("++++++++++", i) |
|||
tree.Add(String(fmt.Sprintf("%02d", i)), String(fmt.Sprintf("%02d", i))) |
|||
printTree(tree.root, "") |
|||
} |
|||
} |
|||
|
|||
func printTree(node *BpNode, prefix string) { |
|||
fmt.Printf("%sNode %d\n", prefix, node.protoNodeId) |
|||
prefix += " " |
|||
for i:=0;i<len(node.keys);i++{ |
|||
fmt.Printf("%skey %s\n", prefix, node.keys[i]) |
|||
if i < len(node.pointers) && node.pointers[i] != nil { |
|||
printTree(node.pointers[i], prefix+" ") |
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue