Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 23 additions & 20 deletions triedb/pathdb/history_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"errors"
"fmt"
"math"
"sort"

"github.com/ethereum/go-ethereum/core/rawdb"
"github.com/ethereum/go-ethereum/ethdb"
Expand Down Expand Up @@ -119,30 +118,34 @@ func (r *indexReader) refresh() error {
return nil
}

// newIterator creates an iterator for traversing the index entries.
func (r *indexReader) newIterator() *indexIterator {
return newIndexIterator(r.descList, func(id uint32) (*blockReader, error) {
br, ok := r.readers[id]
if !ok {
var err error
br, err = newBlockReader(readStateIndexBlock(r.state, r.db, id))
if err != nil {
return nil, err
}
r.readers[id] = br
}
return br, nil
})
}

// readGreaterThan locates the first element that is greater than the specified
// id. If no such element is found, MaxUint64 is returned.
func (r *indexReader) readGreaterThan(id uint64) (uint64, error) {
index := sort.Search(len(r.descList), func(i int) bool {
return id < r.descList[i].max
})
if index == len(r.descList) {
return math.MaxUint64, nil
it := r.newIterator()
found := it.SeekGT(id)
if err := it.Error(); err != nil {
return 0, err
}
desc := r.descList[index]

br, ok := r.readers[desc.id]
if !ok {
var err error
blob := readStateIndexBlock(r.state, r.db, desc.id)
br, err = newBlockReader(blob)
if err != nil {
return 0, err
}
r.readers[desc.id] = br
if !found {
return math.MaxUint64, nil
}
// The supplied ID is not greater than block.max, ensuring that an element
// satisfying the condition can be found.
return br.readGreaterThan(id)
return it.ID(), nil
}

// indexWriter is responsible for writing index data for a specific state (either
Expand Down
54 changes: 5 additions & 49 deletions triedb/pathdb/history_index_block.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"errors"
"fmt"
"math"
"sort"
)

const (
Expand Down Expand Up @@ -164,58 +163,15 @@ func newBlockReader(blob []byte) (*blockReader, error) {
// readGreaterThan locates the first element in the block that is greater than
// the specified value. If no such element is found, MaxUint64 is returned.
func (br *blockReader) readGreaterThan(id uint64) (uint64, error) {
var err error
index := sort.Search(len(br.restarts), func(i int) bool {
item, n := binary.Uvarint(br.data[br.restarts[i]:])
if n <= 0 {
err = fmt.Errorf("failed to decode item at restart %d", br.restarts[i])
}
return item > id
})
if err != nil {
it := newBlockIterator(br.data, br.restarts)
found := it.SeekGT(id)
if err := it.Error(); err != nil {
return 0, err
}
if index == 0 {
item, _ := binary.Uvarint(br.data[br.restarts[0]:])
return item, nil
}
var (
start int
limit int
result uint64
)
if index == len(br.restarts) {
// The element being searched falls within the last restart section,
// there is no guarantee such element can be found.
start = int(br.restarts[len(br.restarts)-1])
limit = len(br.data)
} else {
// The element being searched falls within the non-last restart section,
// such element can be found for sure.
start = int(br.restarts[index-1])
limit = int(br.restarts[index])
}
pos := start
for pos < limit {
x, n := binary.Uvarint(br.data[pos:])
if pos == start {
result = x
} else {
result += x
}
if result > id {
return result, nil
}
pos += n
}
// The element which is greater than specified id is not found.
if index == len(br.restarts) {
if !found {
return math.MaxUint64, nil
}
// The element which is the first one greater than the specified id
// is exactly the one located at the restart point.
item, _ := binary.Uvarint(br.data[br.restarts[index]:])
return item, nil
return it.ID(), nil
}

type blockWriter struct {
Expand Down
Loading