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() { ...@@ -345,6 +345,11 @@ 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{} {
panic("TODO")
}
// 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 +445,11 @@ func (t *btreeState) DropState() { ...@@ -440,6 +445,11 @@ 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{} {
panic("TODO")
}
// 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
......
...@@ -347,6 +347,11 @@ func (b *iobucketState) DropState() { ...@@ -347,6 +347,11 @@ 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{} {
panic("TODO")
}
// 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 +447,11 @@ func (t *iobtreeState) DropState() { ...@@ -442,6 +447,11 @@ 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{} {
panic("TODO")
}
// 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,11 @@ func (b *lobucketState) DropState() { ...@@ -347,6 +347,11 @@ 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{} {
panic("TODO")
}
// 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 +447,11 @@ func (t *lobtreeState) DropState() { ...@@ -442,6 +447,11 @@ 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{} {
panic("TODO")
}
// 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
......
...@@ -44,6 +44,7 @@ import ( ...@@ -44,6 +44,7 @@ import (
// type myObjectState MyObject // type myObjectState MyObject
// //
// func (o *myObjectState) DropState() { ... } // func (o *myObjectState) DropState() { ... }
// func (o *myObjectState) GetState() *mem.Buf { ... }
// func (o *myObjectState) SetState(state *mem.Buf) error { ... } // func (o *myObjectState) SetState(state *mem.Buf) error { ... }
// //
// func init() { // func init() {
...@@ -98,23 +99,34 @@ type loadState struct { ...@@ -98,23 +99,34 @@ type loadState struct {
// Ghostable is the interface describing in-RAM object who can release its in-RAM state. // Ghostable is the interface describing in-RAM object who can release its in-RAM state.
type Ghostable interface { type Ghostable interface {
// DropState should discard in-RAM object state. // 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() DropState()
} }
// Stateful is the interface describing in-RAM object whose data state can be // Stateful is the interface describing in-RAM object whose data state can be
// exchanged as raw bytes. // exchanged as raw bytes.
type Stateful interface { 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. // 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 // state ownership is not passed to SetState, so if state needs to be
// retained after SetState returns it needs to be incref'ed. // retained after SetState returns it needs to be incref'ed.
// //
// The error returned does not need to have object/setstate prefix - // The error returned does not need to have object/setstate prefix -
// persistent machinery is adding such prefix automatically. // persistent machinery is adding such prefix automatically.
SetState(state *mem.Buf) error 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() { ...@@ -229,6 +241,11 @@ func (obj *Persistent) PDeactivate() {
} }
} }
// already ghost
if obj.state == GHOST {
return
}
obj.serial = InvalidTid obj.serial = InvalidTid
obj.istate().DropState() obj.istate().DropState()
obj.state = GHOST obj.state = GHOST
...@@ -245,6 +262,11 @@ func (obj *Persistent) PInvalidate() { ...@@ -245,6 +262,11 @@ func (obj *Persistent) PInvalidate() {
panic(obj.badf("invalidate: refcnt != 0 (= %d)", obj.refcnt)) panic(obj.badf("invalidate: refcnt != 0 (= %d)", obj.refcnt))
} }
// already ghost
if obj.state == GHOST {
return
}
obj.serial = InvalidTid obj.serial = InvalidTid
obj.istate().DropState() obj.istate().DropState()
obj.state = GHOST obj.state = GHOST
...@@ -482,6 +504,7 @@ type Broken struct { ...@@ -482,6 +504,7 @@ type Broken struct {
} }
// XXX register (Broken, brokenState) ? // XXX register (Broken, brokenState) ?
var _ interface { Ghostable; Stateful} = (*brokenState)(nil)
type brokenState Broken // hide state methods from public API type brokenState Broken // hide state methods from public API
...@@ -490,6 +513,11 @@ func (b *brokenState) DropState() { ...@@ -490,6 +513,11 @@ func (b *brokenState) DropState() {
b.state = nil b.state = nil
} }
func (b *brokenState) GetState() *mem.Buf {
b.state.Incref()
return b.state
}
func (b *brokenState) SetState(state *mem.Buf) error { func (b *brokenState) SetState(state *mem.Buf) error {
b.state.XRelease() b.state.XRelease()
state.Incref() state.Incref()
......
...@@ -51,6 +51,10 @@ func (o *myObjectState) PySetState(pystate interface{}) error { ...@@ -51,6 +51,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
......
...@@ -29,17 +29,24 @@ import ( ...@@ -29,17 +29,24 @@ import (
// PyStateful is the interface describing in-RAM object whose data state can be // PyStateful is the interface describing in-RAM object whose data state can be
// exchanged as Python data. // exchanged as Python data.
type PyStateful interface { 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. // PySetState should set state of the in-RAM object from Python data.
// //
// It is analog of __setstate__() in Python. // 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 - // 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 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 // 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