Commit 8192892a authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent f5b30c35
......@@ -20,6 +20,7 @@ package btree
import (
"context"
"reflect"
"sort"
"lab.nexedi.com/kirr/go123/xerr"
......@@ -316,17 +317,7 @@ func (b *Bucket) PySetState(pystate interface{}) error {
// ---- register classes to ZODB ----
func bucketNew(base *zodb.Persistent) zodb.IPersistent {
// XXX simplify vvv
return &Bucket{PyPersistent: &zodb.PyPersistent{Persistent: base}}
}
func btreeNew(base *zodb.Persistent) zodb.IPersistent {
// XXX simplify vvv
return &BTree{PyPersistent: &zodb.PyPersistent{Persistent: base}}
}
func init() {
zodb.RegisterClass("zodb.BTree.LOBucket", bucketNew)
zodb.RegisterClass("zodb.BTree.LOBtree", btreeNew)
zodb.RegisterClass("zodb.BTree.LOBucket", reflect.TypeOf(Bucket{}))
zodb.RegisterClass("zodb.BTree.LOBtree", reflect.TypeOf(BTree{}))
}
......@@ -108,43 +108,7 @@ type LiveCacheControl interface {
}
// ---- class -> new ghost ----
// XXX type Class string ?
// function representing new of a class.
type classNewFunc func(base *Persistent) IPersistent
// {} class -> new(pyobj XXX)
var classTab = make(map[string]classNewFunc)
/*
// RegisterClass registers ZODB class to be transformed to Go instance
// created via classNew.
//
// Must be called from global init().
func RegisterClass(class string, classNew classNewFunc) {
classTab[class] = classNew
// XXX + register so that PyData decode handles class
}
// newGhost creates new ghost object corresponding to class and oid.
func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
base := &Persistent{class: class, jar: conn, oid: oid, serial: 0, state: GHOST}
// switch on pyclass and transform e.g. "zodb.BTree.Bucket" -> *ZBucket
classNew := classTab[class]
var instance IPersistent
if classNew != nil {
instance = classNew(base)
} else {
instance = &Broken{Persistent: base}
}
base.instance = instance
return instance
}
*/
// ---- class <-> type; new ghost ----
var class2Type = make(map[string]reflect.Type) // {} class -> type
var type2Class = make(map[reflect.Type]string) // {} type -> class
......@@ -156,25 +120,57 @@ func zclassOf(obj IPersistent) string {
return type2Class[reflect.TypeOf(obj)]
}
var rIPersistent = reflect.TypeOf((*IPersistent)(nil)).Elem() // typeof(IPersistent)
var rGhostable = reflect.TypeOf((*Ghostable)(nil)).Elem() // typeof(Ghostable)
var rStateful = reflect.TypeOf((*Stateful)(nil)).Elem() // typeof(Stateful)
var rPyStateful = reflect.TypeOf((*PyStateful)(nil)).Elem() // typeof(PyStateful)
// RegisterClass registers ZODB class to correspond to Go type.
//
// *type must implement IPersistent. XXX and either Stateful or PyStateful
// type must embed IPersistent.
// *type must implement IPersistent, Ghostable and either Stateful or PyStateful.
//
// Must be called from global init().
func RegisterClass(class string, typ reflect.Type) {
rIPersistent := reflect.TypeOf(IPersistent(nil))
if !typ.Implements(rIPersistent) {
panic(fmt.Sprintf("zodb: register class: %q does not implement IPersistent", typ))
badf := func(format string, argv ...interface{}) {
msg := fmt.Sprintf(format, argv...)
panic(fmt.Sprintf("zodb: register class (%q, %q): %s", class, typ, msg))
}
if class == "" {
badf("class must be not empty")
}
if typ, already := class2Type[class]; already {
badf("class already registered for %q", typ)
}
// typ must have IPersistent embedded
basef, ok := typ.FieldByName("IPersistent")
if !(ok && basef.Anonymous && basef.Type == rIPersistent) {
badf("type does not embed IPersistent")
}
switch {
case !typ.Implements(rIPersistent):
// typ must not override IPersistent methods with e.g. different signature
badf("does not implement IPersistent")
case !typ.Implements(rGhostable):
badf("does not implement Ghostable")
}
stateful := typ.Implements(rStateful)
pystateful := typ.Implements(rPyStateful)
if !(stateful || pystateful) {
badf("does not implement any of Stateful or PyStateful")
}
// find out if typ implements PyStateful and, if yes, use PyPersistent as base
rPyStateful := reflect.TypeOf(PyStateful(nil))
if typ.Implements(rPyStateful) {
if pystateful {
// XXX
}
// XXX check typ has IPersistent embedded
// XXX check *typ implements Stateful
// XXX check if class was already registered
// XXX check class != ""
......@@ -201,7 +197,7 @@ func (conn *Connection) newGhost(class string, oid Oid) IPersistent {
xobjBase.Set(reflect.ValueOf(base))
obj := xpobj.Interface()
base.instance = obj.(interface{IPersistent; Stateful})
base.instance = obj.(interface{IPersistent; Ghostable; Stateful})
return base.instance
}
......
......@@ -31,8 +31,6 @@ import (
//
// XXX safe to access from multiple goroutines simultaneously.
type IPersistent interface {
//zclass() string // ZODB class of this object. XXX remove from IPersistent?
PJar() *Connection // Connection this in-RAM object is part of.
POid() Oid // object ID in the database.
......@@ -100,11 +98,6 @@ type IPersistent interface {
// XXX probably don't need this.
//PState() ObjectState // in-RAM object state.
// // Object must be stateful for persistency to work.
// // XXX try to move out of IPersistent?
// Stateful
}
// ObjectState describes state of in-RAM object.
......@@ -119,9 +112,6 @@ const (
// Persistent is common base implementation for in-RAM representation of database objects.
type Persistent struct {
// // XXX kill here; move -> Broken
// class string // zodb class of this object. XXX try not to store and retrieve via reflect?
jar *Connection
oid Oid
serial Tid
......@@ -129,11 +119,10 @@ type Persistent struct {
mu sync.Mutex
state ObjectState
refcnt int32
instance interface{IPersistent; Stateful} // Persistent should be the base for the instance
instance interface{IPersistent; Ghostable; Stateful} // Persistent should be the base for the instance
loading *loadState
}
//func (obj *Persistent) zclass() string { return obj.class }
func (obj *Persistent) PJar() *Connection { return obj.jar }
func (obj *Persistent) POid() Oid { return obj.oid }
func (obj *Persistent) PSerial() Tid { return obj.serial }
......@@ -150,13 +139,15 @@ type loadState struct {
err error
}
// Stateful is the interface describing in-RAM object whose data state can be
// exchanged as raw bytes.
type Stateful interface {
// Ghostable is the interface describin in-RAM object who can release its in-RAM state.
type Ghostable interface {
// DropState should discard in-RAM object state.
// XXX move out of Stateful? -> Ghostable?
DropState()
}
// Stateful is the interface describing in-RAM object whose data state can be
// exchanged as raw bytes.
type Stateful interface {
// SetState should set state of the in-RAM object from raw data.
//
// state ownership is not passed to SetState, so if state needs to be
......
......@@ -42,7 +42,6 @@ type IPyPersistent interface {
// PyPersistent is common base implementation for in-RAM representation of ZODB Python objects.
type PyPersistent struct {
*Persistent // XXX remove ptr
// pyclass pickle.Class // XXX kill
}
//func (pyobj *PyPersistent) PyClass() pickle.Class { return pyobj.pyclass }
......
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