Commit 7fbd77cb authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent cdd85527
......@@ -27,6 +27,8 @@
//
// BTree.FirstBucket() and Bucket.Next() allow to iterate through leaf B⁺ tree nodes.
//
// BTree.V<op>(..., visit) performs <op> with calling visit on every accessed tree node.
//
// --------
//
// (*) https://github.com/zopefoundation/ZODB/blob/3.10.7-4-gb8d7a8567/src/BTrees/Development.txt#L211
......
......@@ -153,16 +153,13 @@ func (b *Bucket) Next() *Bucket {
//
// t need not be activated beforehand for Get to work.
func (t *BTree) Get(ctx context.Context, key KEY) (_ interface{}, _ bool, err error) {
return t.GetTo(ctx, key, nil)
return t.VGet(ctx, key, nil)
}
// GetTo searches BTree by key and visits btree-path nodes.
//
// It is similar to Get, but additionally calls visit on every BTree node
// (BTree or Bucket) it traverses from root to leaf to find the key.
// VGet is like Get but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *BTree) GetTo(ctx context.Context, key KEY, visit func(node zodb.IPersistent)) (_ interface{}, _ bool, err error) {
func (t *BTree) VGet(ctx context.Context, key KEY, visit func(node zodb.IPersistent)) (_ interface{}, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key)
err = t.PActivate(ctx)
if err != nil {
......@@ -234,12 +231,23 @@ func (b *Bucket) Get(key KEY) (interface{}, bool) {
// If the tree is empty, ok=false is returned.
// The tree does not need to be activated beforehand.
func (t *BTree) MinKey(ctx context.Context) (_ KEY, ok bool, err error) {
return t.VMinKey(ctx, nil)
}
// VMinKey is like MinKey but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *BTree) VMinKey(ctx context.Context, visit func(node zodb.IPersistent)) (_ KEY, ok bool, err error) {
defer xerr.Contextf(&err, "btree(%s): minkey", t.POid())
err = t.PActivate(ctx)
if err != nil {
return 0, false, err
}
if visit != nil {
visit(t)
}
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
......@@ -255,6 +263,10 @@ func (t *BTree) MinKey(ctx context.Context) (_ KEY, ok bool, err error) {
return 0, false, err
}
if visit != nil {
visit(child)
}
switch child := child.(type) {
case *BTree:
t = child
......@@ -272,12 +284,23 @@ func (t *BTree) MinKey(ctx context.Context) (_ KEY, ok bool, err error) {
// If the tree is empty, ok=false is returned.
// The tree does not need to be activated beforehand.
func (t *BTree) MaxKey(ctx context.Context) (_ KEY, _ bool, err error) {
return t.VMaxKey(ctx, nil)
}
// VMaxKey is like MaxKey but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *BTree) VMaxKey(ctx context.Context, visit func(node zodb.IPersistent)) (_ KEY, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid())
err = t.PActivate(ctx)
if err != nil {
return 0, false, err
}
if visit != nil {
visit(t)
}
l := len(t.data)
if l == 0 {
// empty btree
......@@ -293,6 +316,10 @@ func (t *BTree) MaxKey(ctx context.Context) (_ KEY, _ bool, err error) {
return 0, false, err
}
if visit != nil {
visit(child)
}
switch child := child.(type) {
case *BTree:
t = child
......
......@@ -155,16 +155,13 @@ func (b *IOBucket) Next() *IOBucket {
//
// t need not be activated beforehand for Get to work.
func (t *IOBTree) Get(ctx context.Context, key int32) (_ interface{}, _ bool, err error) {
return t.GetTo(ctx, key, nil)
return t.VGet(ctx, key, nil)
}
// GetTo searches IOBTree by key and visits btree-path nodes.
//
// It is similar to Get, but additionally calls visit on every IOBTree node
// (IOBTree or IOBucket) it traverses from root to leaf to find the key.
// VGet is like Get but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *IOBTree) GetTo(ctx context.Context, key int32, visit func(node zodb.IPersistent)) (_ interface{}, _ bool, err error) {
func (t *IOBTree) VGet(ctx context.Context, key int32, visit func(node zodb.IPersistent)) (_ interface{}, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key)
err = t.PActivate(ctx)
if err != nil {
......@@ -236,12 +233,23 @@ func (b *IOBucket) Get(key int32) (interface{}, bool) {
// If the tree is empty, ok=false is returned.
// The tree does not need to be activated beforehand.
func (t *IOBTree) MinKey(ctx context.Context) (_ int32, ok bool, err error) {
return t.VMinKey(ctx, nil)
}
// VMinKey is like MinKey but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *IOBTree) VMinKey(ctx context.Context, visit func(node zodb.IPersistent)) (_ int32, ok bool, err error) {
defer xerr.Contextf(&err, "btree(%s): minkey", t.POid())
err = t.PActivate(ctx)
if err != nil {
return 0, false, err
}
if visit != nil {
visit(t)
}
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
......@@ -257,6 +265,10 @@ func (t *IOBTree) MinKey(ctx context.Context) (_ int32, ok bool, err error) {
return 0, false, err
}
if visit != nil {
visit(child)
}
switch child := child.(type) {
case *IOBTree:
t = child
......@@ -274,12 +286,23 @@ func (t *IOBTree) MinKey(ctx context.Context) (_ int32, ok bool, err error) {
// If the tree is empty, ok=false is returned.
// The tree does not need to be activated beforehand.
func (t *IOBTree) MaxKey(ctx context.Context) (_ int32, _ bool, err error) {
return t.VMaxKey(ctx, nil)
}
// VMaxKey is like MaxKey but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *IOBTree) VMaxKey(ctx context.Context, visit func(node zodb.IPersistent)) (_ int32, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid())
err = t.PActivate(ctx)
if err != nil {
return 0, false, err
}
if visit != nil {
visit(t)
}
l := len(t.data)
if l == 0 {
// empty btree
......@@ -295,6 +318,10 @@ func (t *IOBTree) MaxKey(ctx context.Context) (_ int32, _ bool, err error) {
return 0, false, err
}
if visit != nil {
visit(child)
}
switch child := child.(type) {
case *IOBTree:
t = child
......
......@@ -155,16 +155,13 @@ func (b *LOBucket) Next() *LOBucket {
//
// t need not be activated beforehand for Get to work.
func (t *LOBTree) Get(ctx context.Context, key int64) (_ interface{}, _ bool, err error) {
return t.GetTo(ctx, key, nil)
return t.VGet(ctx, key, nil)
}
// GetTo searches LOBTree by key and visits btree-path nodes.
//
// It is similar to Get, but additionally calls visit on every LOBTree node
// (LOBTree or LOBucket) it traverses from root to leaf to find the key.
// VGet is like Get but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *LOBTree) GetTo(ctx context.Context, key int64, visit func(node zodb.IPersistent)) (_ interface{}, _ bool, err error) {
func (t *LOBTree) VGet(ctx context.Context, key int64, visit func(node zodb.IPersistent)) (_ interface{}, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key)
err = t.PActivate(ctx)
if err != nil {
......@@ -236,12 +233,23 @@ func (b *LOBucket) Get(key int64) (interface{}, bool) {
// If the tree is empty, ok=false is returned.
// The tree does not need to be activated beforehand.
func (t *LOBTree) MinKey(ctx context.Context) (_ int64, ok bool, err error) {
return t.VMinKey(ctx, nil)
}
// VMinKey is like MinKey but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *LOBTree) VMinKey(ctx context.Context, visit func(node zodb.IPersistent)) (_ int64, ok bool, err error) {
defer xerr.Contextf(&err, "btree(%s): minkey", t.POid())
err = t.PActivate(ctx)
if err != nil {
return 0, false, err
}
if visit != nil {
visit(t)
}
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
......@@ -257,6 +265,10 @@ func (t *LOBTree) MinKey(ctx context.Context) (_ int64, ok bool, err error) {
return 0, false, err
}
if visit != nil {
visit(child)
}
switch child := child.(type) {
case *LOBTree:
t = child
......@@ -274,12 +286,23 @@ func (t *LOBTree) MinKey(ctx context.Context) (_ int64, ok bool, err error) {
// If the tree is empty, ok=false is returned.
// The tree does not need to be activated beforehand.
func (t *LOBTree) MaxKey(ctx context.Context) (_ int64, _ bool, err error) {
return t.VMaxKey(ctx, nil)
}
// VMaxKey is like MaxKey but also calls visit while traversing the tree.
//
// Visit is called with node being activated.
func (t *LOBTree) VMaxKey(ctx context.Context, visit func(node zodb.IPersistent)) (_ int64, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid())
err = t.PActivate(ctx)
if err != nil {
return 0, false, err
}
if visit != nil {
visit(t)
}
l := len(t.data)
if l == 0 {
// empty btree
......@@ -295,6 +318,10 @@ func (t *LOBTree) MaxKey(ctx context.Context) (_ int64, _ bool, err error) {
return 0, false, err
}
if visit != nil {
visit(child)
}
switch child := child.(type) {
case *LOBTree:
t = child
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment