Commit 8e7e9dcb authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 8192892a
......@@ -178,14 +178,16 @@ func (b *Bucket) get(key KEY) (interface{}, bool) {
//
// In the above, key[i] means self->data[i].key, and similarly for child[i].
type btreeState BTree // hide state methods from public API
// DropState implements zodb.Stateful.
func (t *BTree) DropState() {
func (t *btreeState) DropState() {
t.firstbucket = nil
t.data = nil
}
// PySetState implements zodb.PyStateful to set btree data from pystate.
func (bt *BTree) PySetState(pystate interface{}) error {
func (bt *btreeState) PySetState(pystate interface{}) error {
// empty btree
if _, ok := pystate.(pickle.None); ok {
bt.firstbucket = nil
......@@ -201,7 +203,7 @@ func (bt *BTree) PySetState(pystate interface{}) error {
// btree with 1 child bucket without oid
if len(t) == 1 {
bucket := &Bucket{PyPersistent: nil /* FIXME */}
err := bucket.PySetState(t[0])
err := (*bucketState)(bucket).PySetState(t[0])
if err != nil {
// XXX
}
......@@ -265,15 +267,17 @@ func (bt *BTree) PySetState(pystate interface{}) error {
// <self->next iff non-NULL>
// )
type bucketState Bucket // hide state methods from public API
// DropState implements Stateful to discard bucket state.
func (b *Bucket) DropState() {
func (b *bucketState) DropState() {
b.next = nil
b.keys = nil
b.values = nil
}
// PySetState implements PyStateful to set bucket data from pystate.
func (b *Bucket) PySetState(pystate interface{}) error {
func (b *bucketState) PySetState(pystate interface{}) error {
t, ok := pystate.(pickle.Tuple)
if !ok || !(1 <= len(t) && len(t) <= 2) {
// XXX complain
......@@ -318,6 +322,7 @@ func (b *Bucket) PySetState(pystate interface{}) error {
// ---- register classes to ZODB ----
func init() {
zodb.RegisterClass("zodb.BTree.LOBucket", reflect.TypeOf(Bucket{}))
zodb.RegisterClass("zodb.BTree.LOBtree", reflect.TypeOf(BTree{}))
t := reflect.TypeOf
zodb.RegisterClass("zodb.BTree.LOBucket", t(Bucket{}), t(bucketState{}))
zodb.RegisterClass("zodb.BTree.LOBtree", t(BTree{}), t(btreeState{}))
}
......@@ -110,8 +110,8 @@ type LiveCacheControl interface {
// ---- class <-> type; new ghost ----
var class2Type = make(map[string]reflect.Type) // {} class -> type
var type2Class = make(map[reflect.Type]string) // {} type -> class
var class2Type = make(map[string]reflect.Type) // {} class -> (type, stateType)
var type2Class = make(map[reflect.Type]string) // {} type -> (class, stateType)
// zclassOf returns ZODB class of a Go object.
//
......@@ -128,11 +128,17 @@ var rPyStateful = reflect.TypeOf((*PyStateful)(nil)).Elem() // typeof(PyStatef
// RegisterClass registers ZODB class to correspond to Go type.
//
// type must embed IPersistent.
// *type must implement IPersistent, Ghostable and either Stateful or PyStateful.
// typ must embed IPersistent; *typ must implement IPersistent.
//
// typ must be convertible to stateType; stateType must implement Ghostable and
// either Stateful or PyStateful(*)
//
// Must be called from global init().
func RegisterClass(class string, typ reflect.Type) {
//
// (*) the rationale for stateType coming separately is that this way for
// application types it is possible not to expose Ghostable and Stateful
// methods in their public API.
func RegisterClass(class string, typ, stateType reflect.Type) {
badf := func(format string, argv ...interface{}) {
msg := fmt.Sprintf(format, argv...)
panic(fmt.Sprintf("zodb: register class (%q, %q): %s", class, typ, msg))
......@@ -146,6 +152,8 @@ func RegisterClass(class string, typ reflect.Type) {
}
// typ must have IPersistent embedded
// TODO later change to directly embedding non-pointer Persistent | PyPersistent
// (optimize memory + less allocation)
basef, ok := typ.FieldByName("IPersistent")
if !(ok && basef.Anonymous && basef.Type == rIPersistent) {
badf("type does not embed IPersistent")
......
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