mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
core, eth: avoid RLP serialization in downloader queue
This commit is contained in:
parent
30ddc903c2
commit
49bdc8b121
4 changed files with 34 additions and 8 deletions
|
|
@ -25,6 +25,7 @@ import (
|
||||||
"sort"
|
"sort"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
@ -121,6 +122,12 @@ func (h *Header) HashNoNonce() common.Hash {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Size returns the approximate memory used by all internal contents. It is used
|
||||||
|
// to approximate and limit the memory consumption of various caches.
|
||||||
|
func (h *Header) Size() common.StorageSize {
|
||||||
|
return common.StorageSize(unsafe.Sizeof(*h)) + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen()+h.Time.BitLen())/8)
|
||||||
|
}
|
||||||
|
|
||||||
func rlpHash(x interface{}) (h common.Hash) {
|
func rlpHash(x interface{}) (h common.Hash) {
|
||||||
hw := sha3.NewKeccak256()
|
hw := sha3.NewKeccak256()
|
||||||
rlp.Encode(hw, x)
|
rlp.Encode(hw, x)
|
||||||
|
|
@ -322,6 +329,8 @@ func (b *Block) HashNoNonce() common.Hash {
|
||||||
return b.header.HashNoNonce()
|
return b.header.HashNoNonce()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Size returns the true RLP encoded storage size of the block, either by encoding
|
||||||
|
// and returning it, or returning a previsouly cached value.
|
||||||
func (b *Block) Size() common.StorageSize {
|
func (b *Block) Size() common.StorageSize {
|
||||||
if size := b.size.Load(); size != nil {
|
if size := b.size.Load(); size != nil {
|
||||||
return size.(common.StorageSize)
|
return size.(common.StorageSize)
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"unsafe"
|
||||||
|
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
|
|
@ -136,6 +137,18 @@ func (r *Receipt) statusEncoding() []byte {
|
||||||
return r.PostState
|
return r.PostState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Size returns the approximate memory used by all internal contents. It is used
|
||||||
|
// to approximate and limit the memory consumption of various caches.
|
||||||
|
func (r *Receipt) Size() common.StorageSize {
|
||||||
|
size := common.StorageSize(unsafe.Sizeof(*r)) + common.StorageSize(len(r.PostState))
|
||||||
|
|
||||||
|
size += common.StorageSize(len(r.Logs)) * common.StorageSize(unsafe.Sizeof(Log{}))
|
||||||
|
for _, log := range r.Logs {
|
||||||
|
size += common.StorageSize(len(log.Topics)*common.HashLength + len(log.Data))
|
||||||
|
}
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
// String implements the Stringer interface.
|
// String implements the Stringer interface.
|
||||||
func (r *Receipt) String() string {
|
func (r *Receipt) String() string {
|
||||||
if len(r.PostState) == 0 {
|
if len(r.PostState) == 0 {
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,8 @@ func (tx *Transaction) Hash() common.Hash {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Size returns the true RLP encoded storage size of the transaction, either by
|
||||||
|
// encoding and returning it, or returning a previsouly cached value.
|
||||||
func (tx *Transaction) Size() common.StorageSize {
|
func (tx *Transaction) Size() common.StorageSize {
|
||||||
if size := tx.size.Load(); size != nil {
|
if size := tx.size.Load(); size != nil {
|
||||||
return size.(common.StorageSize)
|
return size.(common.StorageSize)
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import (
|
||||||
"github.com/ethereum/go-ethereum/common"
|
"github.com/ethereum/go-ethereum/common"
|
||||||
"github.com/ethereum/go-ethereum/core/types"
|
"github.com/ethereum/go-ethereum/core/types"
|
||||||
"github.com/ethereum/go-ethereum/log"
|
"github.com/ethereum/go-ethereum/log"
|
||||||
"github.com/ethereum/go-ethereum/rlp"
|
|
||||||
"github.com/rcrowley/go-metrics"
|
"github.com/rcrowley/go-metrics"
|
||||||
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
|
"gopkg.in/karalabe/cookiejar.v2/collections/prque"
|
||||||
)
|
)
|
||||||
|
|
@ -386,13 +385,16 @@ func (q *queue) Results(block bool) []*fetchResult {
|
||||||
|
|
||||||
// Recalculate the result item weights to prevent memory exhaustion
|
// Recalculate the result item weights to prevent memory exhaustion
|
||||||
for _, result := range results {
|
for _, result := range results {
|
||||||
var size common.StorageSize
|
size := result.Header.Size()
|
||||||
|
for _, uncle := range result.Uncles {
|
||||||
blob, _ := rlp.EncodeToBytes(result.Receipts) // TODO(karalabe): Whoah, nice hack, super optimal
|
size += uncle.Size()
|
||||||
size += common.StorageSize(len(blob))
|
}
|
||||||
blob, _ = rlp.EncodeToBytes(result.Transactions)
|
for _, receipt := range result.Receipts {
|
||||||
size += common.StorageSize(len(blob))
|
size += receipt.Size()
|
||||||
|
}
|
||||||
|
for _, tx := range result.Transactions {
|
||||||
|
size += tx.Size()
|
||||||
|
}
|
||||||
q.resultSize = common.StorageSize(blockCacheSizeWeight)*size + (1-common.StorageSize(blockCacheSizeWeight))*q.resultSize
|
q.resultSize = common.StorageSize(blockCacheSizeWeight)*size + (1-common.StorageSize(blockCacheSizeWeight))*q.resultSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue