Commit 7b2dca36 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent d3c86584
......@@ -79,6 +79,7 @@ func (t *ZBTree) Get(ctx context.Context, key KEY) (interface{}, bool, error) {
if len(t.data) == 0 {
// empty btree
t.PDeactivate()
return nil, false, nil
}
......@@ -94,13 +95,15 @@ func (t *ZBTree) Get(ctx context.Context, key KEY) (interface{}, bool, error) {
switch child := t.data[i].child.(type) {
case *ZBTree:
// XXX t.PAllowDeactivate
t.PDeactivate()
t = child
t.PActivate(ctx) // XXX err
case *ZBucket:
t.PDeactivate()
child.PActivate(ctx) // XXX err
v, ok := child.get(key)
child.PDeactivate()
return v, ok, nil
}
}
......@@ -181,8 +184,10 @@ func (t *ZBTree) PActivate(ctx context.Context) error {
// PDeactivate implements Object.
func (b *ZBucket) PDeactivate() {
// XXX check if activated
// b.pyObject.PDeactivate() ...
b.next = nil
b.keys = nil
b.values = nil
......@@ -200,7 +205,7 @@ func (b *ZBucket) PActivate(ctx context.Context) (bool, error) {
return false, nil
}
// FIXME other users must wait for first decode to complet
// FIXME other users must wait for first decode to complete
err = b.decode()
if err != nil {
b.pyObject.PDeactivate()
......
......@@ -122,15 +122,6 @@ func (pyobj *pyObject) PyClass() pickle.Class { return pyobj.pyclass }
func (pyobj *pyObject) PyState() interface{} { return pyobj.pystate }
// LiveCacheControl is the interface that allows applications to influence
// Connection's decisions with respect to its live cache.
type LiveCacheControl interface {
// WantEvict is called when object is going to be evicted from live cache and made ghost.
// If !ok the object will remain live.
WantEvict(obj Object) (ok bool)
}
// Connection represents a view of ZODB database.
//
// The view is representing state of ZODB objects as of `at` transaction.
......@@ -200,6 +191,17 @@ type Connection struct {
cacheControl LiveCacheControl
}
// LiveCacheControl is the interface that allows applications to influence
// Connection's decisions with respect to its live cache.
type LiveCacheControl interface {
// WantEvict is called when object is going to be evicted from live cache and made ghost.
// If !ok the object will remain live.
WantEvict(obj Object) (ok bool)
}
// ----------------------------------------
// Get returns in-RAM object corresponding to specified ZODB object according to current database view.
//
......@@ -211,7 +213,7 @@ type Connection struct {
// The object's data is not neccessarily loaded after Get returns. Use
// PActivate to make sure the object ifs fully loaded.
func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (interface{} /*PyObject*/, error) {
conn.objmu.Lock()
conn.objmu.Lock() // XXX -> rlock
wobj := conn.objtab[oid]
var xobj interface{}
if wobj != nil {
......@@ -263,7 +265,7 @@ func (e *wrongClassError) Error() string {
//
// XXX object scope.
//
// use-case: in ZODB references are (pyclass, oid), so new ghost is created
// Use-case: in ZODB references are (pyclass, oid), so new ghost is created
// without further loading anything.
func (conn *Connection) get(pyclass pickle.Class, oid zodb.Oid) (PyObject, error) {
conn.objmu.Lock() // XXX -> rlock
......@@ -298,22 +300,27 @@ func (conn *Connection) get(pyclass pickle.Class, oid zodb.Oid) (PyObject, error
}
// loadpy loads object specified by oid and decodes it as a ZODB Python object.
//
// loadpy does not create any in-RAM object associated with Connection.
// It only returns decoded database data.
func (conn *Connection) loadpy(ctx context.Context, oid zodb.Oid) (pyclass pickle.Class, pystate interface{}, serial zodb.Tid, _ error) {
buf, serial, err := conn.stor.Load(ctx, zodb.Xid{Oid: oid, At: conn.at})
if err != nil {
return pickle.Class{}, nil, 0, err
}
defer buf.Release()
pyclass, pystate, err = zodb.PyData(buf.Data).Decode()
if err != nil {
return pickle.Class{}, nil, 0, err // XXX err ctx
}
buf.Release()
return pyclass, pystate, serial, nil
}
// ---- pyclass -> new ghost ----
// path(class) -> new(pyobj)
var classTab = make(map[string]func(*pyObject)PyObject)
......@@ -445,5 +452,3 @@ func (pyobj *pyObject) PDeactivate() {
// XXX pyobj.PInvalidate() = deactivate without checking if state != modified
// XXX panic if refcnt != 0 (object being used)
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