Commit 5a1077d8 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1742e47b
...@@ -153,19 +153,30 @@ func (b *Bucket) Next() *Bucket { ...@@ -153,19 +153,30 @@ func (b *Bucket) Next() *Bucket {
// //
// t need not be activated beforehand for Get to work. // t need not be activated beforehand for Get to work.
func (t *BTree) Get(ctx context.Context, key KEY) (_ interface{}, _ bool, err error) { func (t *BTree) Get(ctx context.Context, key KEY) (_ interface{}, _ bool, err error) {
v, ok, _, _, err := t.GetTo(ctx, key)
return v, ok, err
}
// GetTo searches BTree by key and returns value and path.
//
// It is similar to Get, but additionally provides information via which
// intermediate tree nodes and leaf bucket the key was found.
func (t *BTree) GetTo(ctx context.Context, key KEY) (_ interface{}, _ bool, path []*BTree, leaf *Bucket, err error) {
defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key) defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key)
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return nil, false, err return nil, false, nil, nil, err
} }
if len(t.data) == 0 { if len(t.data) == 0 {
// empty btree // empty btree
t.PDeactivate() t.PDeactivate()
return nil, false, nil return nil, false, nil, nil, nil
} }
for { for {
path = append(path, t)
// search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞ // search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞
i := sort.Search(len(t.data), func(i int) bool { i := sort.Search(len(t.data), func(i int) bool {
j := i + 1 j := i + 1
...@@ -181,12 +192,17 @@ func (t *BTree) Get(ctx context.Context, key KEY) (_ interface{}, _ bool, err er ...@@ -181,12 +192,17 @@ func (t *BTree) Get(ctx context.Context, key KEY) (_ interface{}, _ bool, err er
t = child t = child
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return nil, false, err return nil, false, nil, nil, err
} }
case *Bucket: case *Bucket:
t.PDeactivate() t.PDeactivate()
return child.Get(ctx, key) v, ok, err := child.Get(ctx, key)
if err != nil {
path = nil
child = nil
}
return v, ok, path, child, err
} }
} }
} }
......
...@@ -155,19 +155,30 @@ func (b *IOBucket) Next() *IOBucket { ...@@ -155,19 +155,30 @@ func (b *IOBucket) Next() *IOBucket {
// //
// t need not be activated beforehand for Get to work. // t need not be activated beforehand for Get to work.
func (t *IOBTree) Get(ctx context.Context, key int32) (_ interface{}, _ bool, err error) { func (t *IOBTree) Get(ctx context.Context, key int32) (_ interface{}, _ bool, err error) {
v, ok, _, _, err := t.GetTo(ctx, key)
return v, ok, err
}
// GetTo searches IOBTree by key and returns value and path.
//
// It is similar to Get, but additionally provides information via which
// intermediate tree nodes and leaf bucket the key was found.
func (t *IOBTree) GetTo(ctx context.Context, key int32) (_ interface{}, _ bool, path []*IOBTree, leaf *IOBucket, err error) {
defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key) defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key)
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return nil, false, err return nil, false, nil, nil, err
} }
if len(t.data) == 0 { if len(t.data) == 0 {
// empty btree // empty btree
t.PDeactivate() t.PDeactivate()
return nil, false, nil return nil, false, nil, nil, nil
} }
for { for {
path = append(path, t)
// search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞ // search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞
i := sort.Search(len(t.data), func(i int) bool { i := sort.Search(len(t.data), func(i int) bool {
j := i + 1 j := i + 1
...@@ -183,12 +194,17 @@ func (t *IOBTree) Get(ctx context.Context, key int32) (_ interface{}, _ bool, er ...@@ -183,12 +194,17 @@ func (t *IOBTree) Get(ctx context.Context, key int32) (_ interface{}, _ bool, er
t = child t = child
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return nil, false, err return nil, false, nil, nil, err
} }
case *IOBucket: case *IOBucket:
t.PDeactivate() t.PDeactivate()
return child.Get(ctx, key) v, ok, err := child.Get(ctx, key)
if err != nil {
path = nil
child = nil
}
return v, ok, path, child, err
} }
} }
} }
......
...@@ -155,19 +155,30 @@ func (b *LOBucket) Next() *LOBucket { ...@@ -155,19 +155,30 @@ func (b *LOBucket) Next() *LOBucket {
// //
// t need not be activated beforehand for Get to work. // t need not be activated beforehand for Get to work.
func (t *LOBTree) Get(ctx context.Context, key int64) (_ interface{}, _ bool, err error) { func (t *LOBTree) Get(ctx context.Context, key int64) (_ interface{}, _ bool, err error) {
v, ok, _, _, err := t.GetTo(ctx, key)
return v, ok, err
}
// GetTo searches LOBTree by key and returns value and path.
//
// It is similar to Get, but additionally provides information via which
// intermediate tree nodes and leaf bucket the key was found.
func (t *LOBTree) GetTo(ctx context.Context, key int64) (_ interface{}, _ bool, path []*LOBTree, leaf *LOBucket, err error) {
defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key) defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key)
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return nil, false, err return nil, false, nil, nil, err
} }
if len(t.data) == 0 { if len(t.data) == 0 {
// empty btree // empty btree
t.PDeactivate() t.PDeactivate()
return nil, false, nil return nil, false, nil, nil, nil
} }
for { for {
path = append(path, t)
// search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞ // search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞
i := sort.Search(len(t.data), func(i int) bool { i := sort.Search(len(t.data), func(i int) bool {
j := i + 1 j := i + 1
...@@ -183,12 +194,17 @@ func (t *LOBTree) Get(ctx context.Context, key int64) (_ interface{}, _ bool, er ...@@ -183,12 +194,17 @@ func (t *LOBTree) Get(ctx context.Context, key int64) (_ interface{}, _ bool, er
t = child t = child
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return nil, false, err return nil, false, nil, nil, err
} }
case *LOBucket: case *LOBucket:
t.PDeactivate() t.PDeactivate()
return child.Get(ctx, key) v, ok, err := child.Get(ctx, key)
if err != nil {
path = nil
child = nil
}
return v, ok, path, child, err
} }
} }
} }
......
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