Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
f0931de9
Commit
f0931de9
authored
Jul 19, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
0f146bcb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
62 additions
and
82 deletions
+62
-82
wcfs/btree.go
wcfs/btree.go
+2
-2
wcfs/xxx.go
wcfs/xxx.go
+10
-38
wcfs/zblk.go
wcfs/zblk.go
+1
-1
wcfs/zodb.go
wcfs/zodb.go
+49
-41
No files found.
wcfs/btree.go
View file @
f0931de9
...
...
@@ -243,6 +243,6 @@ func btreeNew(pyobj *pyObject) PyObject {
}
func
init
()
{
registerClass
(
"zodb.BTree.LOBucket"
,
bucketNew
)
registerClass
(
"zodb.BTree.LOBtree"
,
btreeNew
)
register
Py
Class
(
"zodb.BTree.LOBucket"
,
bucketNew
)
register
Py
Class
(
"zodb.BTree.LOBtree"
,
btreeNew
)
}
wcfs/xxx.go
View file @
f0931de9
package
main
/*
// 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 {
ready chan struct{} // closed when loading finishes
// result of the load
pyobj interface{} // XXX -> pyObject iface
err error
}
// XXX -> pyObject.SetState
/*
pyclass, pystate, serial, err := pyobj.jar.loadpy(ctx, pyobj.oid)
if err == nil && pyclass != pyobj.pyclass {
// complain pyclass changed
// (both ref and object data uses pyclass so it indeed can be different)
err = &wrongClassError{want: pyobj.pyclass, have: pyclass} // XXX + err ctx
pystate = nil
}
*/
/*
conn.objmu.Lock() // XXX -> rlock
objentry := conn.objtab[oid]
...
...
@@ -122,32 +123,3 @@ type loadInProgress struct {
}
}
*/
/*
// XXX -> loadpy
buf, serial, err := conn.stor.Load(ctx, zodb.Xid{Oid: oid, At: conn.at})
if err != nil {
return nil, err
}
pyclass, pystate, err := zodb.PyData(buf.Data).Decode()
if err != nil {
return nil, err // XXX err ctx
}
buf.Release()
return &pyObject{
object: object{jar: conn,oid: oid, serial: serial},
pyclass: pyclass,
pystate: pystate,
}, nil
}
*/
/*
func (conn *Connection) load(ctx context.Context, oid zodb.Oid) (*pyObject, error) {
// XXX
}
*/
wcfs/zblk.go
View file @
f0931de9
...
...
@@ -165,5 +165,5 @@ func zbigfileNew(pyobj *pyObject) PyObject {
}
func
init
()
{
registerClass
(
zwendelin
+
".ZBigFile"
,
zbigfileNew
)
register
Py
Class
(
zwendelin
+
".ZBigFile"
,
zbigfileNew
)
}
wcfs/zodb.go
View file @
f0931de9
...
...
@@ -20,6 +20,7 @@ import (
"sync"
// "sync/atomic"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/neo/go/zodb"
pickle
"github.com/kisielk/og-rek"
...
...
@@ -115,9 +116,11 @@ type object struct {
oid
zodb
.
Oid
serial
zodb
.
Tid
mu
sync
.
Mutex
state
ObjectState
refcnt
int32
mu
sync
.
Mutex
state
ObjectState
refcnt
int32
instance
Stateful
loading
*
loadState
}
func
(
obj
*
object
)
PJar
()
*
Connection
{
return
obj
.
jar
}
...
...
@@ -129,9 +132,9 @@ type pyObject struct {
object
pyclass
pickle
.
Class
// protected by object.mu
instance
PyStateful
loading
*
loadState
//
// protected by object.mu
//
instance PyStateful
//
loading *loadState
}
func
(
pyobj
*
pyObject
)
PyClass
()
pickle
.
Class
{
return
pyobj
.
pyclass
}
...
...
@@ -149,16 +152,26 @@ type loadState struct {
err
error
}
// XXX
// Stateful is the interface describing in-RAM object whose data stat can be
// exchanged as raw bytes.
type
Stateful
interface
{
// DropState should discard in-RAM object state.
// XXX move out of Stateful?
DropState
()
// SetState should set state of the in-RAM object from raw data.
//
// SetState must incref state buffer, if it needs the buffer to stay dedicated XXX
SetState
(
state
*
mem
.
Buf
)
error
// GetState should return state of the in-RAM object as raw data.
//GetState() *mem.Buf
}
// PyStateful is the interface describing in-RAM object whose data state can be
// exchanged as Python data.
type
PyStateful
interface
{
Stateful
//Stateful XXX no need here?
// PySetState should set state of the in-RAM object from Python data.
// Analog of __setstate__() in Python.
...
...
@@ -260,7 +273,7 @@ type LiveCacheControl interface {
//
// 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
)
{
func
(
conn
*
Connection
)
Get
(
ctx
context
.
Context
,
oid
zodb
.
Oid
)
(
PyObject
,
error
)
{
conn
.
objmu
.
Lock
()
// XXX -> rlock
wobj
:=
conn
.
objtab
[
oid
]
var
xobj
interface
{}
...
...
@@ -271,7 +284,7 @@ func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (interface{} /*Py
// object was already there in objtab.
if
xobj
!=
nil
{
return
xobj
,
nil
return
xobj
.
(
PyObject
)
,
nil
}
// object is not there in objtab - raw load it, get its class -> get(pyclass, oid)
...
...
@@ -280,7 +293,7 @@ func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (interface{} /*Py
return
nil
,
err
// XXX errctx
}
xobj
,
err
=
conn
.
get
(
pyclass
,
oid
)
obj
,
err
:
=
conn
.
get
(
pyclass
,
oid
)
if
err
!=
nil
{
return
nil
,
err
}
...
...
@@ -290,7 +303,7 @@ func (conn *Connection) Get(ctx context.Context, oid zodb.Oid) (interface{} /*Py
//
// TODO -> use (pystate, serial) to activate.
_
,
_
=
pystate
,
serial
return
x
obj
,
nil
return
obj
,
nil
}
...
...
@@ -370,15 +383,15 @@ func (conn *Connection) loadpy(ctx context.Context, oid zodb.Oid) (pyclass pickl
// ---- pyclass -> new ghost ----
// path(class) -> new(pyobj)
var
classTab
=
make
(
map
[
string
]
func
(
*
pyObject
)
PyObject
)
// path(
py
class) -> new(pyobj)
var
classTab
=
make
(
map
[
string
]
func
(
base
*
pyObject
)
PyObject
)
// registerClass registers python class to be transformed to Go instance
// register
Py
Class registers python class to be transformed to Go instance
// created via classNew.
//
// must be called from global init().
func
register
Class
(
classPath
string
,
classNew
func
(
*
pyObject
)
PyObject
)
{
classTab
[
c
lassPath
]
=
classNew
func
register
PyClass
(
pyClassPath
string
,
classNew
func
(
base
*
pyObject
)
PyObject
)
{
classTab
[
pyC
lassPath
]
=
classNew
}
// newGhost creates new ghost object corresponding to pyclass and oid.
...
...
@@ -420,7 +433,9 @@ func (d *dummyPyInstance) PySetState(pystate interface{}) error {
// ----------------------------------------
// object's activate & friends that only manage base activation state, without actually loading data.
// XXX ^^^ still relevant?
/*
// activate increments object reference counter.
//
// it returns whether object data needs to be loaded.
...
...
@@ -430,16 +445,8 @@ func (d *dummyPyInstance) PySetState(pystate interface{}) error {
func (obj *object) activate() (load bool) {
obj.refcnt++
return (obj.refcnt == 1 && obj.state == GHOST)
/*
nuse := atomic.AddInt32(&obj.refcnt, +1)
if nuse == 1 {
// we become responsible for loading object's data.
// XXX also check state (it could be already loaded, but with refcnt=0)
return true
}
return false
*/
}
*/
// deactivate decrements object reference counter.
//
...
...
@@ -490,23 +497,24 @@ func (obj *object) invalidate() {
// PActivate implements Object.
func
(
pyobj
*
pyObject
)
PActivate
(
ctx
context
.
Context
)
(
err
error
)
{
pyobj
.
mu
.
Lock
()
doload
:=
pyobj
.
activate
()
func
(
obj
*
object
)
PActivate
(
ctx
context
.
Context
)
(
err
error
)
{
obj
.
mu
.
Lock
()
ob
.
refcnt
++
doload
:=
(
obj
.
refcnt
==
1
&&
obj
.
state
==
GHOST
)
defer
func
()
{
if
err
!=
nil
{
// no need to check for drop - the state is already
// dropped - we just need to decref here.
//
// XXX locking
py
obj
.
deactivate
()
// XXX -> drop?
obj
.
deactivate
()
// XXX -> drop?
}
}()
if
!
doload
{
// someone else is already activated/activating the object.
// wait for its loading to complete and we are done.
loading
:=
py
obj
.
loading
py
obj
.
mu
.
Unlock
()
loading
:=
obj
.
loading
obj
.
mu
.
Unlock
()
select
{
case
<-
ctx
.
Done
()
:
...
...
@@ -518,18 +526,18 @@ func (pyobj *pyObject) PActivate(ctx context.Context) (err error) {
// we become responsible for loading the object
loading
:=
&
loadState
{
ready
:
make
(
chan
struct
{})}
py
obj
.
loading
=
loading
// XXX assert before it was = nil ?
py
obj
.
mu
.
Unlock
()
obj
.
loading
=
loading
// XXX assert before it was = nil ?
obj
.
mu
.
Unlock
()
// do the loading outside of pyobj lock
pyclass
,
pystate
,
serial
,
err
:=
pyobj
.
jar
.
loadpy
(
ctx
,
pyobj
.
oid
)
if
err
==
nil
&&
pyclass
!=
pyobj
.
pyclass
{
// complain pyclass changed
// (both ref and object data uses pyclass so it indeed can be different)
err
=
&
wrongClassError
{
want
:
pyobj
.
pyclass
,
have
:
pyclass
}
// XXX + err ctx
pystate
=
nil
// do the loading outside of obj lock
buf
,
serial
,
err
:=
obj
.
jar
.
load
(
ctx
,
obj
.
oid
)
if
err
==
nil
{
err
=
obj
.
instance
.
SetState
(
buf
)
// XXX err ctx
buf
.
Release
()
}
// relock the object
pyobj
.
mu
.
Lock
()
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment