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
Show 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) {
...
@@ -126,6 +126,11 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
return
b
.
values
[
i
],
true
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:
// 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) {
...
@@ -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].
// In the above, key[i] means self->data[i].key, and similarly for child[i].
func
(
t
*
ZBTree
)
PDeactivate
()
{
// DropState implements Stateful.
// XXX check if activated?
func
(
t
*
ZBTree
)
DropState
()
{
t
.
firstbucket
=
nil
t
.
firstbucket
=
nil
t
.
data
=
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"
)
panic
(
"TODO"
)
}
}
// XXX ZBucket.MinKey ?
// XXX ZBucket.MaxKey ?
// from https://github.com/zopefoundation/BTrees/blob/4.5.0-1-gc8bf24e/BTrees/BucketTemplate.c#L1195:
// 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.
// 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 {
...
@@ -182,41 +183,16 @@ func (t *ZBTree) PActivate(ctx context.Context) error {
// <self->next iff non-NULL>
// <self->next iff non-NULL>
// )
// )
// DropState implements Stateful to discard bucket state.
func
(
b
*
ZBucket
)
DropState
()
{
// PDeactivate implements Object.
func
(
b
*
ZBucket
)
PDeactivate
()
{
// XXX check if activated
// b.pyObject.PDeactivate() ...
b
.
next
=
nil
b
.
next
=
nil
b
.
keys
=
nil
b
.
keys
=
nil
b
.
values
=
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
{
// PySetState implements PyStateful to set bucket data from pystate.
t
,
ok
:=
b
.
pyObject
.
pystate
.
(
pickle
.
Tuple
)
func
(
b
*
ZBucket
)
PySetState
(
pystate
interface
{})
error
{
t
,
ok
:=
pystate
.
(
pickle
.
Tuple
)
if
!
ok
||
!
(
1
<=
len
(
t
)
&&
len
(
t
)
<=
2
)
{
if
!
ok
||
!
(
1
<=
len
(
t
)
&&
len
(
t
)
<=
2
)
{
// XXX complain
// XXX complain
}
}
...
@@ -256,7 +232,7 @@ func (b *ZBucket) decode() error {
...
@@ -256,7 +232,7 @@ func (b *ZBucket) decode() error {
}
}
// ----
--------------------------------
----
// ----
register classes to ZODB
----
func
bucketNew
(
pyobj
*
pyObject
)
PyObject
{
func
bucketNew
(
pyobj
*
pyObject
)
PyObject
{
return
&
ZBucket
{
pyObject
:
pyobj
}
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) (
...
@@ -468,7 +468,7 @@ func (bf *BigFile) Read(_ nodefs.File, dest []byte, off int64, _ fuse.Context) (
// TODO set it to Connection.CacheControl
// TODO set it to Connection.CacheControl
type
zodbCacheControl
struct
{}
type
zodbCacheControl
struct
{}
func
(
cc
*
zodbCacheControl
)
WantEvict
(
obj
Object
)
{
func
(
cc
*
zodbCacheControl
)
WantEvict
(
obj
Object
)
bool
{
switch
obj
.
(
type
)
{
switch
obj
.
(
type
)
{
default
:
default
:
return
true
return
true
...
...
wcfs/zblk.go
View file @
a65f9492
...
@@ -94,19 +94,16 @@ func (conn *zpyconn) loadZBigFile(ctx context.Context, oid zodb.Oid) (*ZBigFile,
...
@@ -94,19 +94,16 @@ func (conn *zpyconn) loadZBigFile(ctx context.Context, oid zodb.Oid) (*ZBigFile,
*/
*/
func
(
bf
*
ZBigFile
)
PDeactivate
()
{
// DropState implements Stateful.
if
bf
.
blktab
==
nil
{
func
(
bf
*
ZBigFile
)
DropState
()
{
return
}
bf
.
blksize
=
-
1
bf
.
blksize
=
-
1
bf
.
blktab
=
nil
bf
.
blktab
=
nil
bf
.
pyObject
.
PDeactivate
()
}
}
func
(
bf
*
ZBigFile
)
PySetState
(
pystate
interface
{})
(
err
error
)
{
panic
(
"TODO"
)
/* XXX reenable (pickletools)
/* XXX reenable (pickletools)
func (bf *ZBigFile) PActivate(ctx context.Context) (err error) {
if bf.blktab != nil {
if bf.blktab != nil {
return nil
return nil
}
}
...
@@ -137,8 +134,8 @@ func (bf *ZBigFile) PActivate(ctx context.Context) (err error) {
...
@@ -137,8 +134,8 @@ func (bf *ZBigFile) PActivate(ctx context.Context) (err error) {
bf.blksize = blksize
bf.blksize = blksize
bf.blktab = blktab
bf.blktab = blktab
return nil
return nil
}
*/
*/
}
// XXX -> newGhost
// XXX -> newGhost
...
...
wcfs/zodb.go
View file @
a65f9492
...
@@ -48,7 +48,7 @@ type Object interface {
...
@@ -48,7 +48,7 @@ type Object interface {
//
//
// Object data must be accessed only after corresponding PActivate
// Object data must be accessed only after corresponding PActivate
// call, which marks that object's data as being in use.
// 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.
// PDeactivate indicates that corresponding PActivate caller finished access to object's data.
//
//
...
@@ -63,7 +63,7 @@ type Object interface {
...
@@ -63,7 +63,7 @@ type Object interface {
//
//
// Besides exotic cases, the caller thus must not use object's data
// Besides exotic cases, the caller thus must not use object's data
// after PDeactivate call.
// after PDeactivate call.
PDeactivate
()
// XXX + -> nuse ?
PDeactivate
()
// PInvalidate requests in-RAM object data to be discarded.
// PInvalidate requests in-RAM object data to be discarded.
//
//
...
@@ -86,16 +86,36 @@ type Object interface {
...
@@ -86,16 +86,36 @@ type Object interface {
PInvalidate
()
PInvalidate
()
}
}
// XXX
type
Stateful
interface
{
// XXX
DropState
()
}
// PyObject is the interface that every in-RAM object representing Python ZODB object implements.
// PyObject is the interface that every in-RAM object representing Python ZODB object implements.
type
PyObject
interface
{
type
PyObject
interface
{
Object
Object
PyClass
()
pickle
.
Class
// python class of this 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
{
type
object
struct
{
jar
*
Connection
jar
*
Connection
oid
zodb
.
Oid
oid
zodb
.
Oid
...
@@ -108,18 +128,19 @@ func (obj *object) PJar() *Connection { return obj.jar }
...
@@ -108,18 +128,19 @@ func (obj *object) PJar() *Connection { return obj.jar }
func
(
obj
*
object
)
POid
()
zodb
.
Oid
{
return
obj
.
oid
}
func
(
obj
*
object
)
POid
()
zodb
.
Oid
{
return
obj
.
oid
}
func
(
obj
*
object
)
PSerial
()
zodb
.
Tid
{
return
obj
.
serial
}
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
{
type
pyObject
struct
{
object
object
pyclass
pickle
.
Class
pyclass
pickle
.
Class
pystate
interface
{}
// pystate interface{}
instance
PyStateful
loaderr
error
// if there was error at state loading
loaderr
error
// if there was error at state loading
ready
chan
struct
{}
// activation complete
ready
chan
struct
{}
// activation complete
}
}
func
(
pyobj
*
pyObject
)
PyClass
()
pickle
.
Class
{
return
pyobj
.
pyclass
}
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.
// Connection represents a view of ZODB database.
...
@@ -338,7 +359,7 @@ func (conn *Connection) newGhost(pyclass pickle.Class, oid zodb.Oid) PyObject {
...
@@ -338,7 +359,7 @@ func (conn *Connection) newGhost(pyclass pickle.Class, oid zodb.Oid) PyObject {
pyobj
:=
&
pyObject
{
pyobj
:=
&
pyObject
{
object
:
object
{
jar
:
conn
,
oid
:
oid
,
serial
:
0
},
object
:
object
{
jar
:
conn
,
oid
:
oid
,
serial
:
0
},
pyclass
:
pyclass
,
pyclass
:
pyclass
,
pystat
e
:
nil
,
//instanc
e: nil,
}
}
// switch on pyclass and transform e.g. "zodb.BTree.Bucket" -> *ZBucket
// 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 {
...
@@ -347,7 +368,9 @@ func (conn *Connection) newGhost(pyclass pickle.Class, oid zodb.Oid) PyObject {
return
pyobj
// XXX or return error here?
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() {
...
@@ -368,14 +391,18 @@ func (obj *object) PDeactivate() {
// object's pactivate & friends that only manage base activation state, without actually loading data.
// 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
)
nuse
:=
atomic
.
AddInt32
(
&
obj
.
refcnt
,
+
1
)
if
nuse
==
1
{
if
nuse
==
1
{
// we become responsible for loading object's data.
// 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
)
{
func
(
obj
*
object
)
pdeactivate
()
(
drop
bool
)
{
nuse
:=
atomic
.
AddInt32
(
&
obj
.
refcnt
,
-
1
)
nuse
:=
atomic
.
AddInt32
(
&
obj
.
refcnt
,
-
1
)
if
nuse
<
0
{
if
nuse
<
0
{
...
@@ -389,14 +416,16 @@ func (obj *object) pdeactivate() (drop bool) {
...
@@ -389,14 +416,16 @@ func (obj *object) pdeactivate() (drop bool) {
// TODO state=modified -> don't drop.
// TODO state=modified -> don't drop.
drop
=
true
drop
=
true
// XXX -> pyObject?
if
drop
{
if
drop
{
if
cc
:=
obj
.
jar
.
cacheControl
;
cc
!=
nil
{
if
cc
:=
obj
.
jar
.
cacheControl
;
cc
!=
nil
{
drop
=
cc
.
WantEvict
(
obj
)
drop
=
cc
.
WantEvict
(
obj
.
instance
)
}
}
}
}
if
drop
{
if
drop
{
obj
.
serial
=
0
obj
.
serial
=
0
//obj.insance.DropState()
}
}
return
drop
return
drop
...
@@ -404,16 +433,23 @@ func (obj *object) pdeactivate() (drop bool) {
...
@@ -404,16 +433,23 @@ func (obj *object) pdeactivate() (drop bool) {
// PActivate implements Object.
// 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
()
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
{
if
!
load
{
// someone else is already activated/activating the object.
// someone else is already activated/activating the object.
// wait for its loading to complete and we are done.
// wait for its loading to complete and we are done.
select
{
select
{
case
<-
ctx
.
Done
:
case
<-
ctx
.
Done
()
:
return
false
,
ctx
.
Err
()
// XXX err ctx
return
ctx
.
Err
()
// XXX err ctx
case
<-
pyobj
.
ready
:
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) {
...
@@ -427,10 +463,19 @@ func (pyobj *pyObject) PActivate(ctx context.Context) (bool, error) {
}
}
pyobj
.
serial
=
serial
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
pyobj
.
loaderr
=
err
close
(
pyobj
.
ready
)
close
(
pyobj
.
ready
)
return
true
,
err
// XXX err ctx
return
err
// XXX err ctx
}
}
...
@@ -443,12 +488,16 @@ func (pyobj *pyObject) PDeactivate() {
...
@@ -443,12 +488,16 @@ func (pyobj *pyObject) PDeactivate() {
// we have to drop pyobject state
// we have to drop pyobject state
// XXX locking?
// XXX locking?
pyobj
.
pystate
=
nil
// pyobj.pystate = nil
pyobj
.
instance
.
DropState
()
pyobj
.
loaderr
=
nil
pyobj
.
loaderr
=
nil
pyobj
.
ready
=
make
(
chan
struct
{})
pyobj
.
ready
=
make
(
chan
struct
{})
return
drop
}
}
// XXX pyobj.PInvalidate() = deactivate without checking if state != modified
// 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