Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
525305a0
Commit
525305a0
authored
6 years ago
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
7bf85a48
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
106 additions
and
33 deletions
+106
-33
go/zodb/btree/btree.go
go/zodb/btree/btree.go
+29
-19
go/zodb/cache.go
go/zodb/cache.go
+2
-0
go/zodb/pydata.go
go/zodb/pydata.go
+75
-14
No files found.
go/zodb/btree/btree.go
View file @
525305a0
...
...
@@ -18,40 +18,51 @@
// XXX name -> zbtree ?
package
btree
// ZBucket mimics ?OBucket from btree/py, with ? being any integer.
import
(
"context"
"sort"
"lab.nexedi.com/kirr/neo/go/zodb"
)
// XXX temp
type
KEY
int64
// Bucket mimics ?OBucket from btree/py, with ? being any integer.
//
// py description:
//
original
py description:
//
// A Bucket wraps contiguous vectors of keys and values. Keys are unique,
// and stored in sorted order. The 'values' pointer may be NULL if the
// Bucket is used to implement a set. Buckets serving as leafs of BTrees
// are chained together via 'next', so that the entire BTree contents
// can be traversed in sorted order quickly and easily.
type
Z
Bucket
struct
{
type
Bucket
struct
{
pyobj
*
zodb
.
PyObject
next
*
Z
Bucket
// the bucket with the next-larger keys
next
*
Bucket
// the bucket with the next-larger keys
keys
[]
KEY
// 'len' keys, in increasing order
values
[]
interface
{}
// 'len' corresponding values XXX merge k/v ?
}
// zBTreeItem mimics BTreeItem from btree/py.
type
zBTreeItem
{
type
zBTreeItem
struct
{
key
KEY
child
interface
{}
//
ZBTree or Z
Bucket
child
interface
{}
//
BTree or
Bucket
}
//
Z
BTree mimics ?OBTree from btree/py, with ? being any integer.
// BTree mimics ?OBTree from btree/py, with ? being any integer.
//
// See https://github.com/zopefoundation/BTrees/blob/4.5.0-1-gc8bf24e/BTrees/Development.txt#L198
// for details.
type
Z
BTree
struct
{
type
BTree
struct
{
pyobj
*
zodb
.
PyObject
// firstbucket points to the bucket containing the smallest key in
// the BTree. This is found by traversing leftmost child pointers
// (data[0].child) until reaching a Bucket.
firstbucket
*
Z
Bucket
firstbucket
*
Bucket
// The BTree points to 'len' children, via the "child" fields of the data
// array. There are len-1 keys in the 'key' fields, stored in increasing
...
...
@@ -66,7 +77,7 @@ type ZBTree struct {
//
// It loads intermediate BTree nodes from database on demand as needed.
// XXX ok -> ErrKeyNotFound?
func
(
t
*
Z
BTree
)
Get
(
ctx
context
.
Context
,
key
KEY
)
(
interface
{},
bool
,
error
)
{
func
(
t
*
BTree
)
Get
(
ctx
context
.
Context
,
key
KEY
)
(
interface
{},
bool
,
error
)
{
t
.
PActivate
(
ctx
)
// XXX err
if
len
(
t
.
data
)
==
0
{
...
...
@@ -85,14 +96,15 @@ func (t *ZBTree) Get(ctx context.Context, key KEY) (interface{}, bool, error) {
})
switch
child
:=
t
.
data
[
i
]
.
child
.
(
type
)
{
case
*
Z
BTree
:
case
*
BTree
:
// XXX t.PAllowDeactivate
t
=
child
t
.
PActivate
(
ctx
)
// XXX err
case
*
Z
Bucket
:
case
*
Bucket
:
child
.
PActivate
(
ctx
)
// XXX err
return
child
.
Get
(
key
),
nil
x
,
ok
:=
child
.
get
(
key
)
return
x
,
ok
,
nil
}
}
}
...
...
@@ -100,12 +112,12 @@ func (t *ZBTree) Get(ctx context.Context, key KEY) (interface{}, bool, error) {
// get searches Bucket by key.
//
// no loading from database is done. The bucket must be already activated.
func
(
b
*
Z
Bucket
)
get
(
key
KEY
)
(
interface
{},
bool
)
{
func
(
b
*
Bucket
)
get
(
key
KEY
)
(
interface
{},
bool
)
{
// XXX b.PActivate ? XXX better caller? (or inside if get -> Get)
// search i: K(i-1) < k ≤ K(i) ; K(-1) = -∞, K(len) = +∞
i
:=
sort
.
Search
(
len
(
b
.
keys
),
func
(
i
int
)
bool
{
return
key
<=
t
.
data
[
i
]
.
key
return
key
<=
b
.
keys
[
i
]
})
if
i
==
len
(
b
.
keys
)
||
b
.
keys
[
i
]
!=
key
{
...
...
@@ -142,10 +154,8 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
// In the above, key[i] means self->data[i].key, and similarly for child[i].
// XXX ZBTree.Get(key)
// XXX ZBucket.MinKey ?
// XXX ZBucket.MaxKey ?
// XXX Bucket.MinKey ?
// XXX Bucket.MaxKey ?
// from https://github.com/zopefoundation/BTrees/blob/4.5.0-1-gc8bf24e/BTrees/BucketTemplate.c#L1195:
...
...
This diff is collapsed.
Click to expand it.
go/zodb/cache.go
View file @
525305a0
...
...
@@ -35,6 +35,8 @@ import (
// TODO maintain nhit / nmiss + way to read cache stats
// TODO optimize cache more so that miss overhead becomes negligible
// TODO Drop(xid) -> make sure data for xid is no longer in cache
// Cache provides RAM caching layer that can be used over a storage.
type
Cache
struct
{
loader
interface
{
...
...
This diff is collapsed.
Click to expand it.
go/zodb/pydata.go
View file @
525305a0
...
...
@@ -23,11 +23,68 @@ package zodb
import
(
"bytes"
"errors"
"fmt"
//
"fmt"
pickle
"github.com/kisielk/og-rek"
)
// XXX move out of py
// Object is in-process representaion of a ZODB object.
type
Object
interface
{
Jar
()
*
Connection
Oid
()
Oid
Serial
()
Tid
Data
()
*
mem
.
Buf
// XXX for raw, py -> PyObject
// XXX register(jar, oid) - register to database ? (for Connection.Add)
// PActivate
// PDeactivate
// PInvalidate
}
// XXX
type
DataManager
interface
{
//LoadObject(obj Object)
//LoadObject(oid Oid)
LoadState
(
obj
)
// XXX oldstate(oid, tid)
// XXX register(obj)
}
// Connection represent client-visible part of a connection to ZODB database.
//
// XXX consitent view for some `at`.
// XXX not needed? (just DB.Open() -> root object and connection not be visible)?
type
Connection
interface
{
// Get returns object by oid.
// XXX multiple calls to Get with same oid return the same object.
// XXX root object has oid=0.
Get
(
ctx
context
.
Context
,
oid
Oid
)
(
Object
,
error
)
// XXX Add(obj Object) -> add obj to database and assign it an oid
// obj must be not yet added
// XXX ReadCurrent(obj)
// XXX Close() error
}
// PyData represents raw data stored into ZODB by Python applications.
//
// The format is based on python pickles. Basically every serialized object has
...
...
@@ -48,14 +105,15 @@ type PyData []byte
// PyObject represents persistent Python object.
//
// PyObject can be decoded from PyData.
// PyObject can be decoded from PyData.
XXX
type
PyObject
struct
{
//oid Oid
//serial Tid
Jar
*
Connection
// XXX -> ro
Oid
Oid
// XXX -> ro
Serial
Tid
// XXX -> ro
// XXX + Oid, Serial ? (_p_oid, _p_serial)
pyClass
pickle
.
Class
// python class of this object XXX -> ro
State
interface
{}
// object state. python passes this to pyclass.__new__().__setstate__()
PyClass
pickle
.
Class
// python class of this object XXX -> ro ?
PyState
interface
{}
// object state. python passes this to pyclass.__new__().__setstate__()
}
...
...
@@ -67,18 +125,19 @@ type PyLoader interface {
}
/*
// Decode decodes raw ZODB python data into PyObject. XXX -> (pyclass, pystate)
//func (d PyData) Decode() (*PyObject, error) {
func
(
d
PyData
)
Decode
()
(
pyclass
Py
Class
,
pystate
interface
{},
_
error
)
{
func (d PyData) Decode() (pyclass
pickle.
Class, pystate interface{}, _ error) {
p := pickle.NewDecoder(bytes.NewReader([]byte(d)))
xklass, err := p.Decode()
if err != nil {
return
nil
,
fmt
.
Errorf
(
"pydata: decode: class description: %s"
,
err
)
return nil,
nil,
fmt.Errorf("pydata: decode: class description: %s", err)
}
klass, err := normPyClass(xklass)
if err != nil {
return
nil
,
fmt
.
Errorf
(
"pydata: decode: class description: %s"
,
err
)
return nil,
nil,
fmt.Errorf("pydata: decode: class description: %s", err)
}
state, err := p.Decode()
...
...
@@ -86,8 +145,10 @@ func (d PyData) Decode() (pyclass PyClass, pystate interface{}, _ error) {
return nil, fmt.Errorf("pydata: decode: object state: %s", err)
}
return
&
PyObject
{
pyClass
:
klass
,
State
:
state
},
nil
//return &PyObject{pyClass: klass, State: state}, nil
return klass, state, nil
}
*/
// ClassName returns fully-qualified python class name used for object type.
...
...
@@ -150,7 +211,7 @@ func normPyClass(xklass interface{}) (pickle.Class, error) {
return
pickle
.
Class
{},
errInvalidPyClass
}
// PyClass returns Python class of the object.
func
(
pyobj
*
PyObject
)
PyClass
()
pickle
.
Class
{
return
pyobj
.
pyClass
}
//
//
PyClass returns Python class of the object.
//
func (pyobj *PyObject) PyClass() pickle.Class {
//
return pyobj.pyClass
//
}
This diff is collapsed.
Click to expand it.
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