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
6e858c16
Commit
6e858c16
authored
Jul 13, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
6c9c45ec
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
262 additions
and
16 deletions
+262
-16
wcfs/btree.go
wcfs/btree.go
+63
-4
wcfs/zblk.go
wcfs/zblk.go
+69
-12
wcfs/zodb.go
wcfs/zodb.go
+130
-0
No files found.
wcfs/btree.go
View file @
6e858c16
...
@@ -12,10 +12,11 @@
...
@@ -12,10 +12,11 @@
// FOR A PARTICULAR PURPOSE
// FOR A PARTICULAR PURPOSE
package
main
package
main
// ZODB BTree handling
// ZODB BTree handling
XXX -> zodb
import
(
import
(
"context"
"context"
"sort"
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/zodb"
)
)
...
@@ -98,7 +99,8 @@ func (t *ZBTree) Get(ctx context.Context, key KEY) (interface{}, bool, error) {
...
@@ -98,7 +99,8 @@ func (t *ZBTree) Get(ctx context.Context, key KEY) (interface{}, bool, error) {
case
*
ZBucket
:
case
*
ZBucket
:
child
.
PActivate
(
ctx
)
// XXX err
child
.
PActivate
(
ctx
)
// XXX err
return
child
.
Get
(
key
),
nil
v
,
ok
:=
child
.
get
(
key
)
return
v
,
ok
,
nil
}
}
}
}
}
}
...
@@ -111,7 +113,7 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
...
@@ -111,7 +113,7 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
// search i: K(i-1) < k ≤ K(i) ; K(-1) = -∞, K(len) = +∞
// search i: K(i-1) < k ≤ K(i) ; K(-1) = -∞, K(len) = +∞
i
:=
sort
.
Search
(
len
(
b
.
keys
),
func
(
i
int
)
bool
{
i
:=
sort
.
Search
(
len
(
b
.
keys
),
func
(
i
int
)
bool
{
return
key
<=
t
.
data
[
i
]
.
key
return
key
<=
b
.
keys
[
i
]
})
})
if
i
==
len
(
b
.
keys
)
||
b
.
keys
[
i
]
!=
key
{
if
i
==
len
(
b
.
keys
)
||
b
.
keys
[
i
]
!=
key
{
...
@@ -147,8 +149,14 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
...
@@ -147,8 +149,14 @@ 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
()
{
// XXX check if activated?
t
.
firstbucket
=
nil
t
.
data
=
nil
t
.
pyobj
.
PDeactivate
()
}
// XXX ZBTree.Get(key)
// XXX ZBucket.MinKey ?
// XXX ZBucket.MinKey ?
// XXX ZBucket.MaxKey ?
// XXX ZBucket.MaxKey ?
...
@@ -166,3 +174,54 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
...
@@ -166,3 +174,54 @@ func (b *ZBucket) get(key KEY) (interface{}, bool) {
// keys[len-1], values[len-1]),
// keys[len-1], values[len-1]),
// <self->next iff non-NULL>
// <self->next iff non-NULL>
// )
// )
func
(
b
*
ZBucket
)
PDeactivate
()
{
// XXX check if activated
b
.
next
=
nil
b
.
keys
=
nil
b
.
values
=
nil
b
.
pyobj
.
PDeactivate
()
}
func
(
b
*
ZBucket
)
PActivate
(
ctx
context
.
Context
)
error
{
// XXX check if already activated
err
:=
b
.
pyobj
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
err
}
t
,
ok
:=
b
.
pyobj
.
pystate
.
(
pickle
.
Tuple
)
if
!
ok
||
!
(
1
<=
len
(
q
)
&&
len
(
q
)
<=
2
)
{
// XXX complain
}
// .next present
if
len
(
t
)
==
2
{
next
,
ok
:=
t
[
1
]
.
(
*
ZBucket
)
// XXX if !ok
b
.
next
=
next
}
// main part
t
,
ok
=
t
[
0
]
.
(
picklet
.
Tuple
)
// XXX if !ok || (len(t) % 2 != 0)
// reset arrays just in case
n
:=
len
(
t
)
/
2
t
.
keys
=
make
([]
KEY
,
0
,
n
)
t
.
values
=
make
([]
interface
{},
0
,
n
)
for
i
:=
0
;
i
<
n
;
i
++
{
xk
:=
t
[
2
*
i
]
v
:=
t
[
2
*
i
+
1
]
k
,
ok
:=
xk
.
(
int64
)
// XXX use KEY
// XXX if !ok
t
.
keys
=
append
(
t
.
keys
,
k
)
t
.
values
=
append
(
t
.
values
,
v
)
}
}
wcfs/zblk.go
View file @
6e858c16
// Copyright (c) 2001, 2002 Zope Foundation and Contributors.
// All Rights Reserved.
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE
//
// XXX clarify on licensing (ZPL for BTrees)
//
// Copyright (C) 2018 Nexedi SA and Contributors.
// Copyright (C) 2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Kirill Smelkov <kirr@nexedi.com>
//
//
...
@@ -59,6 +47,7 @@ type ZBigFile struct {
...
@@ -59,6 +47,7 @@ type ZBigFile struct {
// module of Wendelin ZODB py objects
// module of Wendelin ZODB py objects
const
zwendelin
=
"wendelin.bigfile.file_zodb"
const
zwendelin
=
"wendelin.bigfile.file_zodb"
/*
// loadZBigFile loads ZBigFile object from specified oid.
// loadZBigFile loads ZBigFile object from specified oid.
func (conn *zpyconn) loadZBigFile(ctx context.Context, oid zodb.Oid) (*ZBigFile, error) {
func (conn *zpyconn) loadZBigFile(ctx context.Context, oid zodb.Oid) (*ZBigFile, error) {
// ZBigFile
// ZBigFile
...
@@ -101,3 +90,71 @@ func (conn *zpyconn) loadZBigFile(ctx context.Context, oid zodb.Oid) (*ZBigFile,
...
@@ -101,3 +90,71 @@ func (conn *zpyconn) loadZBigFile(ctx context.Context, oid zodb.Oid) (*ZBigFile,
// XXX ok
// XXX ok
}
}
*/
func
(
bf
*
ZBigFile
)
PDeactivate
()
{
if
bf
.
blktab
==
nil
{
return
}
bf
.
blksize
=
-
1
bf
.
blktab
=
nil
bf
.
pyobj
.
PDeactivate
()
}
func
(
bf
*
ZBigFile
)
PActivate
(
ctx
context
.
Context
)
(
err
error
)
{
if
bf
.
blktab
!=
nil
{
return
nil
}
err
=
bf
.
pyobj
.
PActivate
(
ctx
)
if
err
!=
nil
{
return
err
}
defer
func
()
{
if
err
!=
nil
{
// decoding went wrong
}
}()
// decode pystate
t
,
ok
:=
pyobj
.
PyState
.
(
pickle
.
Tuple
)
if
!
ok
||
len
(
t
)
!=
2
{
// XXX expected (.blksize, blktab)
}
blksize
,
ok
=
pickletools
.
Xint64
(
t
[
0
])
// XXX if !ok
blktab
,
ok
:=
t
[
1
]
.
(
*
ZBTree
)
// XXX if !ok
bf
.
blksize
=
blksize
bf
.
blktab
=
blktab
return
nil
}
// XXX -> newGhost
/*
tabref, ok := t[1].(pickle.Ref)
// XXX if !ok
t, ok = tabref.Pid.(pickle.Tuple)
if !ok || len(t) != 2 {
// XXX expected (oid, LOBTree)
}
taboid, err = decodeOID(t[0])
// XXX err
lobtreeClass := pickle.Class{Module: "BTrees.LOBTree", Name: "LOBTree"}
if t[1] != lobtreeClass {
// XXX err
}
*/
wcfs/zodb.go
0 → 100644
View file @
6e858c16
// Copyright (c) 2001, 2002 Zope Foundation and Contributors.
// All Rights Reserved.
//
// Copyright (C) 2018 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This software is subject to the provisions of the Zope Public License,
// Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE
package
main
// Bits that should be in ZODB XXX -> zodb
import
(
"context"
"lab.nexedi.com/kirr/neo/go/zodb"
pickle
"github.com/kisielk/og-rek"
)
type
Object
struct
{
jar
*
Connection
oid
zodb
.
Oid
serial
zodb
.
Tid
}
type
PyObject
struct
{
Object
pyclass
pickle
.
Class
// python class of this object
pystate
interface
{}
// object state. python passes this to pyclass.__new__().__setstate__()
}
// Connection represents a view of ZODB database.
//
// XXX Connection, and {Py}Object methods that relate to it, are not safe for
// modifications from multiple goroutines simultaneously.
type
Connection
struct
{
stor
zodb
.
IStorage
// underlying storage
at
zodb
.
Tid
// current view of database
}
// Gets loads and decodes object from the database according to its current view.
//
// FIXME multiple calls to Get(oid) have to return the same instance.
// XXX this is needed if there are several persistent references to the same object.
// however wendelin.core does not do this.
func
(
conn
*
Connection
)
Get
(
ctx
context
.
Context
,
oid
zodb
.
Oid
)
(
*
PyObject
,
error
)
{
buf
,
serial
,
err
:=
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
)
loadpy
(
ctx
context
.
Context
,
oid
zodb
.
Oid
)
(
pyclass
pickle
.
Class
,
pystate
interface
{},
serial
zodb
.
Tid
,
_
error
)
{
buf
,
serial
,
err
:=
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
pyclass
,
pystate
,
serial
,
nil
}
// newGhost creates new ghost object.
func
(
conn
*
Connection
)
newGhost
(
pyclass
pickle
.
Class
,
oid
zodb
.
Oid
)
interface
{}
{
pyobj
:=
PyObject
{
Object
:
Object
{
jar
:
conn
,
oid
:
oid
,
serial
:
zodb
.
InvalidTID
},
pyclass
:
pyclass
,
pystate
:
nil
,
}
// TODO switch on pyclass and transform e.g. "zodb.BTree.Bucket" -> *ZBucket
return
&
pyobj
}
// PDeactivates transforms object to ghost state.
//
// In ghost state object data is dropped and only oid/pyclass information is left in RAM.
//
// XXX if state=modified PDeactivate must be noop.
func
(
pyobj
*
PyObject
)
PDeactivate
()
{
pyobj
.
pystate
=
nil
pyobj
.
serial
=
zodb
.
InvalidTID
}
// PActivate brings object to live state.
//
// If object state is not in RAM - it is loaded from the database.
func
(
pyobj
*
PyObject
)
PActivate
(
ctx
context
.
Context
)
error
{
if
pyobj
.
pystate
!=
nil
{
return
nil
// already loaded
}
pyclass
,
pystate
,
serial
,
err
:=
pyobj
.
jar
.
loadpy
(
ctx
,
pyobj
.
oid
)
if
err
!=
nil
{
return
err
}
if
pyclass
!=
pyobj
.
pyclass
{
// XXX complain pyclass changed
// XXX both ref and object data uses pyclass so it indeed can be different
}
pyobj
.
serial
=
serial
pyobj
.
pystate
=
pystate
}
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