Skip to content

Commit ab41279

Browse files
committed
triedb/pathdb: implement iterator in the history index
1 parent cfa3b96 commit ab41279

File tree

4 files changed

+684
-69
lines changed

4 files changed

+684
-69
lines changed

triedb/pathdb/history_index.go

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import (
2020
"errors"
2121
"fmt"
2222
"math"
23-
"sort"
2423

2524
"github.com/ethereum/go-ethereum/core/rawdb"
2625
"github.com/ethereum/go-ethereum/ethdb"
@@ -119,30 +118,34 @@ func (r *indexReader) refresh() error {
119118
return nil
120119
}
121120

121+
// newIterator creates an iterator for traversing the index entries.
122+
func (r *indexReader) newIterator() *indexIterator {
123+
return newIndexIterator(r.descList, func(id uint32) (*blockReader, error) {
124+
br, ok := r.readers[id]
125+
if !ok {
126+
var err error
127+
br, err = newBlockReader(readStateIndexBlock(r.state, r.db, id))
128+
if err != nil {
129+
return nil, err
130+
}
131+
r.readers[id] = br
132+
}
133+
return br, nil
134+
})
135+
}
136+
122137
// readGreaterThan locates the first element that is greater than the specified
123138
// id. If no such element is found, MaxUint64 is returned.
124139
func (r *indexReader) readGreaterThan(id uint64) (uint64, error) {
125-
index := sort.Search(len(r.descList), func(i int) bool {
126-
return id < r.descList[i].max
127-
})
128-
if index == len(r.descList) {
129-
return math.MaxUint64, nil
140+
it := r.newIterator()
141+
found := it.SeekGT(id)
142+
if err := it.Error(); err != nil {
143+
return 0, err
130144
}
131-
desc := r.descList[index]
132-
133-
br, ok := r.readers[desc.id]
134-
if !ok {
135-
var err error
136-
blob := readStateIndexBlock(r.state, r.db, desc.id)
137-
br, err = newBlockReader(blob)
138-
if err != nil {
139-
return 0, err
140-
}
141-
r.readers[desc.id] = br
145+
if !found {
146+
return math.MaxUint64, nil
142147
}
143-
// The supplied ID is not greater than block.max, ensuring that an element
144-
// satisfying the condition can be found.
145-
return br.readGreaterThan(id)
148+
return it.ID(), nil
146149
}
147150

148151
// indexWriter is responsible for writing index data for a specific state (either

triedb/pathdb/history_index_block.go

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"errors"
2222
"fmt"
2323
"math"
24-
"sort"
2524
)
2625

2726
const (
@@ -164,58 +163,15 @@ func newBlockReader(blob []byte) (*blockReader, error) {
164163
// readGreaterThan locates the first element in the block that is greater than
165164
// the specified value. If no such element is found, MaxUint64 is returned.
166165
func (br *blockReader) readGreaterThan(id uint64) (uint64, error) {
167-
var err error
168-
index := sort.Search(len(br.restarts), func(i int) bool {
169-
item, n := binary.Uvarint(br.data[br.restarts[i]:])
170-
if n <= 0 {
171-
err = fmt.Errorf("failed to decode item at restart %d", br.restarts[i])
172-
}
173-
return item > id
174-
})
175-
if err != nil {
166+
it := newBlockIterator(br.data, br.restarts)
167+
found := it.SeekGT(id)
168+
if err := it.Error(); err != nil {
176169
return 0, err
177170
}
178-
if index == 0 {
179-
item, _ := binary.Uvarint(br.data[br.restarts[0]:])
180-
return item, nil
181-
}
182-
var (
183-
start int
184-
limit int
185-
result uint64
186-
)
187-
if index == len(br.restarts) {
188-
// The element being searched falls within the last restart section,
189-
// there is no guarantee such element can be found.
190-
start = int(br.restarts[len(br.restarts)-1])
191-
limit = len(br.data)
192-
} else {
193-
// The element being searched falls within the non-last restart section,
194-
// such element can be found for sure.
195-
start = int(br.restarts[index-1])
196-
limit = int(br.restarts[index])
197-
}
198-
pos := start
199-
for pos < limit {
200-
x, n := binary.Uvarint(br.data[pos:])
201-
if pos == start {
202-
result = x
203-
} else {
204-
result += x
205-
}
206-
if result > id {
207-
return result, nil
208-
}
209-
pos += n
210-
}
211-
// The element which is greater than specified id is not found.
212-
if index == len(br.restarts) {
171+
if !found {
213172
return math.MaxUint64, nil
214173
}
215-
// The element which is the first one greater than the specified id
216-
// is exactly the one located at the restart point.
217-
item, _ := binary.Uvarint(br.data[br.restarts[index]:])
218-
return item, nil
174+
return it.ID(), nil
219175
}
220176

221177
type blockWriter struct {

0 commit comments

Comments
 (0)