Commit 0979eab2 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1b190e2b
...@@ -345,6 +345,22 @@ func (b *bucketState) DropState() { ...@@ -345,6 +345,22 @@ func (b *bucketState) DropState() {
b.values = nil b.values = nil
} }
// PyGetState implements zodb.PyStateful to get bucket data as pystate.
func (b *bucketState) PyGetState() interface{} {
// XXX assert len(b.keys) == len(b.values) ?
t := make(pickle.Tuple, 0, 2*len(b.keys))
for i := range b.keys {
t = append(t, b.keys[i], b.values[i])
}
t = pickle.Tuple{t}
if b.next != nil {
t = append(t, b.next)
}
return t
}
// PySetState implements zodb.PyStateful to set bucket data from pystate. // PySetState implements zodb.PyStateful to set bucket data from pystate.
func (b *bucketState) PySetState(pystate interface{}) (err error) { func (b *bucketState) PySetState(pystate interface{}) (err error) {
t, ok := pystate.(pickle.Tuple) t, ok := pystate.(pickle.Tuple)
...@@ -440,6 +456,36 @@ func (t *btreeState) DropState() { ...@@ -440,6 +456,36 @@ func (t *btreeState) DropState() {
t.data = nil t.data = nil
} }
// PyGetState implements zodb.PyStateful to get btree data as pystate.
func (bt *btreeState) PyGetState() interface{} {
// empty btree
if len(bt.data) == 0 {
// XXX assert .firstbucket = nil ?
return pickle.None{}
}
// btree with 1 child bucket without oid
if len(bt.data) == 1 {
bucket, ok := bt.data[0].child.(*Bucket)
if ok && bucket.POid() == zodb.InvalidOid { // XXX recheck vs "NULL oid"
return pickle.Tuple{pickle.Tuple{((*bucketState)(bucket)).PyGetState()}}
}
}
// regular btree
t := make(pickle.Tuple, 0, 2*len(bt.data)-1)
for i, entry := range bt.data {
// key[0] is unused and not saved
if i > 0 {
t = append(t, entry.key)
}
t = append(t, entry.child)
}
t = pickle.Tuple{t}
t = append(t, bt.firstbucket)
return t
}
// PySetState implements zodb.PyStateful to set btree data from pystate. // PySetState implements zodb.PyStateful to set btree data from pystate.
func (bt *btreeState) PySetState(pystate interface{}) (err error) { func (bt *btreeState) PySetState(pystate interface{}) (err error) {
// empty btree // empty btree
......
...@@ -252,6 +252,8 @@ func TestBTree(t *testing.T) { ...@@ -252,6 +252,8 @@ func TestBTree(t *testing.T) {
return firstbucket return firstbucket
} }
// XXX verify PyGetState <-> PySetState is the same.
// XXX verify Entryv ? // XXX verify Entryv ?
// XXX verify FirstBucket / Next ? // XXX verify FirstBucket / Next ?
......
...@@ -347,6 +347,22 @@ func (b *iobucketState) DropState() { ...@@ -347,6 +347,22 @@ func (b *iobucketState) DropState() {
b.values = nil b.values = nil
} }
// PyGetState implements zodb.PyStateful to get bucket data as pystate.
func (b *iobucketState) PyGetState() interface{} {
// XXX assert len(b.keys) == len(b.values) ?
t := make(pickle.Tuple, 0, 2*len(b.keys))
for i := range b.keys {
t = append(t, b.keys[i], b.values[i])
}
t = pickle.Tuple{t}
if b.next != nil {
t = append(t, b.next)
}
return t
}
// PySetState implements zodb.PyStateful to set bucket data from pystate. // PySetState implements zodb.PyStateful to set bucket data from pystate.
func (b *iobucketState) PySetState(pystate interface{}) (err error) { func (b *iobucketState) PySetState(pystate interface{}) (err error) {
t, ok := pystate.(pickle.Tuple) t, ok := pystate.(pickle.Tuple)
...@@ -442,6 +458,36 @@ func (t *iobtreeState) DropState() { ...@@ -442,6 +458,36 @@ func (t *iobtreeState) DropState() {
t.data = nil t.data = nil
} }
// PyGetState implements zodb.PyStateful to get btree data as pystate.
func (bt *iobtreeState) PyGetState() interface{} {
// empty btree
if len(bt.data) == 0 {
// XXX assert .firstbucket = nil ?
return pickle.None{}
}
// btree with 1 child bucket without oid
if len(bt.data) == 1 {
bucket, ok := bt.data[0].child.(*IOBucket)
if ok && bucket.POid() == zodb.InvalidOid { // XXX recheck vs "NULL oid"
return pickle.Tuple{pickle.Tuple{((*iobucketState)(bucket)).PyGetState()}}
}
}
// regular btree
t := make(pickle.Tuple, 0, 2*len(bt.data)-1)
for i, entry := range bt.data {
// key[0] is unused and not saved
if i > 0 {
t = append(t, entry.key)
}
t = append(t, entry.child)
}
t = pickle.Tuple{t}
t = append(t, bt.firstbucket)
return t
}
// PySetState implements zodb.PyStateful to set btree data from pystate. // PySetState implements zodb.PyStateful to set btree data from pystate.
func (bt *iobtreeState) PySetState(pystate interface{}) (err error) { func (bt *iobtreeState) PySetState(pystate interface{}) (err error) {
// empty btree // empty btree
......
...@@ -347,6 +347,22 @@ func (b *lobucketState) DropState() { ...@@ -347,6 +347,22 @@ func (b *lobucketState) DropState() {
b.values = nil b.values = nil
} }
// PyGetState implements zodb.PyStateful to get bucket data as pystate.
func (b *lobucketState) PyGetState() interface{} {
// XXX assert len(b.keys) == len(b.values) ?
t := make(pickle.Tuple, 0, 2*len(b.keys))
for i := range b.keys {
t = append(t, b.keys[i], b.values[i])
}
t = pickle.Tuple{t}
if b.next != nil {
t = append(t, b.next)
}
return t
}
// PySetState implements zodb.PyStateful to set bucket data from pystate. // PySetState implements zodb.PyStateful to set bucket data from pystate.
func (b *lobucketState) PySetState(pystate interface{}) (err error) { func (b *lobucketState) PySetState(pystate interface{}) (err error) {
t, ok := pystate.(pickle.Tuple) t, ok := pystate.(pickle.Tuple)
...@@ -442,6 +458,36 @@ func (t *lobtreeState) DropState() { ...@@ -442,6 +458,36 @@ func (t *lobtreeState) DropState() {
t.data = nil t.data = nil
} }
// PyGetState implements zodb.PyStateful to get btree data as pystate.
func (bt *lobtreeState) PyGetState() interface{} {
// empty btree
if len(bt.data) == 0 {
// XXX assert .firstbucket = nil ?
return pickle.None{}
}
// btree with 1 child bucket without oid
if len(bt.data) == 1 {
bucket, ok := bt.data[0].child.(*LOBucket)
if ok && bucket.POid() == zodb.InvalidOid { // XXX recheck vs "NULL oid"
return pickle.Tuple{pickle.Tuple{((*lobucketState)(bucket)).PyGetState()}}
}
}
// regular btree
t := make(pickle.Tuple, 0, 2*len(bt.data)-1)
for i, entry := range bt.data {
// key[0] is unused and not saved
if i > 0 {
t = append(t, entry.key)
}
t = append(t, entry.child)
}
t = pickle.Tuple{t}
t = append(t, bt.firstbucket)
return t
}
// PySetState implements zodb.PyStateful to set btree data from pystate. // PySetState implements zodb.PyStateful to set btree data from pystate.
func (bt *lobtreeState) PySetState(pystate interface{}) (err error) { func (bt *lobtreeState) PySetState(pystate interface{}) (err error) {
// empty btree // empty btree
......
...@@ -17,20 +17,8 @@ ...@@ -17,20 +17,8 @@
// See COPYING file for full licensing terms. // See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options. // See https://www.nexedi.com/licensing for rationale and options.
package zodb_test package zodb
// things imported at runtime via import_x_test due to cyclic dependency
import ( var ZPyCommit func(string, Tid, ...interface{}) (Tid, error) // XXX ZObject
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/internal/xtesting"
// wks or any other storage cannot be imported from zodb due to cycle
_ "lab.nexedi.com/kirr/neo/go/zodb/wks"
)
// import at runtime few things into zodb, that zodb cannot import itself due to cyclic dependency.
func init() {
//zodb.ZPyCommit = xtesting.ZPyCommit
zodb.ZPyCommit = func(zurl string, at zodb.Tid, objv ...interface{}) (zodb.Tid, error) {
return xtesting.ZPyCommit(zurl, at) // XXX + objv
}
}
// Copyright (C) 2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
// option) any later version, as published by the Free Software Foundation.
//
// You can also Link and Combine this program with other software covered by
// the terms of any of the Free Software licenses or any of the Open Source
// Initiative approved licenses and Convey the resulting work. Corresponding
// source of such a combination shall include the source code for all other
// software used.
//
// This program is distributed WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
package zodb_test
import (
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/internal/xtesting"
// wks or any other storage cannot be imported from zodb due to cycle
_ "lab.nexedi.com/kirr/neo/go/zodb/wks"
)
// import at runtime few things into zodb, that zodb cannot import itself due to cyclic dependency.
func init() {
//zodb.ZPyCommit = xtesting.ZPyCommit
zodb.ZPyCommit = func(zurl string, at zodb.Tid, objv ...interface{}) (zodb.Tid, error) {
return xtesting.ZPyCommit(zurl, at) // XXX + objv
}
}
...@@ -115,7 +115,10 @@ type Stateful interface { ...@@ -115,7 +115,10 @@ type Stateful interface {
SetState(state *mem.Buf) error SetState(state *mem.Buf) error
// GetState should return state of the in-RAM object as raw data. // GetState should return state of the in-RAM object as raw data.
//GetState() *mem.Buf TODO //
// XXX called only when state is not dropped.
// XXX buf ownership.
GetState() *mem.Buf
} }
......
...@@ -57,6 +57,10 @@ func (o *myObjectState) PySetState(pystate interface{}) error { ...@@ -57,6 +57,10 @@ func (o *myObjectState) PySetState(pystate interface{}) error {
return nil return nil
} }
func (o *myObjectState) PyGetState() interface{} {
return o.value
}
// Peristent that is not registered to ZODB. // Peristent that is not registered to ZODB.
type Unregistered struct { type Unregistered struct {
Persistent Persistent
...@@ -173,8 +177,6 @@ func (cc *zcacheControl) WantEvict(obj IPersistent) bool { ...@@ -173,8 +177,6 @@ func (cc *zcacheControl) WantEvict(obj IPersistent) bool {
return true return true
} }
var ZPyCommit func(string, Tid, ...interface{}) (Tid, error) // XXX ZObject
// Persistent tests with storage. // Persistent tests with storage.
func TestPersistentDB(t *testing.T) { func TestPersistentDB(t *testing.T) {
X := exc.Raiseif X := exc.Raiseif
......
// Copyright (C) 2018 Nexedi SA and Contributors. // Copyright (C) 2018-2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your // it under the terms of the GNU General Public License version 3, or (at your
...@@ -39,7 +39,10 @@ type PyStateful interface { ...@@ -39,7 +39,10 @@ type PyStateful interface {
// PyGetState should return state of the in-RAM object as Python data. // PyGetState should return state of the in-RAM object as Python data.
// Analog of __getstate__() in Python. // Analog of __getstate__() in Python.
//PyGetState() interface{} TODO //
// XXX called only when state is not dropped.
// XXX state ownership?
PyGetState() interface{}
} }
// pySetState decodes raw state as zodb/py serialized stream, and sets decoded // pySetState decodes raw state as zodb/py serialized stream, and sets decoded
......
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