90 lines
1.4 KiB
Go
90 lines
1.4 KiB
Go
package wal
|
|
|
|
import (
|
|
"time"
|
|
|
|
"git.crumpington.com/public/jldb/lib/errs"
|
|
)
|
|
|
|
type walIterator struct {
|
|
// getSeg should return a segment given its ID, or return nil.
|
|
getSeg func(id int64) (*segment, error)
|
|
seg *segment // Our current segment.
|
|
it Iterator // Our current segment iterator.
|
|
seqNum int64
|
|
err error
|
|
}
|
|
|
|
func newWALIterator(
|
|
getSeg func(id int64) (*segment, error),
|
|
seg *segment,
|
|
fromSeqNum int64,
|
|
) (
|
|
*walIterator,
|
|
error,
|
|
) {
|
|
segIter, err := seg.Iterator(fromSeqNum)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &walIterator{
|
|
getSeg: getSeg,
|
|
seg: seg,
|
|
it: segIter,
|
|
seqNum: fromSeqNum,
|
|
}, nil
|
|
}
|
|
|
|
func (it *walIterator) Next(timeout time.Duration) bool {
|
|
if it.err != nil {
|
|
return false
|
|
}
|
|
|
|
if it.it.Next(timeout) {
|
|
it.seqNum++
|
|
return true
|
|
}
|
|
|
|
it.err = it.it.Error()
|
|
if !errs.EOFArchived.Is(it.err) {
|
|
return false
|
|
}
|
|
|
|
it.it.Close()
|
|
|
|
id := it.seg.ID + 1
|
|
it.seg, it.err = it.getSeg(id)
|
|
|
|
if it.err != nil {
|
|
return false
|
|
}
|
|
|
|
if it.seg == nil {
|
|
it.err = errs.NotFound // Could be not-found, or closed.
|
|
return false
|
|
}
|
|
|
|
it.it, it.err = it.seg.Iterator(it.seqNum)
|
|
if it.err != nil {
|
|
return false
|
|
}
|
|
|
|
return it.Next(timeout)
|
|
}
|
|
|
|
func (it *walIterator) Record() Record {
|
|
return it.it.Record()
|
|
}
|
|
|
|
func (it *walIterator) Error() error {
|
|
return it.err
|
|
}
|
|
|
|
func (it *walIterator) Close() {
|
|
if it.it != nil {
|
|
it.it.Close()
|
|
}
|
|
it.it = nil
|
|
}
|