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
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) {
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
{}
// 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