mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
internal/era: improve iterator interface
This commit is contained in:
parent
b8fc70e8f4
commit
67defc417c
1 changed files with 41 additions and 7 deletions
|
|
@ -17,6 +17,7 @@
|
|||
package era
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
|
||||
|
|
@ -29,7 +30,8 @@ type Iterator struct {
|
|||
inner *RawIterator
|
||||
}
|
||||
|
||||
// NewIterator returns a new Iterator instance.
|
||||
// NewRawIterator returns a new Iterator instance. Next must be immediately
|
||||
// called on new iterators to load the first item.
|
||||
func NewIterator(e *Era) (*Iterator, error) {
|
||||
inner, err := NewRawIterator(e)
|
||||
if err != nil {
|
||||
|
|
@ -38,7 +40,9 @@ func NewIterator(e *Era) (*Iterator, error) {
|
|||
return &Iterator{inner}, nil
|
||||
}
|
||||
|
||||
// Next moves the iterator to the next block entry.
|
||||
// Next moves the iterator to the next block entry. It returns false when all
|
||||
// items have been read or an error has halted its progress. Block, Receipts,
|
||||
// and BlockAndReceipts should no longer be called after false is returned.
|
||||
func (it *Iterator) Next() bool {
|
||||
return it.inner.Next()
|
||||
}
|
||||
|
|
@ -48,13 +52,17 @@ func (it *Iterator) Number() uint64 {
|
|||
return it.inner.next - 1
|
||||
}
|
||||
|
||||
// Error returns the error status of the iterator.
|
||||
// Error returns the error status of the iterator. It should be called before
|
||||
// reading from any of the iterator's values.
|
||||
func (it *Iterator) Error() error {
|
||||
return it.inner.Error()
|
||||
}
|
||||
|
||||
// Block returns the block for the iterator's current position.
|
||||
func (it *Iterator) Block() (*types.Block, error) {
|
||||
if it.inner.Header == nil || it.inner.Body == nil {
|
||||
return nil, fmt.Errorf("header and body must be non-nil")
|
||||
}
|
||||
var (
|
||||
header types.Header
|
||||
body types.Body
|
||||
|
|
@ -70,6 +78,9 @@ func (it *Iterator) Block() (*types.Block, error) {
|
|||
|
||||
// Receipts returns the receipts for the iterator's current position.
|
||||
func (it *Iterator) Receipts() (types.Receipts, error) {
|
||||
if it.inner.Receipts == nil {
|
||||
return nil, fmt.Errorf("receipts must be non-nil")
|
||||
}
|
||||
var receipts types.Receipts
|
||||
err := rlp.Decode(it.inner.Receipts, &receipts)
|
||||
return receipts, err
|
||||
|
|
@ -111,7 +122,8 @@ type RawIterator struct {
|
|||
TotalDifficulty io.Reader
|
||||
}
|
||||
|
||||
// NewRawIterator returns a new Iterator instance.
|
||||
// NewRawIterator returns a new RawIterator instance. Next must be immediately
|
||||
// called on new iterators to load the first item.
|
||||
func NewRawIterator(e *Era) (*RawIterator, error) {
|
||||
return &RawIterator{
|
||||
e: e,
|
||||
|
|
@ -119,30 +131,43 @@ func NewRawIterator(e *Era) (*RawIterator, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// Next moves the iterator to the next block entry.
|
||||
// Next moves the iterator to the next block entry. It returns false when all
|
||||
// items have been read or an error has halted its progress. Header, Body,
|
||||
// Receipts, TotalDifficulty will be set to nil in the case returning false or
|
||||
// finding an error and should therefore no longer be read from.
|
||||
func (it *RawIterator) Next() bool {
|
||||
// Clear old errors.
|
||||
it.err = nil
|
||||
if it.e.m.start+it.e.m.count <= it.next {
|
||||
it.clear()
|
||||
return false
|
||||
}
|
||||
off, err := it.e.readOffset(it.next)
|
||||
if err == io.EOF {
|
||||
if err != nil {
|
||||
// Error here means block index is corrupted, so don't
|
||||
// continue.
|
||||
it.clear()
|
||||
it.err = err
|
||||
return false
|
||||
}
|
||||
var n int64
|
||||
if it.Header, n, it.err = newSnappyReader(it.e.s, TypeCompressedHeader, off); it.err != nil {
|
||||
it.clear()
|
||||
return true
|
||||
}
|
||||
off += n
|
||||
if it.Body, n, it.err = newSnappyReader(it.e.s, TypeCompressedBody, off); it.err != nil {
|
||||
it.clear()
|
||||
return true
|
||||
}
|
||||
off += n
|
||||
if it.Receipts, n, it.err = newSnappyReader(it.e.s, TypeCompressedReceipts, off); it.err != nil {
|
||||
it.clear()
|
||||
return true
|
||||
}
|
||||
off += n
|
||||
if it.TotalDifficulty, _, it.err = it.e.s.ReaderAt(TypeTotalDifficulty, off); it.err != nil {
|
||||
it.clear()
|
||||
return true
|
||||
}
|
||||
it.next += 1
|
||||
|
|
@ -154,10 +179,19 @@ func (it *RawIterator) Number() uint64 {
|
|||
return it.next - 1
|
||||
}
|
||||
|
||||
// Error returns the error status of the iterator.
|
||||
// Error returns the error status of the iterator. It should be called before
|
||||
// reading from any of the iterator's values.
|
||||
func (it *RawIterator) Error() error {
|
||||
if it.err == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return it.err
|
||||
}
|
||||
|
||||
// clear sets all the outputs to nil.
|
||||
func (it *RawIterator) clear() {
|
||||
it.Header = nil
|
||||
it.Body = nil
|
||||
it.Receipts = nil
|
||||
it.TotalDifficulty = nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue