Commit cd86628f authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 8da1816d
...@@ -55,6 +55,8 @@ type TxnHeader struct { ...@@ -55,6 +55,8 @@ type TxnHeader struct {
zodb.TxnInfo zodb.TxnInfo
// 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
// as specfied by on-disk header
workMem []byte workMem []byte
} }
...@@ -162,6 +164,15 @@ func okEOF(err error) error { ...@@ -162,6 +164,15 @@ func okEOF(err error) error {
return err return err
} }
// --- Transaction record ---
// HeaderLen returns whole transaction header length including variable part.
// NOTE: data records start right after transaction header.
func (txnh *TxnHeader) HeaderLen() int64 {
return TxnHeaderFixSize + int64(len(txnh.workMem))
}
// CloneFrom copies txnh2 to txnh making sure underlying slices (.workMem .User // CloneFrom copies txnh2 to txnh making sure underlying slices (.workMem .User
// .Desc ...) are not shared // .Desc ...) are not shared
func (txnh *TxnHeader) CloneFrom(txnh2 *TxnHeader) { func (txnh *TxnHeader) CloneFrom(txnh2 *TxnHeader) {
...@@ -177,6 +188,7 @@ func (txnh *TxnHeader) CloneFrom(txnh2 *TxnHeader) { ...@@ -177,6 +188,7 @@ func (txnh *TxnHeader) CloneFrom(txnh2 *TxnHeader) {
txnh.workMem = workMem txnh.workMem = workMem
copy(workMem, txnh2.workMem) copy(workMem, txnh2.workMem)
// FIXME handle case when strings were already loaded
luser := cap(txnh2.User) luser := cap(txnh2.User)
xdesc := luser + cap(txnh2.Description) xdesc := luser + cap(txnh2.Description)
xext := xdesc + cap(txnh2.Extension) xext := xdesc + cap(txnh2.Extension)
...@@ -207,7 +219,7 @@ const ( ...@@ -207,7 +219,7 @@ const (
// LenPrev >= TxnHeaderFixSize LenPrev was read/checked normally // LenPrev >= TxnHeaderFixSize LenPrev was read/checked normally
func (txnh *TxnHeader) Load(r io.ReaderAt /* *os.File */, pos int64, flags TxnLoadFlags) error { func (txnh *TxnHeader) Load(r io.ReaderAt /* *os.File */, pos int64, flags TxnLoadFlags) error {
if cap(txnh.workMem) < txnXHeaderFixSize { if cap(txnh.workMem) < txnXHeaderFixSize {
txnh.workMem = make([]byte, txnXHeaderFixSize) // XXX or 0, ... ? txnh.workMem = make([]byte, txnXHeaderFixSize)
} }
work := txnh.workMem[:txnXHeaderFixSize] work := txnh.workMem[:txnXHeaderFixSize]
...@@ -379,6 +391,7 @@ func (txnh *TxnHeader) LoadNext(r io.ReaderAt, flags TxnLoadFlags) error { ...@@ -379,6 +391,7 @@ func (txnh *TxnHeader) LoadNext(r io.ReaderAt, flags TxnLoadFlags) error {
return err return err
} }
// --- Data record ---
// Len returns whole data record length // Len returns whole data record length
func (dh *DataHeader) Len() int64 { func (dh *DataHeader) Len() int64 {
...@@ -752,7 +765,16 @@ func (fs *FileStorage) StorageName() string { ...@@ -752,7 +765,16 @@ func (fs *FileStorage) StorageName() string {
} }
// txnIter is iterator over transactions // iteration
type iterFlags int
const (
iterDir iterFlags = 1 << iota // iterate forward (1) or backward (0)
iterEOF // EOF reached
iterPreloaded // data for this iteration was already preloaded
)
// txnIter is iterator over transaction records
type txnIter struct { type txnIter struct {
fs *FileStorage fs *FileStorage
...@@ -762,12 +784,23 @@ type txnIter struct { ...@@ -762,12 +784,23 @@ type txnIter struct {
Flags iterFlags // iterate forward (> 0) / backward (< 0) / EOF reached (== 0) Flags iterFlags // iterate forward (> 0) / backward (< 0) / EOF reached (== 0)
} }
type iterFlags int // dataIter is iterator over data records inside one transaction
const ( type dataIter struct {
iterDir iterFlags = 1 << iota // iterate forward (1) or backward (0) fs *FileStorage
iterEOF // EOF reached
iterPreloaded // data for this iteration was alrady preloaded Txnh *TxnHeader // header of transaction we are iterating inside
) Datah DataHeader
sri zodb.StorageRecordInformation // ptr to this will be returned by NextData
dataBuf []byte
}
// iterator is transaction/data-records iterator as specified by zodb.IStorage
type iterator struct {
txnIter txnIter
dataIter dataIter
}
func (ti *txnIter) NextTxn(flags TxnLoadFlags) error { func (ti *txnIter) NextTxn(flags TxnLoadFlags) error {
switch { switch {
...@@ -807,17 +840,6 @@ func (ti *txnIter) NextTxn(flags TxnLoadFlags) error { ...@@ -807,17 +840,6 @@ func (ti *txnIter) NextTxn(flags TxnLoadFlags) error {
return nil return nil
} }
// dataIter is iterator over data records inside one transaction
type dataIter struct {
fs *FileStorage
Txnh *TxnHeader // header of transaction we are iterating inside
Datah DataHeader
sri zodb.StorageRecordInformation // ptr to this will be returned by NextData
dataBuf []byte
}
func (di *dataIter) NextData() (*zodb.StorageRecordInformation, error) { func (di *dataIter) NextData() (*zodb.StorageRecordInformation, error) {
err := di.Datah.LoadNext(di.fs.file, di.Txnh) err := di.Datah.LoadNext(di.fs.file, di.Txnh)
if err != nil { if err != nil {
...@@ -844,22 +866,15 @@ func (di *dataIter) NextData() (*zodb.StorageRecordInformation, error) { ...@@ -844,22 +866,15 @@ func (di *dataIter) NextData() (*zodb.StorageRecordInformation, error) {
} }
// Iterator is transaction/data-records iterator as specified by zodb.IStorage func (fsi *iterator) NextTxn() (*zodb.TxnInfo, zodb.IStorageRecordIterator, error) {
type Iterator struct {
txnIter txnIter
dataIter dataIter
}
func (fsi *Iterator) NextTxn() (*zodb.TxnInfo, zodb.IStorageRecordIterator, error) {
err := fsi.txnIter.NextTxn(LoadAll) err := fsi.txnIter.NextTxn(LoadAll)
if err != nil { if err != nil {
return nil, nil, err // XXX recheck return nil, nil, err // XXX recheck
} }
// TODO set dataIter // set .dataIter to iterate over .txnIter.Txnh
fsi.dataIter.Datah.Pos = fsi.txnIter.Txnh.Pos + fsi.txnIter.Txnh.HeaderLen()
// fsi.dataIter.Datah.DataLen = -DataHeaderSize // first iteration will go to first data record
// XXX NOTE(self): iteration starts with {Pos: txnh.Pos, DataLen: -DataHeaderSize}
return &fsi.txnIter.Txnh.TxnInfo, &fsi.dataIter, nil return &fsi.txnIter.Txnh.TxnInfo, &fsi.dataIter, nil
} }
...@@ -875,7 +890,7 @@ func (fs *FileStorage) Iterate(tidMin, tidMax zodb.Tid) zodb.IStorageIterator { ...@@ -875,7 +890,7 @@ func (fs *FileStorage) Iterate(tidMin, tidMax zodb.Tid) zodb.IStorageIterator {
} }
// XXX naming // XXX naming
Iter := Iterator{} Iter := iterator{}
Iter.txnIter.fs = fs Iter.txnIter.fs = fs
Iter.dataIter.fs = fs Iter.dataIter.fs = fs
Iter.dataIter.Txnh = &Iter.txnIter.Txnh Iter.dataIter.Txnh = &Iter.txnIter.Txnh
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment