Commit 2b746af1 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 2c21bf02
...@@ -698,71 +698,117 @@ func (fs *FileStorage) StorageName() string { ...@@ -698,71 +698,117 @@ func (fs *FileStorage) StorageName() string {
} }
type forwardIter struct { // txnIter is iterator over transactions
type txnIter struct {
fs *FileStorage fs *FileStorage
Txnh TxnHeader // current transaction information Txnh TxnHeader // current transaction information
TidMax zodb.Tid // iterate up to tid <= tidMax TidStop zodb.Tid // iterate up to tid <= tidStop | tid >= tidStop depending on .dir
Dir int // iterate forward (> 0) / backward (< 0) / EOF reached (== 0)
} }
func (fi *forwardIter) NextTxn(flags TxnLoadFlags) error { func (fi *txnIter) NextTxn(flags TxnLoadFlags) error {
if fi.Dir == 0 {
return io.EOF
}
// XXX from what we start? how to yield 1st elem? // XXX from what we start? how to yield 1st elem?
err := fi.Txnh.LoadNext(fi.fs.file, flags) var err error
if fi.Dir > 0 {
err = fi.Txnh.LoadNext(fi.fs.file, flags)
} else {
// XXX we are ok to get EOF, provided that LenPrev was read ok?
err = fi.Txnh.LoadPrev(fi.fs.file, flags)
}
if err != nil { if err != nil {
return err return err
} }
// how to make sure last good txnh is preserved? // how to make sure last good txnh is preserved?
if fi.Txnh.Tid > fi.TidMax { if (fi.Dir > 0 && fi.Txnh.Tid > fi.TidStop) ||
(fi.Dir < 0 && fi.Txnh.Tid < fi.TidStop) {
fi.Dir = 0
return io.EOF return io.EOF
} }
return nil return nil
} }
// TODO backwardIter
type FileStorageIterator struct { type Iterator struct {
forwardIter txnIter txnIter
tidMin zodb.Tid // iteration range: [tidMin, tidMax]
} }
func (fsi *FileStorageIterator) NextTxn(txnInfo *zodb.TxnInfo) (dataIter zodb.IStorageRecordIterator, stop bool, err error) { func (fsi *Iterator) NextTxn(txnInfo *zodb.TxnInfo) (dataIter zodb.IStorageRecordIterator, err error) {
err = fsi.forwardIter.NextTxn(LoadAll) err = fsi.txnIter.NextTxn(LoadAll)
if err != nil { if err != nil {
return nil, false, err // XXX recheck return nil, err // XXX recheck
} }
*txnInfo = fsi.forwardIter.Txnh.TxnInfo *txnInfo = fsi.txnIter.Txnh.TxnInfo
// TODO set dataIter // TODO set dataIter
return dataIter, false, nil return nil /*dataIter*/, nil
} }
func (fs *FileStorage) Iterate(tidMin, tidMax zodb.Tid) zodb.IStorageIterator { func (fs *FileStorage) Iterate(tidMin, tidMax zodb.Tid) zodb.IStorageIterator {
if tidMin < fs.tidMin { if tidMin < fs.tidMin {
tidMin = fs.tidMin tidMin = fs.tidMin
} }
if tidMin > fs.tidMax { if tidMax > fs.tidMax {
tidMax = fs.tidMax
}
if tidMin > tidMax {
// -> XXX empty // -> XXX empty
} }
(tidMin - fs.TidMin) vs (fs.TidMax - tidMin) // scan either from file start or end, depending which way it is likely closer, to tidMin
iter := txnIter{fs: fs}
if forward { if (tidMin - fs.tidMin) < (fs.tidMax - tidMin) {
iter = forwardIter{len(Magic), tidMin} // XXX recheck how we enter loop
iter.Dir = +1
iter.Txnh.Pos = txnValidFrom // XXX -> txnStartFrom ?
// XXX .LenPrev = 0
// XXX .Len = ?
iter.TidStop = tidMin
} else { } else {
iter = backwardIter{fs.topPos, tidMin} // XXX recheck how we enter loop
iter.Dir = -1
iter.Txnh.Pos = fs.topPos
// XXX .LenPrev = ?
// XXX .Len = 0
iter.TidStop = tidMin
} }
var err error
for { for {
iter.NextTxn(txnh, ...) err = iter.NextTxn(LoadNoStrings)
// XXX err
if err == io.EOF {
err = nil
break
}
} }
// txnh should have .Tid <= tidMin but next txn's .Tid is > tidMin if err != nil {
posStart := iter.txnPos panic(err) // XXX
if t }
return &FileStorageIterator{-1, tidMin, tidMax} // XXX -1 ok ? fmt.Printf("tidRange: %v..%v -> found %v @%v", tidMin, tidMax, iter.Txnh.Tid, iter.Txnh.Pos)
return nil
// // prepare to start iterating from found transaction
// // XXX loadStrings() on first step ?
// iter.Txnh.Tid
//
// // txnh should have .Tid <= tidMin but next txn's .Tid is > tidMin
// posStart := iter.txnPos
// if t
//
// return &FileStorageIterator{-1, tidMin, tidMax} // XXX -1 ok ?
} }
...@@ -15,6 +15,7 @@ package fs1 ...@@ -15,6 +15,7 @@ package fs1
import ( import (
"bytes" "bytes"
"io"
"reflect" "reflect"
"testing" "testing"
...@@ -131,8 +132,11 @@ func TestLoad(t *testing.T) { ...@@ -131,8 +132,11 @@ func TestLoad(t *testing.T) {
datai := zodb.StorageRecordInformation{} datai := zodb.StorageRecordInformation{}
for k := 0; ; k++ { for k := 0; ; k++ {
dataIter, stop, err := iter.NextTxn(&txni) dataIter, err := iter.NextTxn(&txni)
if stop || err != nil { if err != nil {
if err == io.EOF {
err = nil
}
break break
} }
...@@ -146,11 +150,11 @@ func TestLoad(t *testing.T) { ...@@ -146,11 +150,11 @@ func TestLoad(t *testing.T) {
} }
for { for {
stop, err = dataIter.NextData(&datai) err = dataIter.NextData(&datai)
if err != nil { if err != nil {
panic(err) // XXX if err == io.EOF {
} err = nil
if stop { }
break break
} }
} }
......
...@@ -175,11 +175,13 @@ type IStorageIterator interface { ...@@ -175,11 +175,13 @@ type IStorageIterator interface {
// 1. transaction metadata, and // 1. transaction metadata, and
// 2. iterator over transaction data records. // 2. iterator over transaction data records.
// transaction metadata is put into *txnInfo and stays valid until next call to NextTxn(). // transaction metadata is put into *txnInfo and stays valid until next call to NextTxn().
NextTxn(txnInfo *TxnInfo) (dataIter IStorageRecordIterator, stop bool, err error) // XXX stop -> io.EOF ? // end of iteration is indicated with io.EOF
NextTxn(txnInfo *TxnInfo) (dataIter IStorageRecordIterator, err error)
} }
type IStorageRecordIterator interface { // XXX naming -> IRecordIterator type IStorageRecordIterator interface { // XXX naming -> IRecordIterator
// NextData puts information about next storage data record into *dataInfo. // NextData puts information about next storage data record into *dataInfo.
// data put into *dataInfo stays valid until next call to NextData(). // data put into *dataInfo stays valid until next call to NextData().
NextData(dataInfo *StorageRecordInformation) (stop bool, err error) // XXX stop -> io.EOF ? // end of iteration is indicated with io.EOF
NextData(dataInfo *StorageRecordInformation) error
} }
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