Commit a7b82699 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent c5a0b724
...@@ -138,7 +138,7 @@ func (e *BucketEntry) Key() KEY { return e.key } ...@@ -138,7 +138,7 @@ func (e *BucketEntry) Key() KEY { return e.key }
func (e *BucketEntry) Value() interface{} { return e.value } func (e *BucketEntry) Value() interface{} { return e.value }
// Entryv returns entries of a Bucket node. // Entryv returns entries of a Bucket node.
func (b *Bucket) Entryv() []BucketEntry { func (b *Bucket) Entryv() /*readonly*/ []BucketEntry {
ev := make([]BucketEntry, len(b.keys)) ev := make([]BucketEntry, len(b.keys))
for i, k := range b.keys { for i, k := range b.keys {
ev[i] = BucketEntry{k, b.values[i]} ev[i] = BucketEntry{k, b.values[i]}
...@@ -272,26 +272,40 @@ func (t *BTree) MinKey(ctx context.Context) (_ KEY, ok bool, err error) { ...@@ -272,26 +272,40 @@ func (t *BTree) MinKey(ctx context.Context) (_ KEY, ok bool, err error) {
// VMinKey is like MinKey but also calls visit while traversing the tree. // VMinKey is like MinKey but also calls visit while traversing the tree.
// //
// Visit is called with node being activated. // Visit is called with node being activated.
func (t *BTree) VMinKey(ctx context.Context, visit func(node Node)) (_ KEY, ok bool, err error) { func (t *BTree) VMinKey(ctx context.Context, visit func(node Node, keycov KeyRange)) (_ KEY, ok bool, err error) {
defer xerr.Contextf(&err, "btree(%s): minkey", t.POid()) defer xerr.Contextf(&err, "btree(%s): minkey", t.POid())
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
keycov := KeyRange{Lo: _KeyMin, Hi_: _KeyMax}
if visit != nil { if visit != nil {
visit(t) visit(t, keycov)
}
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
return 0, false, nil
} }
// NOTE -> can also use t.firstbucket // NOTE -> can also use t.firstbucket
for { for {
l := len(t.data)
if l == 0 {
// empty btree (top, or in leaf)
t.PDeactivate()
return 0, false, nil
}
child := t.data[0].child child := t.data[0].child
// shorten global keycov by local hi) for this child
hi_ := _KeyMax
if 1 < l {
hi_ = t.data[1].key
}
if hi_ != _KeyMax {
hi_--
}
// keycov.Lo stays -∞
keycov.Hi_ = kmin(keycov.Hi_, hi_)
t.PDeactivate() t.PDeactivate()
err = child.PActivate(ctx) err = child.PActivate(ctx)
if err != nil { if err != nil {
...@@ -299,7 +313,7 @@ func (t *BTree) VMinKey(ctx context.Context, visit func(node Node)) (_ KEY, ok b ...@@ -299,7 +313,7 @@ func (t *BTree) VMinKey(ctx context.Context, visit func(node Node)) (_ KEY, ok b
} }
if visit != nil { if visit != nil {
visit(child) visit(child, keycov)
} }
// XXX verify child keys are in valid range according to parent // XXX verify child keys are in valid range according to parent
...@@ -327,27 +341,36 @@ func (t *BTree) MaxKey(ctx context.Context) (_ KEY, _ bool, err error) { ...@@ -327,27 +341,36 @@ func (t *BTree) MaxKey(ctx context.Context) (_ KEY, _ bool, err error) {
// VMaxKey is like MaxKey but also calls visit while traversing the tree. // VMaxKey is like MaxKey but also calls visit while traversing the tree.
// //
// Visit is called with node being activated. // Visit is called with node being activated.
func (t *BTree) VMaxKey(ctx context.Context, visit func(node Node)) (_ KEY, _ bool, err error) { func (t *BTree) VMaxKey(ctx context.Context, visit func(node Node, keycov KeyRange)) (_ KEY, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid()) defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid())
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
keycov := KeyRange{Lo: _KeyMin, Hi_: _KeyMax}
if visit != nil { if visit != nil {
visit(t) visit(t, keycov)
}
l := len(t.data)
if l == 0 {
// empty btree
t.PDeactivate()
return 0, false, nil
} }
for { for {
// FIXME need to refresh l l := len(t.data)
if l == 0 {
// empty btree (top, or in leaf)
t.PDeactivate()
return 0, false, nil
}
child := t.data[l-1].child child := t.data[l-1].child
// shorten global keycov by local [lo for this chile
lo := _KeyMin
if l-1 > 0 {
lo = t.data[l-1].key
}
keycov.Lo = kmax(keycov.Lo, lo)
// keycov.Hi_ stays ∞
t.PDeactivate() t.PDeactivate()
err = child.PActivate(ctx) err = child.PActivate(ctx)
if err != nil { if err != nil {
...@@ -355,7 +378,7 @@ func (t *BTree) VMaxKey(ctx context.Context, visit func(node Node)) (_ KEY, _ bo ...@@ -355,7 +378,7 @@ func (t *BTree) VMaxKey(ctx context.Context, visit func(node Node)) (_ KEY, _ bo
} }
if visit != nil { if visit != nil {
visit(child) visit(child, keycov)
} }
// XXX verify child keys are in valid range according to parent // XXX verify child keys are in valid range according to parent
......
...@@ -289,9 +289,8 @@ func TestBTree(t *testing.T) { ...@@ -289,9 +289,8 @@ func TestBTree(t *testing.T) {
} }
} }
/* XXX reenable visitMinOK := Bvdict[Bv_kmin]
visitMinOK := Bvdict[kmin] visitMaxOK := Bvdict[Bv_kmax]
visitMaxOK := Bvdict[kmax]
visitMin := []tVisit{} visitMin := []tVisit{}
visitMax := []tVisit{} visitMax := []tVisit{}
_, _, err = Bv.VMinKey(ctx, func(node LONode, keycov LKeyRange) { _, _, err = Bv.VMinKey(ctx, func(node LONode, keycov LKeyRange) {
...@@ -307,5 +306,4 @@ func TestBTree(t *testing.T) { ...@@ -307,5 +306,4 @@ func TestBTree(t *testing.T) {
if !reflect.DeepEqual(visitMax, visitMaxOK) { if !reflect.DeepEqual(visitMax, visitMaxOK) {
t.Errorf("VMaxKey(): visit:\nhave: %v\nwant: %v", visitMax, visitMaxOK) t.Errorf("VMaxKey(): visit:\nhave: %v\nwant: %v", visitMax, visitMaxOK)
} }
*/
} }
...@@ -108,6 +108,8 @@ def main2(): ...@@ -108,6 +108,8 @@ def main2():
emit("const B3_maxkey = %d" % B3.maxKey()) emit("const B3_maxkey = %d" % B3.maxKey())
emit("\nconst Bv_oid = %s" % u64(Bv._p_oid)) emit("\nconst Bv_oid = %s" % u64(Bv._p_oid))
emit("const Bv_kmin = %d" % Bv.minKey())
emit("const Bv_kmax = %d" % Bv.maxKey())
emit("var Bvdict = map[int64][]tVisit{") emit("var Bvdict = map[int64][]tVisit{")
noo = "_LKeyMin" noo = "_LKeyMin"
oo = "_LKeyMax" oo = "_LKeyMax"
......
...@@ -140,7 +140,7 @@ func (e *IOBucketEntry) Key() int32 { return e.key } ...@@ -140,7 +140,7 @@ func (e *IOBucketEntry) Key() int32 { return e.key }
func (e *IOBucketEntry) Value() interface{} { return e.value } func (e *IOBucketEntry) Value() interface{} { return e.value }
// Entryv returns entries of a IOBucket node. // Entryv returns entries of a IOBucket node.
func (b *IOBucket) Entryv() []IOBucketEntry { func (b *IOBucket) Entryv() /*readonly*/ []IOBucketEntry {
ev := make([]IOBucketEntry, len(b.keys)) ev := make([]IOBucketEntry, len(b.keys))
for i, k := range b.keys { for i, k := range b.keys {
ev[i] = IOBucketEntry{k, b.values[i]} ev[i] = IOBucketEntry{k, b.values[i]}
...@@ -274,26 +274,40 @@ func (t *IOBTree) MinKey(ctx context.Context) (_ int32, ok bool, err error) { ...@@ -274,26 +274,40 @@ func (t *IOBTree) MinKey(ctx context.Context) (_ int32, ok bool, err error) {
// VMinKey is like MinKey but also calls visit while traversing the tree. // VMinKey is like MinKey but also calls visit while traversing the tree.
// //
// Visit is called with node being activated. // Visit is called with node being activated.
func (t *IOBTree) VMinKey(ctx context.Context, visit func(node IONode)) (_ int32, ok bool, err error) { func (t *IOBTree) VMinKey(ctx context.Context, visit func(node IONode, keycov IKeyRange)) (_ int32, ok bool, err error) {
defer xerr.Contextf(&err, "btree(%s): minkey", t.POid()) defer xerr.Contextf(&err, "btree(%s): minkey", t.POid())
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
keycov := IKeyRange{Lo: _IKeyMin, Hi_: _IKeyMax}
if visit != nil { if visit != nil {
visit(t) visit(t, keycov)
}
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
return 0, false, nil
} }
// NOTE -> can also use t.firstbucket // NOTE -> can also use t.firstbucket
for { for {
l := len(t.data)
if l == 0 {
// empty btree (top, or in leaf)
t.PDeactivate()
return 0, false, nil
}
child := t.data[0].child child := t.data[0].child
// shorten global keycov by local hi) for this child
hi_ := _IKeyMax
if 1 < l {
hi_ = t.data[1].key
}
if hi_ != _IKeyMax {
hi_--
}
// keycov.Lo stays -∞
keycov.Hi_ = ikmin(keycov.Hi_, hi_)
t.PDeactivate() t.PDeactivate()
err = child.PActivate(ctx) err = child.PActivate(ctx)
if err != nil { if err != nil {
...@@ -301,7 +315,7 @@ func (t *IOBTree) VMinKey(ctx context.Context, visit func(node IONode)) (_ int32 ...@@ -301,7 +315,7 @@ func (t *IOBTree) VMinKey(ctx context.Context, visit func(node IONode)) (_ int32
} }
if visit != nil { if visit != nil {
visit(child) visit(child, keycov)
} }
// XXX verify child keys are in valid range according to parent // XXX verify child keys are in valid range according to parent
...@@ -329,27 +343,36 @@ func (t *IOBTree) MaxKey(ctx context.Context) (_ int32, _ bool, err error) { ...@@ -329,27 +343,36 @@ func (t *IOBTree) MaxKey(ctx context.Context) (_ int32, _ bool, err error) {
// VMaxKey is like MaxKey but also calls visit while traversing the tree. // VMaxKey is like MaxKey but also calls visit while traversing the tree.
// //
// Visit is called with node being activated. // Visit is called with node being activated.
func (t *IOBTree) VMaxKey(ctx context.Context, visit func(node IONode)) (_ int32, _ bool, err error) { func (t *IOBTree) VMaxKey(ctx context.Context, visit func(node IONode, keycov IKeyRange)) (_ int32, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid()) defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid())
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
keycov := IKeyRange{Lo: _IKeyMin, Hi_: _IKeyMax}
if visit != nil { if visit != nil {
visit(t) visit(t, keycov)
}
l := len(t.data)
if l == 0 {
// empty btree
t.PDeactivate()
return 0, false, nil
} }
for { for {
// FIXME need to refresh l l := len(t.data)
if l == 0 {
// empty btree (top, or in leaf)
t.PDeactivate()
return 0, false, nil
}
child := t.data[l-1].child child := t.data[l-1].child
// shorten global keycov by local [lo for this chile
lo := _IKeyMin
if l-1 > 0 {
lo = t.data[l-1].key
}
keycov.Lo = ikmax(keycov.Lo, lo)
// keycov.Hi_ stays ∞
t.PDeactivate() t.PDeactivate()
err = child.PActivate(ctx) err = child.PActivate(ctx)
if err != nil { if err != nil {
...@@ -357,7 +380,7 @@ func (t *IOBTree) VMaxKey(ctx context.Context, visit func(node IONode)) (_ int32 ...@@ -357,7 +380,7 @@ func (t *IOBTree) VMaxKey(ctx context.Context, visit func(node IONode)) (_ int32
} }
if visit != nil { if visit != nil {
visit(child) visit(child, keycov)
} }
// XXX verify child keys are in valid range according to parent // XXX verify child keys are in valid range according to parent
......
...@@ -140,7 +140,7 @@ func (e *LOBucketEntry) Key() int64 { return e.key } ...@@ -140,7 +140,7 @@ func (e *LOBucketEntry) Key() int64 { return e.key }
func (e *LOBucketEntry) Value() interface{} { return e.value } func (e *LOBucketEntry) Value() interface{} { return e.value }
// Entryv returns entries of a LOBucket node. // Entryv returns entries of a LOBucket node.
func (b *LOBucket) Entryv() []LOBucketEntry { func (b *LOBucket) Entryv() /*readonly*/ []LOBucketEntry {
ev := make([]LOBucketEntry, len(b.keys)) ev := make([]LOBucketEntry, len(b.keys))
for i, k := range b.keys { for i, k := range b.keys {
ev[i] = LOBucketEntry{k, b.values[i]} ev[i] = LOBucketEntry{k, b.values[i]}
...@@ -274,26 +274,40 @@ func (t *LOBTree) MinKey(ctx context.Context) (_ int64, ok bool, err error) { ...@@ -274,26 +274,40 @@ func (t *LOBTree) MinKey(ctx context.Context) (_ int64, ok bool, err error) {
// VMinKey is like MinKey but also calls visit while traversing the tree. // VMinKey is like MinKey but also calls visit while traversing the tree.
// //
// Visit is called with node being activated. // Visit is called with node being activated.
func (t *LOBTree) VMinKey(ctx context.Context, visit func(node LONode)) (_ int64, ok bool, err error) { func (t *LOBTree) VMinKey(ctx context.Context, visit func(node LONode, keycov LKeyRange)) (_ int64, ok bool, err error) {
defer xerr.Contextf(&err, "btree(%s): minkey", t.POid()) defer xerr.Contextf(&err, "btree(%s): minkey", t.POid())
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
keycov := LKeyRange{Lo: _LKeyMin, Hi_: _LKeyMax}
if visit != nil { if visit != nil {
visit(t) visit(t, keycov)
}
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
return 0, false, nil
} }
// NOTE -> can also use t.firstbucket // NOTE -> can also use t.firstbucket
for { for {
l := len(t.data)
if l == 0 {
// empty btree (top, or in leaf)
t.PDeactivate()
return 0, false, nil
}
child := t.data[0].child child := t.data[0].child
// shorten global keycov by local hi) for this child
hi_ := _LKeyMax
if 1 < l {
hi_ = t.data[1].key
}
if hi_ != _LKeyMax {
hi_--
}
// keycov.Lo stays -∞
keycov.Hi_ = lkmin(keycov.Hi_, hi_)
t.PDeactivate() t.PDeactivate()
err = child.PActivate(ctx) err = child.PActivate(ctx)
if err != nil { if err != nil {
...@@ -301,7 +315,7 @@ func (t *LOBTree) VMinKey(ctx context.Context, visit func(node LONode)) (_ int64 ...@@ -301,7 +315,7 @@ func (t *LOBTree) VMinKey(ctx context.Context, visit func(node LONode)) (_ int64
} }
if visit != nil { if visit != nil {
visit(child) visit(child, keycov)
} }
// XXX verify child keys are in valid range according to parent // XXX verify child keys are in valid range according to parent
...@@ -329,27 +343,36 @@ func (t *LOBTree) MaxKey(ctx context.Context) (_ int64, _ bool, err error) { ...@@ -329,27 +343,36 @@ func (t *LOBTree) MaxKey(ctx context.Context) (_ int64, _ bool, err error) {
// VMaxKey is like MaxKey but also calls visit while traversing the tree. // VMaxKey is like MaxKey but also calls visit while traversing the tree.
// //
// Visit is called with node being activated. // Visit is called with node being activated.
func (t *LOBTree) VMaxKey(ctx context.Context, visit func(node LONode)) (_ int64, _ bool, err error) { func (t *LOBTree) VMaxKey(ctx context.Context, visit func(node LONode, keycov LKeyRange)) (_ int64, _ bool, err error) {
defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid()) defer xerr.Contextf(&err, "btree(%s): maxkey", t.POid())
err = t.PActivate(ctx) err = t.PActivate(ctx)
if err != nil { if err != nil {
return 0, false, err return 0, false, err
} }
keycov := LKeyRange{Lo: _LKeyMin, Hi_: _LKeyMax}
if visit != nil { if visit != nil {
visit(t) visit(t, keycov)
}
l := len(t.data)
if l == 0 {
// empty btree
t.PDeactivate()
return 0, false, nil
} }
for { for {
// FIXME need to refresh l l := len(t.data)
if l == 0 {
// empty btree (top, or in leaf)
t.PDeactivate()
return 0, false, nil
}
child := t.data[l-1].child child := t.data[l-1].child
// shorten global keycov by local [lo for this chile
lo := _LKeyMin
if l-1 > 0 {
lo = t.data[l-1].key
}
keycov.Lo = lkmax(keycov.Lo, lo)
// keycov.Hi_ stays ∞
t.PDeactivate() t.PDeactivate()
err = child.PActivate(ctx) err = child.PActivate(ctx)
if err != nil { if err != nil {
...@@ -357,7 +380,7 @@ func (t *LOBTree) VMaxKey(ctx context.Context, visit func(node LONode)) (_ int64 ...@@ -357,7 +380,7 @@ func (t *LOBTree) VMaxKey(ctx context.Context, visit func(node LONode)) (_ int64
} }
if visit != nil { if visit != nil {
visit(child) visit(child, keycov)
} }
// XXX verify child keys are in valid range according to parent // XXX verify child keys are in valid range according to parent
......
...@@ -15,6 +15,8 @@ const B3_oid = 6 ...@@ -15,6 +15,8 @@ const B3_oid = 6
const B3_maxkey = 9999 const B3_maxkey = 9999
const Bv_oid = 2 const Bv_oid = 2
const Bv_kmin = 1
const Bv_kmax = 9
var Bvdict = map[int64][]tVisit{ var Bvdict = map[int64][]tVisit{
1: []tVisit{{2, LKeyRange{_LKeyMin, _LKeyMax}}, {342, LKeyRange{_LKeyMin, 3}}, {344, LKeyRange{_LKeyMin, 1}}}, 1: []tVisit{{2, LKeyRange{_LKeyMin, _LKeyMax}}, {342, LKeyRange{_LKeyMin, 3}}, {344, LKeyRange{_LKeyMin, 1}}},
2: []tVisit{{2, LKeyRange{_LKeyMin, _LKeyMax}}, {342, LKeyRange{_LKeyMin, 3}}, {349, LKeyRange{2, 3}}}, 2: []tVisit{{2, LKeyRange{_LKeyMin, _LKeyMax}}, {342, LKeyRange{_LKeyMin, 3}}, {349, LKeyRange{2, 3}}},
......
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