Commit a19787b9 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 3ec95a81
...@@ -244,7 +244,7 @@ func bucketNew(pyobj *PyObject) interface{} { ...@@ -244,7 +244,7 @@ func bucketNew(pyobj *PyObject) interface{} {
} }
func btreeNew(pyobj *PyObject) interface{} { func btreeNew(pyobj *PyObject) interface{} {
return &ZBtree{pyobj: pyobj} return &ZBTree{pyobj: pyobj}
} }
func init() { func init() {
......
...@@ -16,6 +16,7 @@ package main ...@@ -16,6 +16,7 @@ package main
import ( import (
"context" "context"
"sync"
"lab.nexedi.com/kirr/neo/go/zodb" "lab.nexedi.com/kirr/neo/go/zodb"
...@@ -97,9 +98,11 @@ type Connection struct { ...@@ -97,9 +98,11 @@ type Connection struct {
// NOTE2 finalizers don't run on when they are attached to an object in cycle. // NOTE2 finalizers don't run on when they are attached to an object in cycle.
// Hopefully we don't have cycles with ZBtree/ZBucket XXX verify this // Hopefully we don't have cycles with ZBtree/ZBucket XXX verify this
objmu sync.Mutex objmu sync.Mutex
objtab map[zodb.Oid]interface{} // oid -> WeakRef(PyObject) | loadInProgress //objtab map[zodb.Oid]interface{} // oid -> WeakRef(PyObject) | loadInProgress
objtab map[zodb.Oid]*WeakRef
} }
/*
// loadInProgress entry in Conn.objtab tells users, that try to get the entry, // loadInProgress entry in Conn.objtab tells users, that try to get the entry,
// that another goroutine is already in progress of loading it. // that another goroutine is already in progress of loading it.
type loadInProgress struct { type loadInProgress struct {
...@@ -109,6 +112,7 @@ type loadInProgress struct { ...@@ -109,6 +112,7 @@ type loadInProgress struct {
pyobj interface{} // XXX -> PyObject iface pyobj interface{} // XXX -> PyObject iface
err error err error
} }
*/
// Get returns in-RAM object corresponding to specified ZODB object according to current database view. // Get returns in-RAM object corresponding to specified ZODB object according to current database view.
// //
...@@ -117,9 +121,39 @@ type loadInProgress struct { ...@@ -117,9 +121,39 @@ type loadInProgress struct {
// //
// The object's data is not neccessarily loaded after Get returns. Use // The object's data is not neccessarily loaded after Get returns. Use
// PActivate to make sure the object ifs fully loaded. // PActivate to make sure the object ifs fully loaded.
func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (*PyObject, error) { func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (interface{} /*PyObject*/, error) {
// XXX = load raw oid, get its class -> get(pyclass, oid) // XXX = load raw oid, get its class -> get(pyclass, oid)
conn.objmu.Lock()
wobj := conn.objtab[oid]
var xobj interface{}
if wobj != nil {
xobj = wobj.Get()
}
conn.objmu.Unlock()
// object was already there in objtab.
if xobj != nil {
return xobj, nil
}
// object is not there in objtab - raw load it, get its class -> get(pyclass, oid)
pyclass, pystate, serial, err := conn.loadpy(ctx, oid)
if err != nil {
return nil, err // XXX errctx
}
xobj = conn.get(pyclass, oid)
// XXX we are dropping just loaded pystate. Usually Get should be used
// to only load root object, so maybe that is ok.
//
// TODO -> use (pystate, serial) to activate.
_, _ = pystate, serial
return xobj, nil
/*
conn.objmu.Lock() // XXX -> rlock conn.objmu.Lock() // XXX -> rlock
objentry := conn.objtab[oid] objentry := conn.objtab[oid]
...@@ -172,19 +206,38 @@ func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (*PyObject, error ...@@ -172,19 +206,38 @@ func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (*PyObject, error
} else { } else {
conn.objtab[oid] = NewWeakRef(pyobj) conn.objtab[oid] = NewWeakRef(pyobj)
} }
*/
} }
// get returns in-RAM object corresponding to specified ZODB object according to current database view. // get returns in-RAM object corresponding to specified ZODB object according to current database view.
// //
// If there is already in-RAM object that corresponds to oid, that in-RAM object is returned. // If there is already in-RAM object that corresponds to oid, that in-RAM object is returned.
// Otherwise new in-RAM object is created and filled with object's class loaded from the database. // Otherwise new in-RAM object is created according to specified class.
// //
// The object's data is not neccessarily loaded after get returns. Use // The object's data is not neccessarily loaded after get returns. Use
// PActivate to make sure the object ifs fully loaded. // PActivate to make sure the object is fully loaded.
// //
// use-case: in ZODB references are (pyclass, oid), so new ghost is created without loading anything. // use-case: in ZODB references are (pyclass, oid), so new ghost is created
func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb.Oid) (*PyObject, error) { // without further loading anything.
func (conn *Connection) get(pyclass pickle.Class, oid zodb.Oid) interface{}/*PyObject*/ {
conn.objmu.Lock() // XXX -> rlock conn.objmu.Lock() // XXX -> rlock
wobj := conn.objtab[oid]
var xobj interface{}
if wobj != nil {
xobj = wobj.Get()
// XXX check pyclass match.
}
if xobj == nil {
xobj = conn.newGhost(pyclass, oid)
conn.objtab[oid] = NewWeakRef(xobj)
}
conn.objmu.Unlock()
return xobj
}
/*
{
objentry := conn.objtab[oid] objentry := conn.objtab[oid]
// someone else is already loading the object. // someone else is already loading the object.
...@@ -236,7 +289,8 @@ func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb. ...@@ -236,7 +289,8 @@ func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb.
} else { } else {
conn.objtab[oid] = NewWeakRef(pyobj) conn.objtab[oid] = NewWeakRef(pyobj)
} }
}
*/
/* /*
// XXX -> loadpy // XXX -> loadpy
...@@ -257,12 +311,14 @@ func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb. ...@@ -257,12 +311,14 @@ func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb.
pyclass: pyclass, pyclass: pyclass,
pystate: pystate, pystate: pystate,
}, nil }, nil
*/
} }
*/
/*
func (conn *Connection) load(ctx context.Context, oid zodb.Oid) (*PyObject, error) { func (conn *Connection) load(ctx context.Context, oid zodb.Oid) (*PyObject, error) {
// XXX // XXX
} }
*/
func (conn *Connection) loadpy(ctx context.Context, oid zodb.Oid) (pyclass pickle.Class, pystate interface{}, serial zodb.Tid, _ error) { 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}) buf, serial, err := conn.stor.Load(ctx, zodb.Xid{Oid: oid, At: conn.at})
...@@ -281,13 +337,13 @@ func (conn *Connection) loadpy(ctx context.Context, oid zodb.Oid) (pyclass pickl ...@@ -281,13 +337,13 @@ func (conn *Connection) loadpy(ctx context.Context, oid zodb.Oid) (pyclass pickl
} }
// path(class) -> new(pyobj) // path(class) -> new(pyobj)
var classTab = map[string]func(*PyObject)interface{} var classTab = make(map[string]func(*PyObject)interface{})
// registerClass registers python class to be transformed to Go instance // registerClass registers python class to be transformed to Go instance
// created via classNew. // created via classNew.
// //
// must be called from global init(). // must be called from global init().
func registerClass(pyClassPath string, classNew func(*PyObject)interface{}) { func registerClass(classPath string, classNew func(*PyObject)interface{}) {
classTab[classPath] = classNew classTab[classPath] = classNew
} }
......
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