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
0dce582b
Commit
0dce582b
authored
Jan 11, 2018
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
a00572f6
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
101 additions
and
87 deletions
+101
-87
go/zodb/cache.go
go/zodb/cache.go
+0
-2
go/zodb/storage/fs1/filestorage.go
go/zodb/storage/fs1/filestorage.go
+16
-16
go/zodb/storage/fs1/filestorage_test.go
go/zodb/storage/fs1/filestorage_test.go
+13
-13
go/zodb/storage/fs1/format.go
go/zodb/storage/fs1/format.go
+47
-48
go/zodb/storage/fs1/fs1tools/dump.go
go/zodb/storage/fs1/fs1tools/dump.go
+4
-4
go/zodb/storage/fs1/fsb/fsbtree.go
go/zodb/storage/fs1/fsb/fsbtree.go
+2
-0
go/zodb/storage/fs1/fsb/fsbtree_util.go
go/zodb/storage/fs1/fsb/fsbtree_util.go
+2
-0
go/zodb/storage/fs1/fsb/gen-fsbtree
go/zodb/storage/fs1/fsb/gen-fsbtree
+15
-1
go/zodb/storage/fs1/util.go
go/zodb/storage/fs1/util.go
+0
-1
go/zodb/zodb.go
go/zodb/zodb.go
+2
-2
No files found.
go/zodb/cache.go
View file @
0dce582b
...
@@ -20,8 +20,6 @@
...
@@ -20,8 +20,6 @@
package
zodb
package
zodb
// cache management
// cache management
//go:generate gotrace gen .
import
(
import
(
"context"
"context"
"fmt"
"fmt"
...
...
go/zodb/storage/fs1/filestorage.go
View file @
0dce582b
...
@@ -22,14 +22,14 @@
...
@@ -22,14 +22,14 @@
// FileStorage is a single file organized as a simple append-only log of
// FileStorage is a single file organized as a simple append-only log of
// transactions with data changes. Every transaction record consists of:
// transactions with data changes. Every transaction record consists of:
//
//
//
- transaction record header represented by TxnHeader,
//
- transaction record header represented by TxnHeader,
//
- several data records corresponding to modified objects,
//
- several data records corresponding to modified objects,
//
- redundant transaction length at the end of transaction record.
//
- redundant transaction length at the end of transaction record.
//
//
// Every data record consists of:
// Every data record consists of:
//
//
//
- data record header represented by DataHeader,
//
- data record header represented by DataHeader,
//
- actual data following the header.
//
- actual data following the header.
//
//
// The "actual data" in addition to raw content, can be a back-pointer
// The "actual data" in addition to raw content, can be a back-pointer
// indicating that the actual content should be retrieved from a past revision.
// indicating that the actual content should be retrieved from a past revision.
...
@@ -72,8 +72,8 @@ import (
...
@@ -72,8 +72,8 @@ import (
"os"
"os"
"sync"
"sync"
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/xcommon/xbufio"
"lab.nexedi.com/kirr/neo/go/xcommon/xbufio"
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/go123/xerr"
...
@@ -84,12 +84,12 @@ import (
...
@@ -84,12 +84,12 @@ import (
//
//
// It is on-disk compatible with FileStorage from ZODB/py.
// It is on-disk compatible with FileStorage from ZODB/py.
type
FileStorage
struct
{
type
FileStorage
struct
{
file
*
os
.
File
file
*
os
.
File
index
*
Index
// oid -> data record position in transaction which last changed oid
index
*
Index
// oid -> data record position in transaction which last changed oid
// transaction headers for min/max transactions committed
// transaction headers for min/max transactions committed
// (both with .Len=0 & .Tid=0 if database is empty)
// (both with .Len=0 & .Tid=0 if database is empty)
txnhMin
TxnHeader
txnhMin
TxnHeader
txnhMax
TxnHeader
txnhMax
TxnHeader
}
}
...
@@ -222,8 +222,8 @@ type zIter struct {
...
@@ -222,8 +222,8 @@ type zIter struct {
// here to avoid allocations )
// here to avoid allocations )
dhLoading
DataHeader
dhLoading
DataHeader
datai
zodb
.
DataInfo
// ptr to this will be returned by .NextData
datai
zodb
.
DataInfo
// ptr to this will be returned by .NextData
dataBuf
*
mem
.
Buf
dataBuf
*
mem
.
Buf
}
}
type
zIterFlags
int
type
zIterFlags
int
...
@@ -332,7 +332,7 @@ func (fs *FileStorage) findTxnRecord(r io.ReaderAt, tid zodb.Tid) (TxnHeader, er
...
@@ -332,7 +332,7 @@ func (fs *FileStorage) findTxnRecord(r io.ReaderAt, tid zodb.Tid) (TxnHeader, er
return
TxnHeader
{},
io
.
EOF
// no such record
return
TxnHeader
{},
io
.
EOF
// no such record
}
}
if
tmin
.
Tid
>=
tid
{
if
tmin
.
Tid
>=
tid
{
return
tmin
,
nil
// tmin satisfies
return
tmin
,
nil
// tmin satisfies
}
}
// now we know tid ∈ (tmin, tmax]
// now we know tid ∈ (tmin, tmax]
...
@@ -395,7 +395,7 @@ func (fs *FileStorage) Iterate(_ context.Context, tidMin, tidMax zodb.Tid) zodb.
...
@@ -395,7 +395,7 @@ func (fs *FileStorage) Iterate(_ context.Context, tidMin, tidMax zodb.Tid) zodb.
txnh
,
err
:=
fs
.
findTxnRecord
(
fsSeq
,
tidMin
)
txnh
,
err
:=
fs
.
findTxnRecord
(
fsSeq
,
tidMin
)
switch
{
switch
{
case
err
==
io
.
EOF
:
case
err
==
io
.
EOF
:
ziter
.
zFlags
|=
zIterEOF
// empty
ziter
.
zFlags
|=
zIterEOF
// empty
return
ziter
return
ziter
case
err
!=
nil
:
case
err
!=
nil
:
...
@@ -414,7 +414,7 @@ func (fs *FileStorage) Iterate(_ context.Context, tidMin, tidMax zodb.Tid) zodb.
...
@@ -414,7 +414,7 @@ func (fs *FileStorage) Iterate(_ context.Context, tidMin, tidMax zodb.Tid) zodb.
iter
.
Datah
.
Pos
=
txnh
.
DataPos
()
// XXX dup wrt Iter.NextTxn
iter
.
Datah
.
Pos
=
txnh
.
DataPos
()
// XXX dup wrt Iter.NextTxn
iter
.
Datah
.
DataLen
=
-
DataHeaderSize
// first iteration will go to first data record
iter
.
Datah
.
DataLen
=
-
DataHeaderSize
// first iteration will go to first data record
iter
.
Dir
=
IterForward
// TODO allow both ways iteration at ZODB level
iter
.
Dir
=
IterForward
// TODO allow both ways iteration at ZODB level
ziter
.
zFlags
|=
zIterPreloaded
ziter
.
zFlags
|=
zIterPreloaded
ziter
.
tidStop
=
tidMax
ziter
.
tidStop
=
tidMax
...
@@ -435,7 +435,7 @@ func open(path string) (_ *FileStorage, err error) {
...
@@ -435,7 +435,7 @@ func open(path string) (_ *FileStorage, err error) {
fs
.
file
=
f
fs
.
file
=
f
defer
func
()
{
defer
func
()
{
if
err
!=
nil
{
if
err
!=
nil
{
f
.
Close
()
// XXX -> lclose
f
.
Close
()
// XXX -> lclose
}
}
}()
}()
...
@@ -500,7 +500,7 @@ func Open(ctx context.Context, path string) (_ *FileStorage, err error) {
...
@@ -500,7 +500,7 @@ func Open(ctx context.Context, path string) (_ *FileStorage, err error) {
}
}
defer
func
()
{
defer
func
()
{
if
err
!=
nil
{
if
err
!=
nil
{
fs
.
file
.
Close
()
// XXX lclose
fs
.
file
.
Close
()
// XXX lclose
}
}
}()
}()
...
...
go/zodb/storage/fs1/filestorage_test.go
View file @
0dce582b
...
@@ -33,16 +33,16 @@ import (
...
@@ -33,16 +33,16 @@ import (
// one database transaction record
// one database transaction record
type
dbEntry
struct
{
type
dbEntry
struct
{
Header
TxnHeader
Header
TxnHeader
Entryv
[]
txnEntry
Entryv
[]
txnEntry
}
}
// one entry inside transaction
// one entry inside transaction
type
txnEntry
struct
{
type
txnEntry
struct
{
Header
DataHeader
Header
DataHeader
rawData
[]
byte
// what is on disk, e.g. it can be backpointer
rawData
[]
byte
// what is on disk, e.g. it can be backpointer
userData
[]
byte
// data client should see on load; `sameAsRaw` means same as RawData
userData
[]
byte
// data client should see on load; `sameAsRaw` means same as RawData
DataTidHint
zodb
.
Tid
// data tid client should see on iter
DataTidHint
zodb
.
Tid
// data tid client should see on iter
}
}
var
sameAsRaw
=
[]
byte
{
0
}
var
sameAsRaw
=
[]
byte
{
0
}
...
@@ -58,8 +58,8 @@ func (txe *txnEntry) Data() []byte {
...
@@ -58,8 +58,8 @@ func (txe *txnEntry) Data() []byte {
// state of an object in the database for some particular revision
// state of an object in the database for some particular revision
type
objState
struct
{
type
objState
struct
{
tid
zodb
.
Tid
tid
zodb
.
Tid
data
[]
byte
// nil if obj was deleted
data
[]
byte
// nil if obj was deleted
}
}
...
@@ -74,7 +74,7 @@ func checkLoad(t *testing.T, fs *FileStorage, xid zodb.Xid, expect objState) {
...
@@ -74,7 +74,7 @@ func checkLoad(t *testing.T, fs *FileStorage, xid zodb.Xid, expect objState) {
URL
:
fs
.
URL
(),
URL
:
fs
.
URL
(),
Op
:
"load"
,
Op
:
"load"
,
Args
:
xid
,
Args
:
xid
,
Err
:
&
zodb
.
NoDataError
{
Oid
:
xid
.
Oid
,
DeletedAt
:
expect
.
tid
},
Err
:
&
zodb
.
NoDataError
{
Oid
:
xid
.
Oid
,
DeletedAt
:
expect
.
tid
},
}
}
if
!
reflect
.
DeepEqual
(
err
,
errOk
)
{
if
!
reflect
.
DeepEqual
(
err
,
errOk
)
{
t
.
Errorf
(
"load %v: returned err unexpected: %v ; want: %v"
,
xid
,
err
,
errOk
)
t
.
Errorf
(
"load %v: returned err unexpected: %v ; want: %v"
,
xid
,
err
,
errOk
)
...
@@ -117,7 +117,7 @@ func xfsopen(t testing.TB, path string) *FileStorage {
...
@@ -117,7 +117,7 @@ func xfsopen(t testing.TB, path string) *FileStorage {
}
}
func
TestLoad
(
t
*
testing
.
T
)
{
func
TestLoad
(
t
*
testing
.
T
)
{
fs
:=
xfsopen
(
t
,
"testdata/1.fs"
)
// TODO open read-only
fs
:=
xfsopen
(
t
,
"testdata/1.fs"
)
// TODO open read-only
defer
exc
.
XRun
(
fs
.
Close
)
defer
exc
.
XRun
(
fs
.
Close
)
// current knowledge of what was "before" for an oid as we scan over
// current knowledge of what was "before" for an oid as we scan over
...
@@ -208,7 +208,7 @@ func testIterate(t *testing.T, fs *FileStorage, tidMin, tidMax zodb.Tid, expectv
...
@@ -208,7 +208,7 @@ func testIterate(t *testing.T, fs *FileStorage, tidMin, tidMax zodb.Tid, expectv
}
}
for
kdata
:=
0
;
;
kdata
++
{
for
kdata
:=
0
;
;
kdata
++
{
dataErrorf
:=
func
(
format
string
,
a
...
interface
{})
{
dataErrorf
:=
func
(
format
string
,
a
...
interface
{})
{
t
.
Helper
()
t
.
Helper
()
dsubj
:=
fmt
.
Sprintf
(
"dstep %v#%v"
,
kdata
,
len
(
dbe
.
Entryv
))
dsubj
:=
fmt
.
Sprintf
(
"dstep %v#%v"
,
kdata
,
len
(
dbe
.
Entryv
))
msg
:=
fmt
.
Sprintf
(
format
,
a
...
)
msg
:=
fmt
.
Sprintf
(
format
,
a
...
)
...
@@ -266,7 +266,7 @@ func testIterate(t *testing.T, fs *FileStorage, tidMin, tidMax zodb.Tid, expectv
...
@@ -266,7 +266,7 @@ func testIterate(t *testing.T, fs *FileStorage, tidMin, tidMax zodb.Tid, expectv
}
}
func
TestIterate
(
t
*
testing
.
T
)
{
func
TestIterate
(
t
*
testing
.
T
)
{
fs
:=
xfsopen
(
t
,
"testdata/1.fs"
)
// TODO open ro
fs
:=
xfsopen
(
t
,
"testdata/1.fs"
)
// TODO open ro
defer
exc
.
XRun
(
fs
.
Close
)
defer
exc
.
XRun
(
fs
.
Close
)
// all []tids in test database
// all []tids in test database
...
@@ -302,7 +302,7 @@ func TestIterate(t *testing.T) {
...
@@ -302,7 +302,7 @@ func TestIterate(t *testing.T) {
}
}
func
BenchmarkIterate
(
b
*
testing
.
B
)
{
func
BenchmarkIterate
(
b
*
testing
.
B
)
{
fs
:=
xfsopen
(
b
,
"testdata/1.fs"
)
// TODO open ro
fs
:=
xfsopen
(
b
,
"testdata/1.fs"
)
// TODO open ro
defer
exc
.
XRun
(
fs
.
Close
)
defer
exc
.
XRun
(
fs
.
Close
)
ctx
:=
context
.
Background
()
ctx
:=
context
.
Background
()
...
...
go/zodb/storage/fs1/format.go
View file @
0dce582b
...
@@ -26,9 +26,9 @@ import (
...
@@ -26,9 +26,9 @@ import (
"io"
"io"
"os"
"os"
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/neo/go/xcommon/xbufio"
"lab.nexedi.com/kirr/neo/go/xcommon/xbufio"
"lab.nexedi.com/kirr/neo/go/xcommon/xio"
"lab.nexedi.com/kirr/neo/go/xcommon/xio"
"lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/go123/mem"
"lab.nexedi.com/kirr/go123/xbytes"
"lab.nexedi.com/kirr/go123/xbytes"
...
@@ -41,9 +41,9 @@ type FileHeader struct {
...
@@ -41,9 +41,9 @@ type FileHeader struct {
// TxnHeader represents header of a transaction record
// TxnHeader represents header of a transaction record
type
TxnHeader
struct
{
type
TxnHeader
struct
{
Pos
int64
// position of transaction start
Pos
int64
// position of transaction start
LenPrev
int64
// whole previous transaction record length (see EOF/error rules in Load)
LenPrev
int64
// whole previous transaction record length (see EOF/error rules in Load)
Len
int64
// whole transaction record length (see EOF/error rules in Load)
Len
int64
// whole transaction record length (see EOF/error rules in Load)
// transaction metadata itself
// transaction metadata itself
zodb
.
TxnInfo
zodb
.
TxnInfo
...
@@ -51,51 +51,51 @@ type TxnHeader struct {
...
@@ -51,51 +51,51 @@ type TxnHeader struct {
// underlying memory for header loading and for user/desc/extension strings
// underlying memory for header loading and for user/desc/extension strings
// invariant: after successful TxnHeader load len(.workMem) = lenUser + lenDesc + lenExt
// invariant: after successful TxnHeader load len(.workMem) = lenUser + lenDesc + lenExt
// as specified by on-disk header.
// as specified by on-disk header.
workMem
[]
byte
workMem
[]
byte
}
}
// DataHeader represents header of a data record
// DataHeader represents header of a data record
type
DataHeader
struct
{
type
DataHeader
struct
{
Pos
int64
// position of data record start
Pos
int64
// position of data record start
Oid
zodb
.
Oid
Oid
zodb
.
Oid
Tid
zodb
.
Tid
Tid
zodb
.
Tid
PrevRevPos
int64
// position of this oid's previous-revision data record
PrevRevPos
int64
// position of this oid's previous-revision data record
TxnPos
int64
// position of transaction record this data record belongs to
TxnPos
int64
// position of transaction record this data record belongs to
//_
uint16
// 2-bytes with zero values. (Was version length.)
//_
uint16
// 2-bytes with zero values. (Was version length.)
DataLen
int64
// length of following data. if 0 -> following = 8 bytes backpointer
DataLen
int64
// length of following data. if 0 -> following = 8 bytes backpointer
// if backpointer == 0 -> oid deleted
// if backpointer == 0 -> oid deleted
// underlying memory for header loading (to avoid allocations)
// underlying memory for header loading (to avoid allocations)
workMem
[
DataHeaderSize
]
byte
workMem
[
DataHeaderSize
]
byte
}
}
const
(
const
(
Magic
=
"FS21"
// every FileStorage file starts with this
Magic
=
"FS21"
// every FileStorage file starts with this
// on-disk sizes
// on-disk sizes
FileHeaderSize
=
4
FileHeaderSize
=
4
TxnHeaderFixSize
=
8
+
8
+
1
+
2
+
2
+
2
// without user/desc/ext strings
TxnHeaderFixSize
=
8
+
8
+
1
+
2
+
2
+
2
// without user/desc/ext strings
txnXHeaderFixSize
=
8
+
TxnHeaderFixSize
// ^^^ with trail LenPrev from previous record
txnXHeaderFixSize
=
8
+
TxnHeaderFixSize
// ^^^ with trail LenPrev from previous record
DataHeaderSize
=
8
+
8
+
8
+
8
+
2
+
8
DataHeaderSize
=
8
+
8
+
8
+
8
+
2
+
8
// txn/data pos that if < vvv are for sure invalid
// txn/data pos that if < vvv are for sure invalid
txnValidFrom
=
FileHeaderSize
txnValidFrom
=
FileHeaderSize
dataValidFrom
=
txnValidFrom
+
TxnHeaderFixSize
dataValidFrom
=
txnValidFrom
+
TxnHeaderFixSize
// invalid length that indicates start of iteration for TxnHeader LoadNext/LoadPrev
// invalid length that indicates start of iteration for TxnHeader LoadNext/LoadPrev
// NOTE load routines check loaded fields to be valid and .Len in particular,
// NOTE load routines check loaded fields to be valid and .Len in particular,
// so it can never come to us from outside to be this.
// so it can never come to us from outside to be this.
lenIterStart
int64
=
-
0x1111111111111112
// = 0xeeeeeeeeeeeeeeee if unsigned
lenIterStart
int64
=
-
0x1111111111111112
// = 0xeeeeeeeeeeeeeeee if unsigned
)
)
// RecordError represents error associated with operation on a record in
// RecordError represents error associated with operation on a record in
// FileStorage data file.
// FileStorage data file.
type
RecordError
struct
{
type
RecordError
struct
{
Path
string
// path of the data file
Path
string
// path of the data file
Record
string
// record kind - "file header", "transaction record", "data record", ...
Record
string
// record kind - "file header", "transaction record", "data record", ...
Pos
int64
// position of record
Pos
int64
// position of record
Subj
string
// subject context for the error - e.g. "read" or "check"
Subj
string
// subject context for the error - e.g. "read" or "check"
Err
error
// actual error
Err
error
// actual error
}
}
func
(
e
*
RecordError
)
Cause
()
error
{
func
(
e
*
RecordError
)
Cause
()
error
{
...
@@ -148,7 +148,7 @@ func (fh *FileHeader) Load(r io.ReaderAt) error {
...
@@ -148,7 +148,7 @@ func (fh *FileHeader) Load(r io.ReaderAt) error {
_
,
err
:=
r
.
ReadAt
(
fh
.
Magic
[
:
],
0
)
_
,
err
:=
r
.
ReadAt
(
fh
.
Magic
[
:
],
0
)
err
=
okEOF
(
err
)
err
=
okEOF
(
err
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
err
}
}
if
string
(
fh
.
Magic
[
:
])
!=
Magic
{
if
string
(
fh
.
Magic
[
:
])
!=
Magic
{
return
fmt
.
Errorf
(
"%s: invalid fs1 magic %q"
,
xio
.
Name
(
r
),
fh
.
Magic
)
return
fmt
.
Errorf
(
"%s: invalid fs1 magic %q"
,
xio
.
Name
(
r
),
fh
.
Magic
)
...
@@ -198,8 +198,8 @@ func (txnh *TxnHeader) CloneFrom(txnh2 *TxnHeader) {
...
@@ -198,8 +198,8 @@ func (txnh *TxnHeader) CloneFrom(txnh2 *TxnHeader) {
// flags for TxnHeader.Load
// flags for TxnHeader.Load
type
TxnLoadFlags
int
type
TxnLoadFlags
int
const
(
const
(
LoadAll
TxnLoadFlags
=
0x00
// load whole transaction header
LoadAll
TxnLoadFlags
=
0x00
// load whole transaction header
LoadNoStrings
=
0x01
// do not load user/desc/ext strings
LoadNoStrings
=
0x01
// do not load user/desc/ext strings
)
)
// Load reads and decodes transaction record header @ pos.
// Load reads and decodes transaction record header @ pos.
...
@@ -228,8 +228,8 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
...
@@ -228,8 +228,8 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
work
:=
txnh
.
workMem
[
:
txnXHeaderFixSize
]
work
:=
txnh
.
workMem
[
:
txnXHeaderFixSize
]
txnh
.
Pos
=
pos
txnh
.
Pos
=
pos
txnh
.
Len
=
-
1
// read error
txnh
.
Len
=
-
1
// read error
txnh
.
LenPrev
=
-
1
// read error
txnh
.
LenPrev
=
-
1
// read error
if
pos
<
txnValidFrom
{
if
pos
<
txnValidFrom
{
bug
(
r
,
txnh
,
"Load() on invalid position"
)
bug
(
r
,
txnh
,
"Load() on invalid position"
)
...
@@ -241,7 +241,7 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
...
@@ -241,7 +241,7 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
if
pos
-
8
>=
txnValidFrom
{
if
pos
-
8
>=
txnValidFrom
{
// read together with previous's txn record redundant length
// read together with previous's txn record redundant length
n
,
err
=
r
.
ReadAt
(
work
,
pos
-
8
)
n
,
err
=
r
.
ReadAt
(
work
,
pos
-
8
)
n
-=
8
// relative to pos
n
-=
8
// relative to pos
if
n
>=
0
{
if
n
>=
0
{
lenPrev
:=
8
+
int64
(
binary
.
BigEndian
.
Uint64
(
work
[
8
-
8
:
]))
lenPrev
:=
8
+
int64
(
binary
.
BigEndian
.
Uint64
(
work
[
8
-
8
:
]))
if
lenPrev
<
TxnHeaderFixSize
{
if
lenPrev
<
TxnHeaderFixSize
{
...
@@ -259,14 +259,14 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
...
@@ -259,14 +259,14 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
}
else
{
}
else
{
// read only current txn without previous record length
// read only current txn without previous record length
n
,
err
=
r
.
ReadAt
(
work
[
8
:
],
pos
)
n
,
err
=
r
.
ReadAt
(
work
[
8
:
],
pos
)
txnh
.
LenPrev
=
0
// EOF backward
txnh
.
LenPrev
=
0
// EOF backward
}
}
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
io
.
EOF
&&
n
==
0
{
if
err
==
io
.
EOF
&&
n
==
0
{
txnh
.
Len
=
0
// EOF forward
txnh
.
Len
=
0
// EOF forward
return
err
// end of stream
return
err
// end of stream
}
}
// EOF after txn header is not good - because at least
// EOF after txn header is not good - because at least
...
@@ -291,8 +291,7 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
...
@@ -291,8 +291,7 @@ func (txnh *TxnHeader) Load(r io.ReaderAt, pos int64, flags TxnLoadFlags) error
return
checkErr
(
r
,
txnh
,
"invalid status: %q"
,
txnh
.
Status
)
return
checkErr
(
r
,
txnh
,
"invalid status: %q"
,
txnh
.
Status
)
}
}
luser
:=
binary
.
BigEndian
.
Uint16
(
work
[
8
+
17
:
])
luser
:=
binary
.
BigEndian
.
Uint16
(
work
[
8
+
17
:
])
ldesc
:=
binary
.
BigEndian
.
Uint16
(
work
[
8
+
19
:
])
ldesc
:=
binary
.
BigEndian
.
Uint16
(
work
[
8
+
19
:
])
lext
:=
binary
.
BigEndian
.
Uint16
(
work
[
8
+
21
:
])
lext
:=
binary
.
BigEndian
.
Uint16
(
work
[
8
+
21
:
])
...
@@ -461,7 +460,7 @@ func (dh *DataHeader) Len() int64 {
...
@@ -461,7 +460,7 @@ func (dh *DataHeader) Len() int64 {
//
//
// No prerequisite requirements are made to previous dh state.
// No prerequisite requirements are made to previous dh state.
func
(
dh
*
DataHeader
)
Load
(
r
io
.
ReaderAt
,
pos
int64
)
error
{
func
(
dh
*
DataHeader
)
Load
(
r
io
.
ReaderAt
,
pos
int64
)
error
{
dh
.
Pos
=
-
1
// ~ error
dh
.
Pos
=
-
1
// ~ error
if
pos
<
dataValidFrom
{
if
pos
<
dataValidFrom
{
bug
(
r
,
dh
,
"Load() on invalid position"
)
bug
(
r
,
dh
,
"Load() on invalid position"
)
...
@@ -473,8 +472,8 @@ func (dh *DataHeader) Load(r io.ReaderAt, pos int64) error {
...
@@ -473,8 +472,8 @@ func (dh *DataHeader) Load(r io.ReaderAt, pos int64) error {
}
}
// XXX also check oid.Valid() ?
// XXX also check oid.Valid() ?
dh
.
Oid
=
zodb
.
Oid
(
binary
.
BigEndian
.
Uint64
(
dh
.
workMem
[
0
:
]))
// XXX -> zodb.Oid.Decode() ?
dh
.
Oid
=
zodb
.
Oid
(
binary
.
BigEndian
.
Uint64
(
dh
.
workMem
[
0
:
]))
dh
.
Tid
=
zodb
.
Tid
(
binary
.
BigEndian
.
Uint64
(
dh
.
workMem
[
8
:
]))
// XXX -> zodb.Tid.Decode() ?
dh
.
Tid
=
zodb
.
Tid
(
binary
.
BigEndian
.
Uint64
(
dh
.
workMem
[
8
:
]))
if
!
dh
.
Tid
.
Valid
()
{
if
!
dh
.
Tid
.
Valid
()
{
return
checkErr
(
r
,
dh
,
"invalid tid: %v"
,
dh
.
Tid
)
return
checkErr
(
r
,
dh
,
"invalid tid: %v"
,
dh
.
Tid
)
}
}
...
@@ -488,7 +487,7 @@ func (dh *DataHeader) Load(r io.ReaderAt, pos int64) error {
...
@@ -488,7 +487,7 @@ func (dh *DataHeader) Load(r io.ReaderAt, pos int64) error {
if
dh
.
TxnPos
+
TxnHeaderFixSize
>
pos
{
if
dh
.
TxnPos
+
TxnHeaderFixSize
>
pos
{
return
checkErr
(
r
,
dh
,
"txn position not decreasing: %v"
,
dh
.
TxnPos
)
return
checkErr
(
r
,
dh
,
"txn position not decreasing: %v"
,
dh
.
TxnPos
)
}
}
if
dh
.
PrevRevPos
!=
0
{
// zero means there is no previous revision
if
dh
.
PrevRevPos
!=
0
{
// zero means there is no previous revision
if
dh
.
PrevRevPos
<
dataValidFrom
{
if
dh
.
PrevRevPos
<
dataValidFrom
{
return
checkErr
(
r
,
dh
,
"invalid prev revision position: %v"
,
dh
.
PrevRevPos
)
return
checkErr
(
r
,
dh
,
"invalid prev revision position: %v"
,
dh
.
PrevRevPos
)
}
}
...
@@ -519,7 +518,7 @@ func (dh *DataHeader) Load(r io.ReaderAt, pos int64) error {
...
@@ -519,7 +518,7 @@ func (dh *DataHeader) Load(r io.ReaderAt, pos int64) error {
// When there is no previous revision: io.EOF is returned.
// When there is no previous revision: io.EOF is returned.
func
(
dh
*
DataHeader
)
LoadPrevRev
(
r
io
.
ReaderAt
)
error
{
func
(
dh
*
DataHeader
)
LoadPrevRev
(
r
io
.
ReaderAt
)
error
{
if
dh
.
PrevRevPos
==
0
{
if
dh
.
PrevRevPos
==
0
{
return
io
.
EOF
// no more previous revisions
return
io
.
EOF
// no more previous revisions
}
}
posCur
:=
dh
.
Pos
posCur
:=
dh
.
Pos
...
@@ -590,7 +589,7 @@ func (dh *DataHeader) LoadBack(r io.ReaderAt) error {
...
@@ -590,7 +589,7 @@ func (dh *DataHeader) LoadBack(r io.ReaderAt) error {
}
}
if
backPos
==
0
{
if
backPos
==
0
{
return
io
.
EOF
// oid was deleted
return
io
.
EOF
// oid was deleted
}
}
posCur
:=
dh
.
Pos
posCur
:=
dh
.
Pos
...
@@ -686,16 +685,16 @@ func (dh *DataHeader) LoadData(r io.ReaderAt) (*mem.Buf, error) {
...
@@ -686,16 +685,16 @@ func (dh *DataHeader) LoadData(r io.ReaderAt) (*mem.Buf, error) {
// Iter is combined 2-level iterator over transaction and data records
// Iter is combined 2-level iterator over transaction and data records
type
Iter
struct
{
type
Iter
struct
{
R
io
.
ReaderAt
R
io
.
ReaderAt
Dir
IterDir
Dir
IterDir
Txnh
TxnHeader
// current transaction record information
Txnh
TxnHeader
// current transaction record information
Datah
DataHeader
// current data record information
Datah
DataHeader
// current data record information
}
}
type
IterDir
int
type
IterDir
int
const
(
const
(
IterForward
IterDir
=
iota
IterForward
IterDir
=
iota
IterBackward
IterBackward
)
)
...
...
go/zodb/storage/fs1/fs1tools/dump.go
View file @
0dce582b
...
@@ -102,7 +102,7 @@ func Dump(w io.Writer, path string, dir fs1.IterDir, d Dumper) (err error) {
...
@@ -102,7 +102,7 @@ func Dump(w io.Writer, path string, dir fs1.IterDir, d Dumper) (err error) {
err
=
it
.
NextTxn
(
fs1
.
LoadAll
)
err
=
it
.
NextTxn
(
fs1
.
LoadAll
)
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
err
=
nil
// XXX -> okEOF(err)
err
=
nil
}
}
return
err
return
err
}
}
...
@@ -110,7 +110,7 @@ func Dump(w io.Writer, path string, dir fs1.IterDir, d Dumper) (err error) {
...
@@ -110,7 +110,7 @@ func Dump(w io.Writer, path string, dir fs1.IterDir, d Dumper) (err error) {
err
=
d
.
DumpTxn
(
buf
,
it
)
err
=
d
.
DumpTxn
(
buf
,
it
)
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
err
=
nil
// XXX -> okEOF(err)
err
=
nil
}
}
return
err
return
err
}
}
...
@@ -163,7 +163,7 @@ func (d *DumperFsDump) DumpTxn(buf *xfmt.Buffer, it *fs1.Iter) error {
...
@@ -163,7 +163,7 @@ func (d *DumperFsDump) DumpTxn(buf *xfmt.Buffer, it *fs1.Iter) error {
err
:=
it
.
NextData
()
err
:=
it
.
NextData
()
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
err
=
nil
// XXX -> okEOF(err)
err
=
nil
}
}
return
err
return
err
}
}
...
@@ -359,7 +359,7 @@ func (d *DumperFsTail) DumpTxn(buf *xfmt.Buffer, it *fs1.Iter) error {
...
@@ -359,7 +359,7 @@ func (d *DumperFsTail) DumpTxn(buf *xfmt.Buffer, it *fs1.Iter) error {
_
,
err
:=
it
.
R
.
ReadAt
(
d
.
data
,
txnh
.
DataPos
())
_
,
err
:=
it
.
R
.
ReadAt
(
d
.
data
,
txnh
.
DataPos
())
if
err
!=
nil
{
if
err
!=
nil
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
err
=
io
.
ErrUnexpectedEOF
// XXX -> noEOF(err)
err
=
io
.
ErrUnexpectedEOF
}
}
// XXX dup wrt fs1.TxnHeader.err
// XXX dup wrt fs1.TxnHeader.err
return
&
fs1
.
RecordError
{
xio
.
Name
(
it
.
R
),
"transaction record"
,
txnh
.
Pos
,
"read data payload"
,
err
}
return
&
fs1
.
RecordError
{
xio
.
Name
(
it
.
R
),
"transaction record"
,
txnh
.
Pos
,
"read data payload"
,
err
}
...
...
go/zodb/storage/fs1/fsb/fsbtree.go
View file @
0dce582b
// Code generated by gen-fsbtree from github.com/cznic/b 93348d0; DO NOT EDIT.
// Code generated by gen-fsbtree from github.com/cznic/b 93348d0; DO NOT EDIT.
// (from patched version available at https://lab.nexedi.com/kirr/b.git)
//
// KEY=zodb.Oid VALUE=int64
// KEY=zodb.Oid VALUE=int64
// ---- 8< ----
// ---- 8< ----
...
...
go/zodb/storage/fs1/fsb/fsbtree_util.go
View file @
0dce582b
// Code generated by gen-fsbtree from github.com/cznic/b 93348d0; DO NOT EDIT.
// Code generated by gen-fsbtree from github.com/cznic/b 93348d0; DO NOT EDIT.
// (from patched version available at https://lab.nexedi.com/kirr/b.git)
//
// ---- 8< ----
// ---- 8< ----
package
fsb
package
fsb
...
...
go/zodb/storage/fs1/fsb/gen-fsbtree
View file @
0dce582b
...
@@ -28,12 +28,24 @@ de=16 # KEY+VALUE
...
@@ -28,12 +28,24 @@ de=16 # KEY+VALUE
o
=
24
#
d
.
c
,
d
.
n
,
d
.
p
o
=
24
#
d
.
c
,
d
.
n
,
d
.
p
kd
=$((
(
4096
-
$
o
-
$
de
)
/
(
2
*
$
de
)
))
kd
=$((
(
4096
-
$
o
-
$
de
)
/
(
2
*
$
de
)
))
#
git_upstream_url
<
repo
>
-
show
current
branch
upstream
URL
git_upstream_url
()
{
repo
=$
1
head
=
"`git -C $repo symbolic-ref --short HEAD`"
#
current
branch
-
e
.
g
.
"t"
remote
=
"`git -C $repo config --get branch.$head.remote`"
#
upstream
name
,
e
.
g
.
"kirr"
url
=
"`git -C $repo config --get remote.$remote.url`"
#
upstream
URL
echo
"$url"
}
b
=
github
.
com
/
cznic
/
b
b
=
github
.
com
/
cznic
/
b
Bdir
=`
go
list
-
f
'{{.Dir}}'
$
b
`
Bdir
=`
go
list
-
f
'{{.Dir}}'
$
b
`
Brev
=`
cd
$
Bdir
&&
git
describe
--
always
`
Brev
=`
git
-
C
$
Bdir
describe
--
always
`
Bweb
=`
git_upstream_url
$
Bdir
`
out
=
fsbtree
.
go
out
=
fsbtree
.
go
echo
"// Code generated by gen-fsbtree from $b $Brev; DO NOT EDIT."
>$
out
echo
"// Code generated by gen-fsbtree from $b $Brev; DO NOT EDIT."
>$
out
echo
"// (from patched version available at $Bweb)"
>>$
out
echo
"//"
>>$
out
echo
"// KEY=$KEY VALUE=$VALUE"
>>$
out
echo
"// KEY=$KEY VALUE=$VALUE"
>>$
out
echo
"// ---- 8< ----"
>>$
out
echo
"// ---- 8< ----"
>>$
out
echo
>>$
out
echo
>>$
out
...
@@ -56,6 +68,8 @@ make -s -C $Bdir generic |sed \
...
@@ -56,6 +68,8 @@ make -s -C $Bdir generic |sed \
#
also
extract
dump
()
routine
#
also
extract
dump
()
routine
out
=
fsbtree_util
.
go
out
=
fsbtree_util
.
go
echo
"// Code generated by gen-fsbtree from $b $Brev; DO NOT EDIT."
>$
out
echo
"// Code generated by gen-fsbtree from $b $Brev; DO NOT EDIT."
>$
out
echo
"// (from patched version available at $Bweb)"
>>$
out
echo
"//"
>>$
out
echo
"// ---- 8< ----"
>>$
out
echo
"// ---- 8< ----"
>>$
out
echo
>>$
out
echo
>>$
out
cat
>>$
out
<<
EOF
cat
>>$
out
<<
EOF
...
...
go/zodb/storage/fs1/util.go
View file @
0dce582b
...
@@ -23,7 +23,6 @@ import (
...
@@ -23,7 +23,6 @@ import (
"io"
"io"
)
)
// XXX -> xio ?
// noEOF returns err, but changes io.EOF -> io.ErrUnexpectedEOF
// noEOF returns err, but changes io.EOF -> io.ErrUnexpectedEOF
func
noEOF
(
err
error
)
error
{
func
noEOF
(
err
error
)
error
{
if
err
==
io
.
EOF
{
if
err
==
io
.
EOF
{
...
...
go/zodb/zodb.go
View file @
0dce582b
...
@@ -239,8 +239,8 @@ type IStorageDriver interface {
...
@@ -239,8 +239,8 @@ type IStorageDriver interface {
// TODO: write mode
// TODO: write mode
// Store(oid Oid, serial Tid, data []byte, txn ITransaction) error
// Store(
ctx,
oid Oid, serial Tid, data []byte, txn ITransaction) error
// StoreKeepCurrent(oid Oid, serial Tid, txn ITransaction)
// StoreKeepCurrent(
ctx,
oid Oid, serial Tid, txn ITransaction)
// TpcBegin(txn)
// TpcBegin(txn)
// TpcVote(txn)
// TpcVote(txn)
...
...
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