Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Kirill Smelkov
neo
Commits
7757f824
Commit
7757f824
authored
Jul 27, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
9c1b50a6
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
50 additions
and
36 deletions
+50
-36
go/zodb/connection.go
go/zodb/connection.go
+27
-13
go/zodb/persistent.go
go/zodb/persistent.go
+20
-3
go/zodb/zodbpy.go
go/zodb/zodbpy.go
+3
-20
No files found.
go/zodb/connection.go
View file @
7757f824
...
...
@@ -110,14 +110,25 @@ type LiveCacheControl interface {
// ---- class <-> type; new ghost ----
var
class2Type
=
make
(
map
[
string
]
reflect
.
Type
)
// {} class -> (type, stateType)
var
type2Class
=
make
(
map
[
reflect
.
Type
]
string
)
// {} type -> (class, stateType)
// zclass describes one ZODB class in relation to Go type.
type
zclass
struct
{
class
string
typ
reflect
.
Type
// application go type corresponding to class
stateType
reflect
.
Type
// *typ and *stateType are convertible; *stateType provides Statufl & co.
}
var
classTab
=
make
(
map
[
string
]
*
zclass
)
// {} class -> zclass
var
typeTab
=
make
(
map
[
reflect
.
Type
]
*
zclass
)
// {} type -> zclass
// zclassOf returns ZODB class of a Go object.
//
// If ZODB class was not registered for obj's type, "" is returned.
func
zclassOf
(
obj
IPersistent
)
string
{
return
type2Class
[
reflect
.
TypeOf
(
obj
)]
zc
,
ok
:=
typeTab
[
reflect
.
TypeOf
(
obj
)]
if
!
ok
{
return
""
}
return
zc
.
class
}
var
rIPersistent
=
reflect
.
TypeOf
((
*
IPersistent
)(
nil
))
.
Elem
()
// typeof(IPersistent)
...
...
@@ -133,7 +144,7 @@ var rPyStateful = reflect.TypeOf((*PyStateful)(nil)).Elem() // typeof(PyStatef
// typ must be convertible to stateType; stateType must implement Ghostable and
// either Stateful or PyStateful(*)
//
//
M
ust be called from global init().
//
RegisterClass m
ust be called from global init().
//
// (*) the rationale for stateType coming separately is that this way for
// application types it is possible not to expose Ghostable and Stateful
...
...
@@ -147,8 +158,8 @@ func RegisterClass(class string, typ, stateType reflect.Type) {
if
class
==
""
{
badf
(
"class must be not empty"
)
}
if
typ
,
already
:=
class2Type
[
class
];
already
{
badf
(
"class already registered for %q"
,
typ
)
if
zc
,
already
:=
classTab
[
class
];
already
{
badf
(
"class already registered for %q"
,
zc
.
typ
)
}
// typ must have IPersistent embedded
...
...
@@ -183,8 +194,9 @@ func RegisterClass(class string, typ, stateType reflect.Type) {
// XXX check if class was already registered
// XXX check class != ""
class2Type
[
class
]
=
typ
type2Class
[
typ
]
=
class
zc
:=
&
zclass
{
class
:
class
,
typ
:
typ
,
stateType
:
stateType
}
classTab
[
class
]
=
zc
typeTab
[
typ
]
=
zc
}
...
...
@@ -192,11 +204,11 @@ func RegisterClass(class string, typ, stateType reflect.Type) {
func
(
conn
*
Connection
)
newGhost
(
class
string
,
oid
Oid
)
IPersistent
{
// switch on class and transform e.g. "zodb.BTree.Bucket" -> btree.Bucket
var
xpobj
reflect
.
Value
// *typ
typ
:=
class2Type
[
class
]
if
typ
==
nil
{
zc
:=
classTab
[
class
]
if
zc
==
nil
{
xpobj
=
reflect
.
ValueOf
(
&
Broken
{
class
:
class
})
}
else
{
xpobj
=
reflect
.
New
(
typ
)
xpobj
=
reflect
.
New
(
zc
.
typ
)
}
base
:=
&
Persistent
{
jar
:
conn
,
oid
:
oid
,
serial
:
0
,
state
:
GHOST
}
...
...
@@ -216,12 +228,14 @@ type Broken struct {
state
*
mem
.
Buf
}
func
(
b
*
Broken
)
DropState
()
{
type
brokenState
Broken
func
(
b
*
brokenState
)
DropState
()
{
b
.
state
.
XRelease
()
b
.
state
=
nil
}
func
(
b
*
Broken
)
SetState
(
state
*
mem
.
Buf
)
error
{
func
(
b
*
brokenState
)
SetState
(
state
*
mem
.
Buf
)
error
{
b
.
state
.
XRelease
()
state
.
Incref
()
b
.
state
=
state
...
...
go/zodb/persistent.go
View file @
7757f824
...
...
@@ -110,7 +110,10 @@ const (
// no STICKY - we pin objects in RAM with PActivate
)
// Persistent is common base implementation for in-RAM representation of database objects.
// Persistent is common base IPersistent implementation for in-RAM
// representation of database objects.
//
// XXX it requires it to embed and provide Ghostable + Stateful.
type
Persistent
struct
{
jar
*
Connection
oid
Oid
...
...
@@ -119,7 +122,10 @@ type Persistent struct {
mu
sync
.
Mutex
state
ObjectState
refcnt
int32
instance
interface
{
IPersistent
;
Ghostable
;
Stateful
}
// Persistent should be the base for the instance
// Persistent should be the base for the instance.
// instance is additionally either Stateful | PyStateful.
instance
interface
{
IPersistent
;
Ghostable
}
// XXX Ghostable also not good here
loading
*
loadState
}
...
...
@@ -203,7 +209,18 @@ func (obj *Persistent) PActivate(ctx context.Context) (err error) {
// try to pass loaded state to object
if
err
==
nil
{
err
=
obj
.
instance
.
SetState
(
state
)
// XXX err ctx
// XXX wrong: obj.instance is not Stateful (not to show it to public API)
switch
inst
:=
obj
.
instance
.
(
type
)
{
case
Stateful
:
err
=
inst
.
SetState
(
state
)
// XXX err ctx
case
PyStateful
:
err
=
pySetState
(
inst
,
state
)
// XXX err ctx
default
:
panic
(
"!stateful instance"
)
}
state
.
Release
()
if
err
==
nil
{
obj
.
state
=
UPTODATE
...
...
go/zodb/zodbpy.go
View file @
7757f824
...
...
@@ -24,14 +24,6 @@ import (
pickle
"github.com/kisielk/og-rek"
)
// PyPersistent is common base implementation for in-RAM representation of ZODB Python objects.
type
PyPersistent
struct
{
Persistent
}
//func (pyobj *PyPersistent) PyClass() pickle.Class { return pyobj.pyclass }
//func (pyobj *PyPersistent) PyState() interface{} { return pyobj.pystate }
// PyStateful is the interface describing in-RAM object whose data state can be
// exchanged as Python data.
type
PyStateful
interface
{
...
...
@@ -44,24 +36,15 @@ type PyStateful interface {
//PyGetState() interface{} TODO
}
// ---- PyPersistent <-> Persistent state exchange ----
// pyinstance returns .instance upcasted to XXXPy.
//
// this should be always safe because we always create pyObjects via
// newGhost which passes IPyPersistent as instance to IPersistent. XXX no longer true
func
(
pyobj
*
PyPersistent
)
pyinstance
()
interface
{
IPersistent
;
Ghostable
;
PyStateful
}
{
return
pyobj
.
instance
.
(
interface
{
IPersistent
;
Ghostable
;
PyStateful
})
}
func
(
pyobj
*
PyPersistent
)
SetState
(
state
*
mem
.
Buf
)
error
{
// pySetState decodes raw state as zodb/py serialized stream, and sets decoded
// state on PyStateful obj.
func
pySetState
(
obj
PyStateful
,
state
*
mem
.
Buf
)
error
{
pyclass
,
pystate
,
err
:=
PyData
(
state
.
Data
)
.
Decode
()
if
err
!=
nil
{
return
err
// XXX err ctx
}
class
:=
pyclassPath
(
pyclass
)
obj
:=
pyobj
.
pyinstance
()
if
objClass
:=
zclassOf
(
obj
);
class
!=
objClass
{
// complain that pyclass changed
...
...
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