Commit e020026a authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb: Complete (Py)Stateful & Ghostable

- require (Py)GetState and make it clear that it is called by
  persistency machinery only on non-ghost objects.
- make it clear that (Py)SetState is called by persistency machinery
  only on ghost objects.
- make it clear that DropState is called by persistency machinery only
  on non-ghost objects.

For btree PyGetState is marked as TODO which we'll fill incrementally
(the code is draftly ready, but there is no test for now).
parent 7f14e2cb
......@@ -345,6 +345,11 @@ func (b *bucketState) DropState() {
b.values = nil
}
// PyGetState implements zodb.PyStateful to get bucket data as pystate.
func (b *bucketState) PyGetState() interface{} {
panic("TODO")
}
// PySetState implements zodb.PyStateful to set bucket data from pystate.
func (b *bucketState) PySetState(pystate interface{}) (err error) {
t, ok := pystate.(pickle.Tuple)
......@@ -440,6 +445,11 @@ func (t *btreeState) DropState() {
t.data = nil
}
// PyGetState implements zodb.PyStateful to get btree data as pystate.
func (bt *btreeState) PyGetState() interface{} {
panic("TODO")
}
// PySetState implements zodb.PyStateful to set btree data from pystate.
func (bt *btreeState) PySetState(pystate interface{}) (err error) {
// empty btree
......
......@@ -347,6 +347,11 @@ func (b *iobucketState) DropState() {
b.values = nil
}
// PyGetState implements zodb.PyStateful to get bucket data as pystate.
func (b *iobucketState) PyGetState() interface{} {
panic("TODO")
}
// PySetState implements zodb.PyStateful to set bucket data from pystate.
func (b *iobucketState) PySetState(pystate interface{}) (err error) {
t, ok := pystate.(pickle.Tuple)
......@@ -442,6 +447,11 @@ func (t *iobtreeState) DropState() {
t.data = nil
}
// PyGetState implements zodb.PyStateful to get btree data as pystate.
func (bt *iobtreeState) PyGetState() interface{} {
panic("TODO")
}
// PySetState implements zodb.PyStateful to set btree data from pystate.
func (bt *iobtreeState) PySetState(pystate interface{}) (err error) {
// empty btree
......
......@@ -347,6 +347,11 @@ func (b *lobucketState) DropState() {
b.values = nil
}
// PyGetState implements zodb.PyStateful to get bucket data as pystate.
func (b *lobucketState) PyGetState() interface{} {
panic("TODO")
}
// PySetState implements zodb.PyStateful to set bucket data from pystate.
func (b *lobucketState) PySetState(pystate interface{}) (err error) {
t, ok := pystate.(pickle.Tuple)
......@@ -442,6 +447,11 @@ func (t *lobtreeState) DropState() {
t.data = nil
}
// PyGetState implements zodb.PyStateful to get btree data as pystate.
func (bt *lobtreeState) PyGetState() interface{} {
panic("TODO")
}
// PySetState implements zodb.PyStateful to set btree data from pystate.
func (bt *lobtreeState) PySetState(pystate interface{}) (err error) {
// empty btree
......
......@@ -44,6 +44,7 @@ import (
// type myObjectState MyObject
//
// func (o *myObjectState) DropState() { ... }
// func (o *myObjectState) GetState() *mem.Buf { ... }
// func (o *myObjectState) SetState(state *mem.Buf) error { ... }
//
// func init() {
......@@ -98,23 +99,34 @@ type loadState struct {
// Ghostable is the interface describing in-RAM object who can release its in-RAM state.
type Ghostable interface {
// DropState should discard in-RAM object state.
//
// It is called by persistency machinery only on non-ghost objects,
// i.e. when the objects has its in-RAM state.
DropState()
}
// Stateful is the interface describing in-RAM object whose data state can be
// exchanged as raw bytes.
type Stateful interface {
// GetState should return state of the in-RAM object as raw data.
//
// It is called by persistency machinery only on non-ghost objects,
// i.e. when the object has its in-RAM state.
//
// GetState should return a new buffer reference.
GetState() *mem.Buf
// SetState should set state of the in-RAM object from raw data.
//
// It is called by persistency machinery only on ghost objects, i.e.
// when the objects does not yet have its in-RAM state.
//
// state ownership is not passed to SetState, so if state needs to be
// retained after SetState returns it needs to be incref'ed.
//
// The error returned does not need to have object/setstate prefix -
// persistent machinery is adding such prefix automatically.
SetState(state *mem.Buf) error
// GetState should return state of the in-RAM object as raw data.
//GetState() *mem.Buf TODO
}
......@@ -229,6 +241,11 @@ func (obj *Persistent) PDeactivate() {
}
}
// already ghost
if obj.state == GHOST {
return
}
obj.serial = InvalidTid
obj.istate().DropState()
obj.state = GHOST
......@@ -245,6 +262,11 @@ func (obj *Persistent) PInvalidate() {
panic(obj.badf("invalidate: refcnt != 0 (= %d)", obj.refcnt))
}
// already ghost
if obj.state == GHOST {
return
}
obj.serial = InvalidTid
obj.istate().DropState()
obj.state = GHOST
......@@ -482,6 +504,7 @@ type Broken struct {
}
// XXX register (Broken, brokenState) ?
var _ interface { Ghostable; Stateful} = (*brokenState)(nil)
type brokenState Broken // hide state methods from public API
......@@ -490,6 +513,11 @@ func (b *brokenState) DropState() {
b.state = nil
}
func (b *brokenState) GetState() *mem.Buf {
b.state.Incref()
return b.state
}
func (b *brokenState) SetState(state *mem.Buf) error {
b.state.XRelease()
state.Incref()
......
......@@ -51,6 +51,10 @@ func (o *myObjectState) PySetState(pystate interface{}) error {
return nil
}
func (o *myObjectState) PyGetState() interface{} {
return o.value
}
// Peristent that is not registered to ZODB.
type Unregistered struct {
Persistent
......
......@@ -29,17 +29,24 @@ import (
// PyStateful is the interface describing in-RAM object whose data state can be
// exchanged as Python data.
type PyStateful interface {
// PyGetState should return state of the in-RAM object as Python data.
//
// It is analog of __getstate__() in Python.
//
// It is called by persistency machinery only on non-ghost objects,
// i.e. when the object has its in-RAM state.
PyGetState() interface{}
// PySetState should set state of the in-RAM object from Python data.
//
// It is analog of __setstate__() in Python.
//
// It is called by persistency machinery only on ghost objects, i.e.
// when the objects does not yet have its in-RAM state.
//
// The error returned does not need to have object/setstate prefix -
// persistent machinery is adding such prefix automatically.
// persistency machinery is adding such prefix automatically.
PySetState(pystate interface{}) error
// PyGetState should return state of the in-RAM object as Python data.
// Analog of __getstate__() in Python.
//PyGetState() interface{} TODO
}
// 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