Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Kirill Smelkov
neo
Commits
ded591a9
Commit
ded591a9
authored
Feb 05, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
cce696b2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
97 additions
and
130 deletions
+97
-130
go/zodb/btree/btree.go.in
go/zodb/btree/btree.go.in
+32
-43
go/zodb/btree/btree_test.go
go/zodb/btree/btree_test.go
+1
-1
go/zodb/btree/ziobtree.go
go/zodb/btree/ziobtree.go
+32
-43
go/zodb/btree/zlobtree.go
go/zodb/btree/zlobtree.go
+32
-43
No files found.
go/zodb/btree/btree.go.in
View file @
ded591a9
...
...
@@ -61,7 +61,7 @@ type BTree struct {
//
Key
limits
child
's keys - see BTree.Entryv for details.
type Entry struct {
key KEY
child
interface{}
// BTree or Bucket
child
zodb.IPersistent
// BTree or Bucket
}
// Bucket is a leaf node of a B⁺ tree.
...
...
@@ -99,7 +99,7 @@ type BucketEntry struct {
func (e *Entry) Key() KEY { return e.key }
// Child returns BTree entry child.
func (e *Entry) Child()
interface{}
{ return e.child }
func (e *Entry) Child()
zodb.IPersistent
{ return e.child }
// Entryv returns entries of a BTree node.
//
...
...
@@ -153,30 +153,33 @@ 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) {
v, ok, _, _, err := t.GetTo(ctx, key)
return v, ok, err
return t.GetTo(ctx, key, nil)
}
// GetTo searches BTree by key and
returns value and path
.
// GetTo searches BTree by key and
visits btree-path nodes
.
//
// 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) {
// 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.
//
// 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) {
defer xerr.Contextf(&err, "btree(%s): get %v", t.POid(), key)
err = t.PActivate(ctx)
if err != nil {
return nil, false, nil, nil, err
return nil, false, err
}
if visit != nil {
visit(t)
}
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
return nil, false, nil
, nil, nil
return nil, false, nil
}
for {
path = append(path, t)
// search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞
i := sort.Search(len(t.data), func(i int) bool {
j := i + 1
...
...
@@ -186,47 +189,33 @@ func (t *BTree) GetTo(ctx context.Context, key KEY) (_ interface{}, _ bool, path
return key < t.data[j].key
})
switch child := t.data[i].child.(type) {
child := t.data[i].child
t.PDeactivate()
err = child.PActivate(ctx)
if err != nil {
return nil, false, err
}
if visit != nil {
visit(child)
}
switch child := child.(type) {
case *BTree:
t.PDeactivate()
t = child
err = t.PActivate(ctx)
if err != nil {
return nil, false, nil, nil, err
}
case *Bucket:
t.PDeactivate()
v, ok, err := child.Get(ctx, key)
if err != nil {
path = nil
child = nil
}
return v, ok, path, child, err
v, ok := child.Get(key)
child.PDeactivate()
return v, ok, nil
}
}
}
// Get searches Bucket by key.
//
// TODO Bucket.Get should not get ctx argument and just require that the bucket
// must be already activated. Correspondingly there should be no error returned.
func (b *Bucket) Get(ctx context.Context, key KEY) (_ interface{}, _ bool, err error) {
defer xerr.Contextf(&err, "bucket(%s): get %v", b.POid(), key)
err = b.PActivate(ctx)
if err != nil {
return nil, false, err
}
v, ok := b.get(key)
b.PDeactivate()
return v, ok, nil
}
// get searches Bucket by key.
//
// no loading from database is done. The bucket must be already activated.
func (b *Bucket)
g
et(key KEY) (interface{}, bool) {
func (b *Bucket)
G
et(key KEY) (interface{}, bool) {
// search i: K(i-1) < k ≤ K(i) ; K(-1) = -∞, K(len) = +∞
i := sort.Search(len(b.keys), func(i int) bool {
return key <= b.keys[i]
...
...
@@ -599,7 +588,7 @@ func (bt *btreeState) PySetState(pystate interface{}) (err error) {
fmt.Errorf("data: [%d]: children must be of the same type", i)
}
bt.data = append(bt.data, Entry{key: kkey, child: child})
bt.data = append(bt.data, Entry{key: kkey, child: child
.(zodb.IPersistent)
})
}
return nil
...
...
go/zodb/btree/btree_test.go
View file @
ded591a9
...
...
@@ -79,7 +79,7 @@ func (b *bucketWrap) withBucket(ctx context.Context, f func()) error {
func
(
b
*
bucketWrap
)
Get
(
ctx
context
.
Context
,
key
int64
)
(
v
interface
{},
ok
bool
,
err
error
)
{
err
=
b
.
withBucket
(
ctx
,
func
()
{
v
,
ok
=
b
.
bucket
()
.
get
(
key
)
// TODO -> Get
v
,
ok
=
b
.
bucket
()
.
Get
(
key
)
})
return
}
...
...
go/zodb/btree/ziobtree.go
View file @
ded591a9
...
...
@@ -63,7 +63,7 @@ type IOBTree struct {
// Key limits child's keys - see IOBTree.Entryv for details.
type
IOEntry
struct
{
key
int32
child
interface
{}
// IOBTree or IOBucket
child
zodb
.
IPersistent
// IOBTree or IOBucket
}
// IOBucket is a leaf node of a B⁺ tree.
...
...
@@ -101,7 +101,7 @@ type IOBucketEntry struct {
func
(
e
*
IOEntry
)
Key
()
int32
{
return
e
.
key
}
// Child returns IOBTree entry child.
func
(
e
*
IOEntry
)
Child
()
interface
{}
{
return
e
.
child
}
func
(
e
*
IOEntry
)
Child
()
zodb
.
IPersistent
{
return
e
.
child
}
// Entryv returns entries of a IOBTree node.
//
...
...
@@ -155,30 +155,33 @@ 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
)
{
v
,
ok
,
_
,
_
,
err
:=
t
.
GetTo
(
ctx
,
key
)
return
v
,
ok
,
err
return
t
.
GetTo
(
ctx
,
key
,
nil
)
}
// GetTo searches IOBTree by key and
returns value and path
.
// GetTo searches IOBTree by key and
visits btree-path nodes
.
//
// 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
)
{
// 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.
//
// 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
)
{
defer
xerr
.
Contextf
(
&
err
,
"btree(%s): get %v"
,
t
.
POid
(),
key
)
err
=
t
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
nil
,
nil
,
err
return
nil
,
false
,
err
}
if
visit
!=
nil
{
visit
(
t
)
}
if
len
(
t
.
data
)
==
0
{
// empty btree
t
.
PDeactivate
()
return
nil
,
false
,
nil
,
nil
,
nil
return
nil
,
false
,
nil
}
for
{
path
=
append
(
path
,
t
)
// search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞
i
:=
sort
.
Search
(
len
(
t
.
data
),
func
(
i
int
)
bool
{
j
:=
i
+
1
...
...
@@ -188,47 +191,33 @@ func (t *IOBTree) GetTo(ctx context.Context, key int32) (_ interface{}, _ bool,
return
key
<
t
.
data
[
j
]
.
key
})
switch
child
:=
t
.
data
[
i
]
.
child
.
(
type
)
{
child
:=
t
.
data
[
i
]
.
child
t
.
PDeactivate
()
err
=
child
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
err
}
if
visit
!=
nil
{
visit
(
child
)
}
switch
child
:=
child
.
(
type
)
{
case
*
IOBTree
:
t
.
PDeactivate
()
t
=
child
err
=
t
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
nil
,
nil
,
err
}
case
*
IOBucket
:
t
.
PDeactivate
()
v
,
ok
,
err
:=
child
.
Get
(
ctx
,
key
)
if
err
!=
nil
{
path
=
nil
child
=
nil
}
return
v
,
ok
,
path
,
child
,
err
v
,
ok
:=
child
.
Get
(
key
)
child
.
PDeactivate
()
return
v
,
ok
,
nil
}
}
}
// Get searches IOBucket by key.
//
// TODO IOBucket.Get should not get ctx argument and just require that the bucket
// must be already activated. Correspondingly there should be no error returned.
func
(
b
*
IOBucket
)
Get
(
ctx
context
.
Context
,
key
int32
)
(
_
interface
{},
_
bool
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"bucket(%s): get %v"
,
b
.
POid
(),
key
)
err
=
b
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
err
}
v
,
ok
:=
b
.
get
(
key
)
b
.
PDeactivate
()
return
v
,
ok
,
nil
}
// get searches IOBucket by key.
//
// no loading from database is done. The bucket must be already activated.
func
(
b
*
IOBucket
)
g
et
(
key
int32
)
(
interface
{},
bool
)
{
func
(
b
*
IOBucket
)
G
et
(
key
int32
)
(
interface
{},
bool
)
{
// search i: K(i-1) < k ≤ K(i) ; K(-1) = -∞, K(len) = +∞
i
:=
sort
.
Search
(
len
(
b
.
keys
),
func
(
i
int
)
bool
{
return
key
<=
b
.
keys
[
i
]
...
...
@@ -601,7 +590,7 @@ func (bt *iobtreeState) PySetState(pystate interface{}) (err error) {
fmt
.
Errorf
(
"data: [%d]: children must be of the same type"
,
i
)
}
bt
.
data
=
append
(
bt
.
data
,
IOEntry
{
key
:
kkey
,
child
:
child
})
bt
.
data
=
append
(
bt
.
data
,
IOEntry
{
key
:
kkey
,
child
:
child
.
(
zodb
.
IPersistent
)
})
}
return
nil
...
...
go/zodb/btree/zlobtree.go
View file @
ded591a9
...
...
@@ -63,7 +63,7 @@ type LOBTree struct {
// Key limits child's keys - see LOBTree.Entryv for details.
type
LOEntry
struct
{
key
int64
child
interface
{}
// LOBTree or LOBucket
child
zodb
.
IPersistent
// LOBTree or LOBucket
}
// LOBucket is a leaf node of a B⁺ tree.
...
...
@@ -101,7 +101,7 @@ type LOBucketEntry struct {
func
(
e
*
LOEntry
)
Key
()
int64
{
return
e
.
key
}
// Child returns LOBTree entry child.
func
(
e
*
LOEntry
)
Child
()
interface
{}
{
return
e
.
child
}
func
(
e
*
LOEntry
)
Child
()
zodb
.
IPersistent
{
return
e
.
child
}
// Entryv returns entries of a LOBTree node.
//
...
...
@@ -155,30 +155,33 @@ 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
)
{
v
,
ok
,
_
,
_
,
err
:=
t
.
GetTo
(
ctx
,
key
)
return
v
,
ok
,
err
return
t
.
GetTo
(
ctx
,
key
,
nil
)
}
// GetTo searches LOBTree by key and
returns value and path
.
// GetTo searches LOBTree by key and
visits btree-path nodes
.
//
// 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
)
{
// 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.
//
// 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
)
{
defer
xerr
.
Contextf
(
&
err
,
"btree(%s): get %v"
,
t
.
POid
(),
key
)
err
=
t
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
nil
,
nil
,
err
return
nil
,
false
,
err
}
if
visit
!=
nil
{
visit
(
t
)
}
if
len
(
t
.
data
)
==
0
{
// empty btree
t
.
PDeactivate
()
return
nil
,
false
,
nil
,
nil
,
nil
return
nil
,
false
,
nil
}
for
{
path
=
append
(
path
,
t
)
// search i: K(i) ≤ k < K(i+1) ; K(0) = -∞, K(len) = +∞
i
:=
sort
.
Search
(
len
(
t
.
data
),
func
(
i
int
)
bool
{
j
:=
i
+
1
...
...
@@ -188,47 +191,33 @@ func (t *LOBTree) GetTo(ctx context.Context, key int64) (_ interface{}, _ bool,
return
key
<
t
.
data
[
j
]
.
key
})
switch
child
:=
t
.
data
[
i
]
.
child
.
(
type
)
{
child
:=
t
.
data
[
i
]
.
child
t
.
PDeactivate
()
err
=
child
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
err
}
if
visit
!=
nil
{
visit
(
child
)
}
switch
child
:=
child
.
(
type
)
{
case
*
LOBTree
:
t
.
PDeactivate
()
t
=
child
err
=
t
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
nil
,
nil
,
err
}
case
*
LOBucket
:
t
.
PDeactivate
()
v
,
ok
,
err
:=
child
.
Get
(
ctx
,
key
)
if
err
!=
nil
{
path
=
nil
child
=
nil
}
return
v
,
ok
,
path
,
child
,
err
v
,
ok
:=
child
.
Get
(
key
)
child
.
PDeactivate
()
return
v
,
ok
,
nil
}
}
}
// Get searches LOBucket by key.
//
// TODO LOBucket.Get should not get ctx argument and just require that the bucket
// must be already activated. Correspondingly there should be no error returned.
func
(
b
*
LOBucket
)
Get
(
ctx
context
.
Context
,
key
int64
)
(
_
interface
{},
_
bool
,
err
error
)
{
defer
xerr
.
Contextf
(
&
err
,
"bucket(%s): get %v"
,
b
.
POid
(),
key
)
err
=
b
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
nil
,
false
,
err
}
v
,
ok
:=
b
.
get
(
key
)
b
.
PDeactivate
()
return
v
,
ok
,
nil
}
// get searches LOBucket by key.
//
// no loading from database is done. The bucket must be already activated.
func
(
b
*
LOBucket
)
g
et
(
key
int64
)
(
interface
{},
bool
)
{
func
(
b
*
LOBucket
)
G
et
(
key
int64
)
(
interface
{},
bool
)
{
// search i: K(i-1) < k ≤ K(i) ; K(-1) = -∞, K(len) = +∞
i
:=
sort
.
Search
(
len
(
b
.
keys
),
func
(
i
int
)
bool
{
return
key
<=
b
.
keys
[
i
]
...
...
@@ -601,7 +590,7 @@ func (bt *lobtreeState) PySetState(pystate interface{}) (err error) {
fmt
.
Errorf
(
"data: [%d]: children must be of the same type"
,
i
)
}
bt
.
data
=
append
(
bt
.
data
,
LOEntry
{
key
:
kkey
,
child
:
child
})
bt
.
data
=
append
(
bt
.
data
,
LOEntry
{
key
:
kkey
,
child
:
child
.
(
zodb
.
IPersistent
)
})
}
return
nil
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment