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
737414e3
Commit
737414e3
authored
Jul 12, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
c78a68ae
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
49 additions
and
104 deletions
+49
-104
go/zodb/cache.go
go/zodb/cache.go
+6
-6
go/zodb/cache_test.go
go/zodb/cache_test.go
+2
-2
go/zodb/open.go
go/zodb/open.go
+4
-4
go/zodb/pydata.go
go/zodb/pydata.go
+7
-68
go/zodb/pydata_test.go
go/zodb/pydata_test.go
+0
-6
go/zodb/str.go
go/zodb/str.go
+1
-1
go/zodb/zodb.go
go/zodb/zodb.go
+29
-17
No files found.
go/zodb/cache.go
View file @
737414e3
...
...
@@ -56,7 +56,7 @@ type Cache struct {
sizeMax
int
// cache is allowed to occupy not more than this
}
// oidCacheEntry maintains cached revisions for 1 oid
// oidCacheEntry maintains cached revisions for 1 oid
.
type
oidCacheEntry
struct
{
oid
Oid
...
...
@@ -70,7 +70,7 @@ type oidCacheEntry struct {
rcev
[]
*
revCacheEntry
}
// revCacheEntry is information about 1 cached oid revision
// revCacheEntry is information about 1 cached oid revision
.
type
revCacheEntry
struct
{
parent
*
oidCacheEntry
// oidCacheEntry holding us
inLRU
lruHead
// in Cache.lru; protected by Cache.gcMu
...
...
@@ -409,7 +409,7 @@ func (c *Cache) loadRCE(ctx context.Context, rce *revCacheEntry) {
c
.
gcMu
.
Unlock
()
}
// tryMerge tries to merge rce prev into next
// tryMerge tries to merge rce prev into next
.
//
// both prev and next must be already loaded.
// prev and next must come adjacent to each other in parent.rcev with
...
...
@@ -561,7 +561,7 @@ func (oce *oidCacheEntry) release() {
// ----------------------------------------
// isErrNoData returns whether an error is due to "there is no such data in
// database", not e.g. some IO loading error
// database", not e.g. some IO loading error
.
func
isErrNoData
(
err
error
)
bool
{
switch
err
.
(
type
)
{
default
:
...
...
@@ -631,7 +631,7 @@ func (oce *oidCacheEntry) del(rce *revCacheEntry) {
}
// loaded reports whether rce was already loaded
// loaded reports whether rce was already loaded
.
//
// must be called with rce.parent locked.
func
(
rce
*
revCacheEntry
)
loaded
()
bool
{
...
...
@@ -653,7 +653,7 @@ func (h *lruHead) rceFromInLRU() (rce *revCacheEntry) {
return
(
*
revCacheEntry
)(
urce
)
}
// errDB returns error about database being inconsistent
// errDB returns error about database being inconsistent
.
func
errDB
(
oid
Oid
,
format
string
,
argv
...
interface
{})
error
{
// XXX -> separate type?
return
fmt
.
Errorf
(
"cache: database inconsistency: oid: %v: "
+
format
,
...
...
go/zodb/cache_test.go
View file @
737414e3
...
...
@@ -35,13 +35,13 @@ import (
"github.com/kylelemons/godebug/pretty"
)
// tStorage implements read-only storage for cache testing
// tStorage implements read-only storage for cache testing
.
type
tStorage
struct
{
// oid -> [](.serial↑, .data)
dataMap
map
[
Oid
][]
tOidData
}
// data for oid for 1 revision
// data for oid for 1 revision
.
type
tOidData
struct
{
serial
Tid
data
[]
byte
...
...
go/zodb/open.go
View file @
737414e3
...
...
@@ -29,19 +29,19 @@ import (
"lab.nexedi.com/kirr/go123/mem"
)
// OpenOptions describes options for OpenStorage
// OpenOptions describes options for OpenStorage
.
type
OpenOptions
struct
{
ReadOnly
bool
// whether to open storage as read-only
NoCache
bool
// don't use cache for read/write operations
}
// DriverOpener is a function to open a storage driver
// DriverOpener is a function to open a storage driver
.
type
DriverOpener
func
(
ctx
context
.
Context
,
u
*
url
.
URL
,
opt
*
OpenOptions
)
(
IStorageDriver
,
error
)
// {} scheme -> DriverOpener
var
driverRegistry
=
map
[
string
]
DriverOpener
{}
// RegisterDriver registers opener to be used for URLs with scheme
// RegisterDriver registers opener to be used for URLs with scheme
.
func
RegisterDriver
(
scheme
string
,
opener
DriverOpener
)
{
if
_
,
already
:=
driverRegistry
[
scheme
];
already
{
panic
(
fmt
.
Errorf
(
"ZODB URL scheme %q was already registered"
,
scheme
))
...
...
@@ -107,7 +107,7 @@ type storage struct {
}
// loading
always
goes through cache - this way prefetching can work
// loading goes through cache - this way prefetching can work
func
(
s
*
storage
)
Load
(
ctx
context
.
Context
,
xid
Xid
)
(
*
mem
.
Buf
,
Tid
,
error
)
{
// XXX here: offload xid validation from cache and driver ?
...
...
go/zodb/pydata.go
View file @
737414e3
...
...
@@ -22,7 +22,6 @@ package zodb
import
(
"bytes"
"errors"
"fmt"
pickle
"github.com/kisielk/og-rek"
...
...
@@ -36,41 +35,8 @@ import (
// https://github.com/zopefoundation/ZODB/blob/a89485c1/src/ZODB/serialize.py
//
// for format description.
//
// PyData can be decoded into PyObject.
type
PyData
[]
byte
// PyObject represents persistent Python object.
//
// PyObject can be decoded from PyData.
type
PyObject
struct
{
PyClass
pickle
.
Class
// python class of this object
State
interface
{}
// object state. python passes this to pyclass.__new__().__setstate__()
}
// Decode decodes raw ZODB python data into PyObject.
func
(
d
PyData
)
Decode
()
(
*
PyObject
,
error
)
{
p
:=
pickle
.
NewDecoder
(
bytes
.
NewReader
([]
byte
(
d
)))
xklass
,
err
:=
p
.
Decode
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"pydata: decode: class description: %s"
,
err
)
}
klass
,
err
:=
normPyClass
(
xklass
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"pydata: decode: class description: %s"
,
err
)
}
state
,
err
:=
p
.
Decode
()
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"pydata: decode: object state: %s"
,
err
)
}
return
&
PyObject
{
PyClass
:
klass
,
State
:
state
},
nil
}
// ClassName returns fully-qualified python class name used for object type.
//
// The format is "module.class".
...
...
@@ -83,50 +49,23 @@ func (d PyData) ClassName() string {
return
"?.?"
}
klass
,
err
:=
normPyClass
(
xklass
)
if
err
!=
nil
{
return
"?.?"
}
return
klass
.
Module
+
"."
+
klass
.
Name
}
var
errInvalidPyClass
=
errors
.
New
(
"invalid py class description"
)
// normPyClass normalizes py class that has just been decoded from a serialized
// ZODB object or reference.
func
normPyClass
(
xklass
interface
{})
(
pickle
.
Class
,
error
)
{
// class description:
//
// - type(obj), or
// - (xklass, newargs|None) ; xklass = type(obj) | (modname, classname)
if
t
,
ok
:=
xklass
.
(
pickle
.
Tuple
);
ok
{
// t = (xklass, newargs|None)
if
len
(
t
)
!=
2
{
return
pickle
.
Class
{},
errInvalidPyClass
if
len
(
t
)
!=
2
{
// (klass, args)
return
"?.?"
}
// XXX newargs is ignored (zodb/py uses it only for persistent classes)
xklass
=
t
[
0
]
if
t
,
ok
:=
xklass
.
(
pickle
.
Tuple
);
ok
{
//
t = (modname, classname)
//
py: "old style reference"
if
len
(
t
)
!=
2
{
return
pickle
.
Class
{},
errInvalidPyClass
}
modname
,
ok1
:=
t
[
0
]
.
(
string
)
classname
,
ok2
:=
t
[
1
]
.
(
string
)
if
!
(
ok1
&&
ok2
)
{
return
pickle
.
Class
{},
errInvalidPyClass
return
"?.?"
// (modname, classname)
}
return
pickle
.
Class
{
Module
:
modname
,
Name
:
classname
},
nil
return
fmt
.
Sprintf
(
"%s.%s"
,
t
...
)
}
}
if
klass
,
ok
:=
xklass
.
(
pickle
.
Class
);
ok
{
// klass = type(obj)
return
klass
,
nil
return
klass
.
Module
+
"."
+
klass
.
Name
}
return
pickle
.
Class
{},
errInvalidPyClass
return
"?.?"
}
go/zodb/pydata_test.go
View file @
737414e3
...
...
@@ -30,8 +30,6 @@ type _PyDataClassName_TestEntry struct {
className
string
}
// XXX + test with zodbpickle.binary (see 12ee41c4 in ZODB)
func
TestPyClassName
(
t
*
testing
.
T
)
{
for
_
,
tt
:=
range
_PyData_ClassName_Testv
{
className
:=
PyData
(
tt
.
pydata
)
.
ClassName
()
...
...
@@ -41,7 +39,3 @@ func TestPyClassName(t *testing.T) {
}
}
}
func
TestPyDecode
(
t
*
testing
.
T
)
{
// XXX
}
go/zodb/str.go
View file @
737414e3
...
...
@@ -83,7 +83,7 @@ func (xid Xid) XFmtString(b xfmt.Buffer) xfmt.Buffer {
*/
// parseHex64 decodes 16-character-wide hex-encoded string into uint64
// parseHex64 decodes 16-character-wide hex-encoded string into uint64
.
func
parseHex64
(
subj
,
s
string
)
(
uint64
,
error
)
{
// XXX -> xfmt ?
// XXX like scanf("%016x") but scanf implicitly skips spaces without giving control to caller and is slower
...
...
go/zodb/zodb.go
View file @
737414e3
// Copyright (C) 2016-201
7
Nexedi SA and Contributors.
// Copyright (C) 2016-201
8
Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
...
...
@@ -26,27 +26,39 @@
//
// Data model
//
// Tid, Oid, ? Xid.
//
//
// Operation
//
// Load(oid, at), iteration.
// OpenStorage
// A ZODB database is conceptually modeled as transactional log of changes to objects.
// Oid identifies an object and Tid - a transaction. A transaction can change
// several objects and also has metadata, like user and description, associated
// with it. If an object is changed by transaction, it is said that there is
// revision of the object with particular object state committed by that transaction.
// Object revision is the same as tid of transaction that modified the object.
// The combination of object identifier and particular revision (serial)
// uniquely addresses corresponding data record.
//
// Tids of consecutive database transactions are monotonically increasing and
// are connected with time when transaction in question was committed.
// This way, besides identifying a transaction with changes, Tid can also be
// used to specify whole database state constructed by all cumulated
// transaction changes from database beginning up to, and including,
// transaction specified by it. Xid is "extended" oid that specifies particular
// object state: it is (oid, at) pair that is mapped to object's latest
// revision with serial ≤ at.
//
// Python data
// Object state data is generally opaque, but is traditionally based on Python
// pickles in ZODB/py world.
//
// PyData, PyObject, ...
//
// Operations
//
// Storage drivers
// A ZODB database can be opened with OpenStorage. Once opened IStorage
// interface is returned that represents access to the database. Please see
// documentation of IStorage, and other interfaces it embeds, for details.
//
// IStorageDriver, RegisterDriver + wks (FileStorage, ZEO and NEO).
//
// ----
// ----
----
//
// XXX link to zodbtools / `zodb` cmd?
// See also package lab.nexedi.com/kirr/neo/go/zodb/zodbtools and associated
// zodb command that provide tools for managing ZODB databases.
package
zodb
import
(
...
...
@@ -88,7 +100,7 @@ type Oid uint64
//
// At specifies whole database state at which object identified with Oid should
// be looked up. The object revision is taken from latest transaction modifying
// the object with tid
<=
At.
// the object with tid
≤
At.
//
// Note that Xids are not unique - the same object revision can be addressed
// with several xids.
...
...
@@ -306,7 +318,7 @@ type IDataIterator interface {
// ---- misc ----
// Valid returns whether tid is in valid transaction identifiers range
// Valid returns whether tid is in valid transaction identifiers range
.
func
(
tid
Tid
)
Valid
()
bool
{
// NOTE 0 is invalid tid
if
0
<
tid
&&
tid
<=
TidMax
{
...
...
@@ -316,7 +328,7 @@ func (tid Tid) Valid() bool {
}
}
// Valid returns true if transaction status value is well-known and valid
// Valid returns true if transaction status value is well-known and valid
.
func
(
ts
TxnStatus
)
Valid
()
bool
{
switch
ts
{
case
TxnComplete
,
TxnPacked
,
TxnInprogress
:
...
...
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