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
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
a65f9492
Commit
a65f9492
authored
Jul 17, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
7b2dca36
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
95 additions
and
73 deletions
+95
-73
wcfs/btree.go
wcfs/btree.go
+15
-39
wcfs/wcfs.go
wcfs/wcfs.go
+1
-1
wcfs/zblk.go
wcfs/zblk.go
+5
-8
wcfs/zodb.go
wcfs/zodb.go
+74
-25
No files found.
wcfs/btree.go
View file @
a65f9492
...
...
@@ -126,6 +126,11 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
return
b
.
values
[
i
],
true
}
// XXX ZBucket.MinKey ?
// XXX ZBucket.MaxKey ?
// ---- serialization ----
// from https://github.com/zopefoundation/BTrees/blob/4.5.0-1-gc8bf24e/BTrees/BTreeTemplate.c#L1087:
//
...
...
@@ -153,22 +158,18 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
//
// In the above, key[i] means self->data[i].key, and similarly for child[i].
func
(
t
*
ZBTree
)
PDeactivate
()
{
// XXX check if activated?
// DropState implements Stateful.
func
(
t
*
ZBTree
)
DropState
()
{
t
.
firstbucket
=
nil
t
.
data
=
nil
t
.
pyObject
.
PDeactivate
()
}
func
(
t
*
ZBTree
)
PActivate
(
ctx
context
.
Context
)
error
{
// PySetState implements PyStateful to set btree data from pystate.
func
(
t
*
ZBTree
)
PySetState
(
pystate
interface
{})
error
{
panic
(
"TODO"
)
}
// XXX ZBucket.MinKey ?
// XXX ZBucket.MaxKey ?
// from https://github.com/zopefoundation/BTrees/blob/4.5.0-1-gc8bf24e/BTrees/BucketTemplate.c#L1195:
//
// For a mapping bucket (self->values is not NULL), a one-tuple or two-tuple.
...
...
@@ -182,41 +183,16 @@ func (t *ZBTree) PActivate(ctx context.Context) error {
// <self->next iff non-NULL>
// )
// PDeactivate implements Object.
func
(
b
*
ZBucket
)
PDeactivate
()
{
// XXX check if activated
// b.pyObject.PDeactivate() ...
// DropState implements Stateful to discard bucket state.
func
(
b
*
ZBucket
)
DropState
()
{
b
.
next
=
nil
b
.
keys
=
nil
b
.
values
=
nil
b
.
pyObject
.
PDeactivate
()
}
// PActivate implements Object.
func
(
b
*
ZBucket
)
PActivate
(
ctx
context
.
Context
)
(
bool
,
error
)
{
activated
,
err
:=
b
.
pyObject
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
err
}
if
!
activated
{
return
false
,
nil
}
// FIXME other users must wait for first decode to complete
err
=
b
.
decode
()
if
err
!=
nil
{
b
.
pyObject
.
PDeactivate
()
return
false
,
err
}
return
true
,
nil
}
func
(
b
*
ZBucket
)
decode
()
error
{
t
,
ok
:=
b
.
pyObject
.
pystate
.
(
pickle
.
Tuple
)
// PySetState implements PyStateful to set bucket data from pystate.
func
(
b
*
ZBucket
)
PySetState
(
pystate
interface
{})
error
{
t
,
ok
:=
pystate
.
(
pickle
.
Tuple
)
if
!
ok
||
!
(
1
<=
len
(
t
)
&&
len
(
t
)
<=
2
)
{
// XXX complain
}
...
...
@@ -256,7 +232,7 @@ func (b *ZBucket) decode() error {
}
// ----
--------------------------------
----
// ----
register classes to ZODB
----
func
bucketNew
(
pyobj
*
pyObject
)
PyObject
{
return
&
ZBucket
{
pyObject
:
pyobj
}
...
...
wcfs/wcfs.go
View file @
a65f9492
...
...
@@ -468,7 +468,7 @@ func (bf *BigFile) Read(_ nodefs.File, dest []byte, off int64, _ fuse.Context) (
// TODO set it to Connection.CacheControl
type
zodbCacheControl
struct
{}
func
(
cc
*
zodbCacheControl
)
WantEvict
(
obj
Object
)
{
func
(
cc
*
zodbCacheControl
)
WantEvict
(
obj
Object
)
bool
{
switch
obj
.
(
type
)
{
default
:
return
true
...
...
wcfs/zblk.go
View file @
a65f9492
...
...
@@ -94,19 +94,16 @@ func (conn *zpyconn) loadZBigFile(ctx context.Context, oid zodb.Oid) (*ZBigFile,
*/
func
(
bf
*
ZBigFile
)
PDeactivate
()
{
if
bf
.
blktab
==
nil
{
return
}
// DropState implements Stateful.
func
(
bf
*
ZBigFile
)
DropState
()
{
bf
.
blksize
=
-
1
bf
.
blktab
=
nil
bf
.
pyObject
.
PDeactivate
()
}
func
(
bf
*
ZBigFile
)
PySetState
(
pystate
interface
{})
(
err
error
)
{
panic
(
"TODO"
)
/* XXX reenable (pickletools)
func (bf *ZBigFile) PActivate(ctx context.Context) (err error) {
if bf.blktab != nil {
return nil
}
...
...
@@ -137,8 +134,8 @@ func (bf *ZBigFile) PActivate(ctx context.Context) (err error) {
bf.blksize = blksize
bf.blktab = blktab
return nil
}
*/
}
// XXX -> newGhost
...
...
wcfs/zodb.go
View file @
a65f9492
...
...
@@ -48,7 +48,7 @@ type Object interface {
//
// Object data must be accessed only after corresponding PActivate
// call, which marks that object's data as being in use.
PActivate
(
ctx
context
.
Context
)
(
activated
bool
,
_
error
)
// XXX ret semantics?
PActivate
(
ctx
context
.
Context
)
error
// PDeactivate indicates that corresponding PActivate caller finished access to object's data.
//
...
...
@@ -63,7 +63,7 @@ type Object interface {
//
// Besides exotic cases, the caller thus must not use object's data
// after PDeactivate call.
PDeactivate
()
// XXX + -> nuse ?
PDeactivate
()
// PInvalidate requests in-RAM object data to be discarded.
//
...
...
@@ -86,16 +86,36 @@ type Object interface {
PInvalidate
()
}
// XXX
type
Stateful
interface
{
// XXX
DropState
()
}
// PyObject is the interface that every in-RAM object representing Python ZODB object implements.
type
PyObject
interface
{
Object
PyClass
()
pickle
.
Class
// python class of this object
PyState
()
interface
{}
// object state. python passes this to pyclass.__new__().__setstate__()
// PyState() interface{} // object state. python passes this to pyclass.__new__().__setstate__()
PyStateful
}
// XXX
type
PyStateful
interface
{
Stateful
// PySetState should set Python state of the in-RAM object.
// Analog of __setstate__() in Python.
PySetState
(
pystate
interface
{})
error
// PyGetState should return Python state of in-RAM object.
// Analog of __getstate__() in Python.
//PyGetState() interface{} XXX
}
// object is common base for in-RAM
representation
of ZODB objects.
// object is common base for in-RAM
implementations
of ZODB objects.
type
object
struct
{
jar
*
Connection
oid
zodb
.
Oid
...
...
@@ -108,18 +128,19 @@ func (obj *object) PJar() *Connection { return obj.jar }
func
(
obj
*
object
)
POid
()
zodb
.
Oid
{
return
obj
.
oid
}
func
(
obj
*
object
)
PSerial
()
zodb
.
Tid
{
return
obj
.
serial
}
// pyObject is common base for in-RAM
representation
of ZODB Python objects.
// pyObject is common base for in-RAM
implementations
of ZODB Python objects.
type
pyObject
struct
{
object
pyclass
pickle
.
Class
pystate
interface
{}
loaderr
error
// if there was error at state loading
ready
chan
struct
{}
// activation complete
pyclass
pickle
.
Class
// pystate interface{}
instance
PyStateful
loaderr
error
// if there was error at state loading
ready
chan
struct
{}
// activation complete
}
func
(
pyobj
*
pyObject
)
PyClass
()
pickle
.
Class
{
return
pyobj
.
pyclass
}
func
(
pyobj
*
pyObject
)
PyState
()
interface
{}
{
return
pyobj
.
pystate
}
//
func (pyobj *pyObject) PyState() interface{} { return pyobj.pystate }
// Connection represents a view of ZODB database.
...
...
@@ -338,7 +359,7 @@ func (conn *Connection) newGhost(pyclass pickle.Class, oid zodb.Oid) PyObject {
pyobj
:=
&
pyObject
{
object
:
object
{
jar
:
conn
,
oid
:
oid
,
serial
:
0
},
pyclass
:
pyclass
,
pystat
e
:
nil
,
//instanc
e: nil,
}
// switch on pyclass and transform e.g. "zodb.BTree.Bucket" -> *ZBucket
...
...
@@ -347,7 +368,9 @@ func (conn *Connection) newGhost(pyclass pickle.Class, oid zodb.Oid) PyObject {
return
pyobj
// XXX or return error here?
}
return
classNew
(
pyobj
)
obj
:=
classNew
(
pyobj
)
pyobj
.
instance
=
obj
return
obj
}
...
...
@@ -368,14 +391,18 @@ func (obj *object) PDeactivate() {
// object's pactivate & friends that only manage base activation state, without actually loading data.
func
(
obj
*
object
)
pactivate
(
ctx
context
.
Context
)
error
{
// XXX -> incref ?
func
(
obj
*
object
)
pactivate
()
(
load
bool
)
{
nuse
:=
atomic
.
AddInt32
(
&
obj
.
refcnt
,
+
1
)
if
nuse
==
1
{
// we become responsible for loading object's data.
// XXX check state
// XXX also check state (it could be already loaded, but with refcnt=0)
return
true
}
return
false
}
// XXX -> decref ?
func
(
obj
*
object
)
pdeactivate
()
(
drop
bool
)
{
nuse
:=
atomic
.
AddInt32
(
&
obj
.
refcnt
,
-
1
)
if
nuse
<
0
{
...
...
@@ -389,14 +416,16 @@ func (obj *object) pdeactivate() (drop bool) {
// TODO state=modified -> don't drop.
drop
=
true
// XXX -> pyObject?
if
drop
{
if
cc
:=
obj
.
jar
.
cacheControl
;
cc
!=
nil
{
drop
=
cc
.
WantEvict
(
obj
)
drop
=
cc
.
WantEvict
(
obj
.
instance
)
}
}
if
drop
{
obj
.
serial
=
0
//obj.insance.DropState()
}
return
drop
...
...
@@ -404,16 +433,23 @@ func (obj *object) pdeactivate() (drop bool) {
// PActivate implements Object.
func
(
pyobj
*
pyObject
)
PActivate
(
ctx
context
.
Context
)
(
bool
,
error
)
{
func
(
pyobj
*
pyObject
)
PActivate
(
ctx
context
.
Context
)
(
err
error
)
{
load
:=
pyobj
.
object
.
pactivate
()
defer
func
()
{
if
err
!=
nil
{
// no need to check for drop - the state is already
// dropped - we just need to decref here.
pyobj
.
object
.
pdeactivate
()
}
}()
if
!
load
{
// someone else is already activated/activating the object.
// wait for its loading to complete and we are done.
select
{
case
<-
ctx
.
Done
:
return
false
,
ctx
.
Err
()
// XXX err ctx
case
<-
ctx
.
Done
()
:
return
ctx
.
Err
()
// XXX err ctx
case
<-
pyobj
.
ready
:
return
(
pyobj
.
loaderr
==
nil
),
pyobj
.
loaderr
// XXX err ctx?
return
pyobj
.
loaderr
// XXX err ctx?
}
}
...
...
@@ -427,10 +463,19 @@ func (pyobj *pyObject) PActivate(ctx context.Context) (bool, error) {
}
pyobj
.
serial
=
serial
pyobj
.
pystate
=
pystate
// pyobj.pystate = pystate
if
err
==
nil
{
err
=
pyobj
.
instance
.
PySetState
(
pystate
)
// XXX err ctx
}
if
err
!=
nil
{
pyobj
.
instance
.
DropState
()
}
pyobj
.
loaderr
=
err
close
(
pyobj
.
ready
)
return
true
,
err
// XXX err ctx
return
err
// XXX err ctx
}
...
...
@@ -443,12 +488,16 @@ func (pyobj *pyObject) PDeactivate() {
// we have to drop pyobject state
// XXX locking?
pyobj
.
pystate
=
nil
// pyobj.pystate = nil
pyobj
.
instance
.
DropState
()
pyobj
.
loaderr
=
nil
pyobj
.
ready
=
make
(
chan
struct
{})
return
drop
}
// XXX pyobj.PInvalidate() = deactivate without checking if state != modified
// XXX panic if refcnt != 0 (object being used)
func
(
pyobj
*
pyObject
)
PInvalidate
()
{
// XXX panic if refcnt != 0 (object being used)
pyobj
.
instance
.
DropState
()
pyobj
.
loaderr
=
nil
pyobj
.
ready
=
make
(
chan
struct
{})
}
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