Commit a19787b9 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 3ec95a81
......@@ -244,7 +244,7 @@ func bucketNew(pyobj *PyObject) interface{} {
}
func btreeNew(pyobj *PyObject) interface{} {
return &ZBtree{pyobj: pyobj}
return &ZBTree{pyobj: pyobj}
}
func init() {
......
......@@ -16,6 +16,7 @@ package main
import (
"context"
"sync"
"lab.nexedi.com/kirr/neo/go/zodb"
......@@ -97,9 +98,11 @@ type Connection struct {
// 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
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,
// that another goroutine is already in progress of loading it.
type loadInProgress struct {
......@@ -109,6 +112,7 @@ type loadInProgress struct {
pyobj interface{} // XXX -> PyObject iface
err error
}
*/
// Get returns in-RAM object corresponding to specified ZODB object according to current database view.
//
......@@ -117,9 +121,39 @@ type loadInProgress 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) (*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)
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
objentry := conn.objtab[oid]
......@@ -172,19 +206,38 @@ func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (*PyObject, error
} else {
conn.objtab[oid] = NewWeakRef(pyobj)
}
*/
}
// 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.
// 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
// 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.
func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb.Oid) (*PyObject, error) {
// 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) interface{}/*PyObject*/ {
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]
// someone else is already loading the object.
......@@ -236,7 +289,8 @@ func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb.
} else {
conn.objtab[oid] = NewWeakRef(pyobj)
}
}
*/
/*
// XXX -> loadpy
......@@ -257,12 +311,14 @@ func (conn *Connection) get(ctx context.Context, pyclass pickle.Class, oid zodb.
pyclass: pyclass,
pystate: pystate,
}, nil
*/
}
*/
/*
func (conn *Connection) load(ctx context.Context, oid zodb.Oid) (*PyObject, error) {
// XXX
}
*/
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})
......@@ -281,13 +337,13 @@ func (conn *Connection) loadpy(ctx context.Context, oid zodb.Oid) (pyclass pickl
}
// 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
// created via classNew.
//
// 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
}
......
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