mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
triedb/pathdb: use uint16 for restart and uint8 for restartLen
This commit is contained in:
parent
69fa0683ad
commit
03d507dc37
1 changed files with 23 additions and 18 deletions
|
|
@ -85,15 +85,19 @@ func (d *indexBlockDesc) decode(blob []byte) {
|
||||||
// | | | ChunkN |
|
// | | | ChunkN |
|
||||||
// | | +------------------+
|
// | | +------------------+
|
||||||
// +-|---| Restart1 |
|
// +-|---| Restart1 |
|
||||||
// | | Restart... | 4N bytes
|
// | | Restart... | 2N bytes
|
||||||
// +---| RestartN |
|
// +---| RestartN |
|
||||||
// +------------------+
|
// +------------------+
|
||||||
// | Restart count | 4 bytes
|
// | Restart count | 1 byte
|
||||||
// +------------------+
|
// +------------------+
|
||||||
//
|
//
|
||||||
// - Chunk list: A list of data chunks
|
// - Chunk list: A list of data chunks
|
||||||
// - Restart list: A list of 4-byte pointers, each pointing to the start position of a chunk
|
// - Restart list: A list of 2-byte pointers, each pointing to the start position of a chunk
|
||||||
// - Restart count: The number of restarts in the block, stored at the end of the block (4 bytes)
|
// - Restart count: The number of restarts in the block, stored at the end of the block (1 byte)
|
||||||
|
//
|
||||||
|
// Note: the pointer is encoded as a uint16, which is sufficient within a chunk.
|
||||||
|
// A uint16 can cover offsets in the range [0, 65536), which is more than enough
|
||||||
|
// to store 4096 integers.
|
||||||
//
|
//
|
||||||
// Each chunk begins with the full value of the first integer, followed by
|
// Each chunk begins with the full value of the first integer, followed by
|
||||||
// subsequent integers representing the differences between the current value
|
// subsequent integers representing the differences between the current value
|
||||||
|
|
@ -111,26 +115,26 @@ func (d *indexBlockDesc) decode(blob []byte) {
|
||||||
// +----------------+
|
// +----------------+
|
||||||
//
|
//
|
||||||
// Empty index block is regarded as invalid.
|
// Empty index block is regarded as invalid.
|
||||||
func parseIndexBlock(blob []byte) ([]uint32, []byte, error) {
|
func parseIndexBlock(blob []byte) ([]uint16, []byte, error) {
|
||||||
if len(blob) < 4 {
|
if len(blob) < 1 {
|
||||||
return nil, nil, fmt.Errorf("corrupted index block, len: %d", len(blob))
|
return nil, nil, fmt.Errorf("corrupted index block, len: %d", len(blob))
|
||||||
}
|
}
|
||||||
restartLen := binary.BigEndian.Uint32(blob[len(blob)-4:])
|
restartLen := blob[len(blob)-1]
|
||||||
if restartLen == 0 {
|
if restartLen == 0 {
|
||||||
return nil, nil, errors.New("corrupted index block, no restart")
|
return nil, nil, errors.New("corrupted index block, no restart")
|
||||||
}
|
}
|
||||||
tailLen := int(restartLen+1) * 4
|
tailLen := int(restartLen)*2 + 1
|
||||||
if len(blob) < tailLen {
|
if len(blob) < tailLen {
|
||||||
return nil, nil, fmt.Errorf("truncated restarts, size: %d, restarts: %d", len(blob), restartLen)
|
return nil, nil, fmt.Errorf("truncated restarts, size: %d, restarts: %d", len(blob), restartLen)
|
||||||
}
|
}
|
||||||
restarts := make([]uint32, 0, restartLen)
|
restarts := make([]uint16, 0, restartLen)
|
||||||
for i := restartLen; i > 0; i-- {
|
for i := int(restartLen); i > 0; i-- {
|
||||||
restart := binary.BigEndian.Uint32(blob[len(blob)-int(i+1)*4:])
|
restart := binary.BigEndian.Uint16(blob[len(blob)-1-2*i:])
|
||||||
restarts = append(restarts, restart)
|
restarts = append(restarts, restart)
|
||||||
}
|
}
|
||||||
// Validate that restart points are strictly ordered and within the valid
|
// Validate that restart points are strictly ordered and within the valid
|
||||||
// data range.
|
// data range.
|
||||||
var prev uint32
|
var prev uint16
|
||||||
for i := 0; i < len(restarts); i++ {
|
for i := 0; i < len(restarts); i++ {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
if restarts[i] <= prev {
|
if restarts[i] <= prev {
|
||||||
|
|
@ -147,7 +151,7 @@ func parseIndexBlock(blob []byte) ([]uint32, []byte, error) {
|
||||||
|
|
||||||
// blockReader is the reader to access the element within a block.
|
// blockReader is the reader to access the element within a block.
|
||||||
type blockReader struct {
|
type blockReader struct {
|
||||||
restarts []uint32
|
restarts []uint16
|
||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,7 +226,7 @@ func (br *blockReader) readGreaterThan(id uint64) (uint64, error) {
|
||||||
|
|
||||||
type blockWriter struct {
|
type blockWriter struct {
|
||||||
desc *indexBlockDesc // Descriptor of the block
|
desc *indexBlockDesc // Descriptor of the block
|
||||||
restarts []uint32 // Offsets into the data slice, marking the start of each section
|
restarts []uint16 // Offsets into the data slice, marking the start of each section
|
||||||
scratch []byte // Buffer used for encoding full integers or value differences
|
scratch []byte // Buffer used for encoding full integers or value differences
|
||||||
data []byte // Aggregated encoded data slice
|
data []byte // Aggregated encoded data slice
|
||||||
}
|
}
|
||||||
|
|
@ -261,7 +265,7 @@ func (b *blockWriter) append(id uint64) error {
|
||||||
if b.desc.entries%indexBlockRestartLen == 0 {
|
if b.desc.entries%indexBlockRestartLen == 0 {
|
||||||
// Save the offset within the data slice as the restart point
|
// Save the offset within the data slice as the restart point
|
||||||
// for the next section.
|
// for the next section.
|
||||||
b.restarts = append(b.restarts, uint32(len(b.data)))
|
b.restarts = append(b.restarts, uint16(len(b.data)))
|
||||||
|
|
||||||
// The restart point item can either be encoded in variable
|
// The restart point item can either be encoded in variable
|
||||||
// size or fixed size. Although variable-size encoding is
|
// size or fixed size. Although variable-size encoding is
|
||||||
|
|
@ -395,9 +399,10 @@ func (b *blockWriter) full() bool {
|
||||||
// This function is safe to be called multiple times.
|
// This function is safe to be called multiple times.
|
||||||
func (b *blockWriter) finish() []byte {
|
func (b *blockWriter) finish() []byte {
|
||||||
var buf []byte
|
var buf []byte
|
||||||
for _, number := range append(b.restarts, uint32(len(b.restarts))) {
|
for _, number := range b.restarts {
|
||||||
binary.BigEndian.PutUint32(b.scratch[:4], number)
|
binary.BigEndian.PutUint16(b.scratch[:2], number)
|
||||||
buf = append(buf, b.scratch[:4]...)
|
buf = append(buf, b.scratch[:2]...)
|
||||||
}
|
}
|
||||||
|
buf = append(buf, byte(len(b.restarts)))
|
||||||
return append(b.data, buf...)
|
return append(b.data, buf...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue