mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-23 05:06:43 +00:00
core/rawdb, ethdb: polish
This commit is contained in:
parent
e6e78637e7
commit
90d9e313f4
9 changed files with 86 additions and 80 deletions
|
|
@ -403,8 +403,8 @@ func (f *chainFreezer) AncientRange(kind string, start, count, maxBytes uint64)
|
||||||
return f.ancients.AncientRange(kind, start, count, maxBytes)
|
return f.ancients.AncientRange(kind, start, count, maxBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *chainFreezer) AncientBytes(kind string, item, offset, length uint64) ([]byte, error) {
|
func (f *chainFreezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) {
|
||||||
return f.ancients.AncientBytes(kind, item, offset, length)
|
return f.ancients.AncientBytes(kind, id, offset, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *chainFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (int64, error) {
|
func (f *chainFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (int64, error) {
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,9 @@ func (db *nofreezedb) AncientRange(kind string, start, max, maxByteSize uint64)
|
||||||
return nil, errNotSupported
|
return nil, errNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
// AncientBytes retrieves a byte range [offset:offset+length] from the specified ancient item.
|
// AncientBytes retrieves the value segment of the element specified by the id
|
||||||
func (db *nofreezedb) AncientBytes(kind string, item, offset, length uint64) ([]byte, error) {
|
// and value offsets.
|
||||||
|
func (db *nofreezedb) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) {
|
||||||
return nil, errNotSupported
|
return nil, errNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -202,10 +202,11 @@ func (f *Freezer) AncientRange(kind string, start, count, maxBytes uint64) ([][]
|
||||||
return nil, errUnknownTable
|
return nil, errUnknownTable
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveBytes retrieves a byte range [offset:offset+length] from the specified ancient item.
|
// AncientBytes retrieves the value segment of the element specified by the id
|
||||||
func (f *Freezer) AncientBytes(kind string, number, offset, length uint64) ([]byte, error) {
|
// and value offsets.
|
||||||
|
func (f *Freezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) {
|
||||||
if table := f.tables[kind]; table != nil {
|
if table := f.tables[kind]; table != nil {
|
||||||
return table.RetrieveBytes(number, offset, length)
|
return table.RetrieveBytes(id, offset, length)
|
||||||
}
|
}
|
||||||
return nil, errUnknownTable
|
return nil, errUnknownTable
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -413,8 +413,9 @@ func (f *MemoryFreezer) AncientDatadir() (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AncientBytes retrieves a byte range [offset:offset+length] from the specified ancient item in memory.
|
// AncientBytes retrieves the value segment of the element specified by the id
|
||||||
func (f *MemoryFreezer) AncientBytes(kind string, item, offset, length uint64) ([]byte, error) {
|
// and value offsets.
|
||||||
|
func (f *MemoryFreezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) {
|
||||||
f.lock.RLock()
|
f.lock.RLock()
|
||||||
defer f.lock.RUnlock()
|
defer f.lock.RUnlock()
|
||||||
|
|
||||||
|
|
@ -422,7 +423,7 @@ func (f *MemoryFreezer) AncientBytes(kind string, item, offset, length uint64) (
|
||||||
if table == nil {
|
if table == nil {
|
||||||
return nil, errUnknownTable
|
return nil, errUnknownTable
|
||||||
}
|
}
|
||||||
entries, err := table.retrieve(item, 1, 0)
|
entries, err := table.retrieve(id, 1, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -430,6 +431,7 @@ func (f *MemoryFreezer) AncientBytes(kind string, item, offset, length uint64) (
|
||||||
return nil, errOutOfBounds
|
return nil, errOutOfBounds
|
||||||
}
|
}
|
||||||
data := entries[0]
|
data := entries[0]
|
||||||
|
|
||||||
if offset > uint64(len(data)) || offset+length > uint64(len(data)) {
|
if offset > uint64(len(data)) || offset+length > uint64(len(data)) {
|
||||||
return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", len(data), offset, length)
|
return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", len(data), offset, length)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,11 +126,13 @@ func (f *resettableFreezer) AncientRange(kind string, start, count, maxBytes uin
|
||||||
return f.freezer.AncientRange(kind, start, count, maxBytes)
|
return f.freezer.AncientRange(kind, start, count, maxBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveBytes retrieves a byte range [offset:offset+length] from the specified ancient item.
|
// AncientBytes retrieves the value segment of the element specified by the id
|
||||||
func (f *resettableFreezer) AncientBytes(kind string, number, offset, length uint64) ([]byte, error) {
|
// and value offsets.
|
||||||
|
func (f *resettableFreezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) {
|
||||||
f.lock.RLock()
|
f.lock.RLock()
|
||||||
defer f.lock.RUnlock()
|
defer f.lock.RUnlock()
|
||||||
return f.freezer.AncientBytes(kind, number, offset, length)
|
|
||||||
|
return f.freezer.AncientBytes(kind, id, offset, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ancients returns the length of the frozen items.
|
// Ancients returns the length of the frozen items.
|
||||||
|
|
|
||||||
|
|
@ -1107,6 +1107,67 @@ func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []i
|
||||||
return output, sizes, nil
|
return output, sizes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RetrieveBytes retrieves the value segment of the element specified by the id
|
||||||
|
// and value offsets.
|
||||||
|
func (t *freezerTable) RetrieveBytes(item, offset, length uint64) ([]byte, error) {
|
||||||
|
t.lock.RLock()
|
||||||
|
defer t.lock.RUnlock()
|
||||||
|
|
||||||
|
if t.index == nil || t.head == nil || t.metadata.file == nil {
|
||||||
|
return nil, errClosed
|
||||||
|
}
|
||||||
|
items, hidden := t.items.Load(), t.itemHidden.Load()
|
||||||
|
if items <= item || hidden > item {
|
||||||
|
return nil, errOutOfBounds
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the index entries for the specified ID and its immediate successor
|
||||||
|
indices, err := t.getIndices(item, 1)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
index0, index1 := indices[0], indices[1]
|
||||||
|
|
||||||
|
itemStart, endLimit, fileId := index0.bounds(index1)
|
||||||
|
itemSize := endLimit - itemStart
|
||||||
|
|
||||||
|
dataFile, exist := t.files[fileId]
|
||||||
|
if !exist {
|
||||||
|
return nil, fmt.Errorf("missing data file %d", fileId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the partial read if no-compression was enabled upon
|
||||||
|
if t.config.noSnappy {
|
||||||
|
// Range check before reading
|
||||||
|
if offset > uint64(itemSize) || offset+length > uint64(itemSize) {
|
||||||
|
return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", itemSize, offset, length)
|
||||||
|
}
|
||||||
|
itemStart += uint32(offset)
|
||||||
|
|
||||||
|
buf := make([]byte, length)
|
||||||
|
_, err = dataFile.ReadAt(buf, int64(itemStart))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf, nil
|
||||||
|
} else {
|
||||||
|
buf := make([]byte, itemSize)
|
||||||
|
_, err = dataFile.ReadAt(buf, int64(itemStart))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// If compressed, read the full item, decompress, then slice
|
||||||
|
data, err := snappy.Decode(nil, buf)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if offset > uint64(len(data)) || offset+length > uint64(len(data)) {
|
||||||
|
return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", len(data), offset, length)
|
||||||
|
}
|
||||||
|
return data[offset : offset+length], nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// size returns the total data size in the freezer table.
|
// size returns the total data size in the freezer table.
|
||||||
func (t *freezerTable) size() (uint64, error) {
|
func (t *freezerTable) size() (uint64, error) {
|
||||||
t.lock.RLock()
|
t.lock.RLock()
|
||||||
|
|
@ -1235,65 +1296,3 @@ func (t *freezerTable) dumpIndex(w io.Writer, start, stop int64) {
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, "|--------------------------|\n")
|
fmt.Fprintf(w, "|--------------------------|\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
// RetrieveBytes retrieves a byte range [offset:offset+length] from the specified ancient item.
|
|
||||||
func (t *freezerTable) RetrieveBytes(item, offset, length uint64) ([]byte, error) {
|
|
||||||
t.lock.RLock()
|
|
||||||
defer t.lock.RUnlock()
|
|
||||||
|
|
||||||
if t.index == nil || t.head == nil || t.metadata.file == nil {
|
|
||||||
return nil, errClosed
|
|
||||||
}
|
|
||||||
items := t.items.Load()
|
|
||||||
hidden := t.itemHidden.Load()
|
|
||||||
if items <= item || hidden > item {
|
|
||||||
return nil, errOutOfBounds
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read the index entries for the item and the next item,
|
|
||||||
// this method will return two indices or an error.
|
|
||||||
indices, err := t.getIndices(item, 1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
index0 := indices[0]
|
|
||||||
index1 := indices[1]
|
|
||||||
startOffset, endOffset, fileId := index0.bounds(index1)
|
|
||||||
itemSize := endOffset - startOffset
|
|
||||||
|
|
||||||
dataFile, exist := t.files[fileId]
|
|
||||||
if !exist {
|
|
||||||
return nil, fmt.Errorf("missing data file %d", fileId)
|
|
||||||
}
|
|
||||||
|
|
||||||
readBytes := int(itemSize)
|
|
||||||
if t.config.noSnappy {
|
|
||||||
// Range check before reading
|
|
||||||
if offset > uint64(itemSize) || offset+length > uint64(itemSize) {
|
|
||||||
return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", itemSize, offset, length)
|
|
||||||
}
|
|
||||||
startOffset += uint32(offset)
|
|
||||||
readBytes = int(length)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf := make([]byte, readBytes)
|
|
||||||
_, err = dataFile.ReadAt(buf, int64(startOffset))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not compressed, read only the requested bytes
|
|
||||||
if t.config.noSnappy {
|
|
||||||
return buf, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// If compressed, read the full item, decompress, then slice
|
|
||||||
data, err := snappy.Decode(nil, buf)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if offset > uint64(len(data)) || offset+length > uint64(len(data)) {
|
|
||||||
return nil, fmt.Errorf("requested range out of bounds after decompression: item size %d, offset %d, length %d", len(data), offset, length)
|
|
||||||
}
|
|
||||||
return data[offset : offset+length], nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -64,8 +64,8 @@ func (t *table) AncientRange(kind string, start, count, maxBytes uint64) ([][]by
|
||||||
|
|
||||||
// AncientBytes is a noop passthrough that just forwards the request to the underlying
|
// AncientBytes is a noop passthrough that just forwards the request to the underlying
|
||||||
// database.
|
// database.
|
||||||
func (t *table) AncientBytes(kind string, item, offset, length uint64) ([]byte, error) {
|
func (t *table) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) {
|
||||||
return t.db.AncientBytes(kind, item, offset, length)
|
return t.db.AncientBytes(kind, id, offset, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ancients is a noop passthrough that just forwards the request to the underlying
|
// Ancients is a noop passthrough that just forwards the request to the underlying
|
||||||
|
|
|
||||||
|
|
@ -121,8 +121,9 @@ type AncientReaderOp interface {
|
||||||
// - if maxBytes is not specified, 'count' items will be returned if they are present
|
// - if maxBytes is not specified, 'count' items will be returned if they are present
|
||||||
AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error)
|
AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error)
|
||||||
|
|
||||||
// AncientBytes retrieves a byte range [offset:offset+length] from the specified ancient item.
|
// AncientBytes retrieves the value segment of the element specified by the id
|
||||||
AncientBytes(kind string, number, offset, length uint64) ([]byte, error)
|
// and value offsets.
|
||||||
|
AncientBytes(kind string, id, offset, length uint64) ([]byte, error)
|
||||||
|
|
||||||
// Ancients returns the ancient item numbers in the ancient store.
|
// Ancients returns the ancient item numbers in the ancient store.
|
||||||
Ancients() (uint64, error)
|
Ancients() (uint64, error)
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ func (db *Database) Close() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *Database) AncientBytes(kind string, item, offset, length uint64) ([]byte, error) {
|
func (db *Database) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) {
|
||||||
panic("not supported")
|
panic("not supported")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue