mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-05-24 08:49:29 +00:00
triedb, core: polish code
This commit is contained in:
parent
e67fa13e34
commit
133ee263c8
7 changed files with 60 additions and 74 deletions
|
|
@ -90,16 +90,17 @@ const (
|
|||
stateHistoryStorageData = "storage.data"
|
||||
)
|
||||
|
||||
// StateHistoryTailGroup is the tail group shared by all state history tables.
|
||||
const StateHistoryTailGroup = "history"
|
||||
// DefaultHistoryGroup is the tail group shared by all state/trienode history
|
||||
// tables with tail pruning enabled.
|
||||
const DefaultHistoryGroup = "history"
|
||||
|
||||
// stateFreezerTableConfigs configures the settings for tables in the state freezer.
|
||||
var stateFreezerTableConfigs = map[string]freezerTableConfig{
|
||||
stateHistoryMeta: {noSnappy: true, tailGroup: StateHistoryTailGroup},
|
||||
stateHistoryAccountIndex: {noSnappy: false, tailGroup: StateHistoryTailGroup},
|
||||
stateHistoryStorageIndex: {noSnappy: false, tailGroup: StateHistoryTailGroup},
|
||||
stateHistoryAccountData: {noSnappy: false, tailGroup: StateHistoryTailGroup},
|
||||
stateHistoryStorageData: {noSnappy: false, tailGroup: StateHistoryTailGroup},
|
||||
stateHistoryMeta: {noSnappy: true, tailGroup: DefaultHistoryGroup},
|
||||
stateHistoryAccountIndex: {noSnappy: false, tailGroup: DefaultHistoryGroup},
|
||||
stateHistoryStorageIndex: {noSnappy: false, tailGroup: DefaultHistoryGroup},
|
||||
stateHistoryAccountData: {noSnappy: false, tailGroup: DefaultHistoryGroup},
|
||||
stateHistoryStorageData: {noSnappy: false, tailGroup: DefaultHistoryGroup},
|
||||
}
|
||||
|
||||
const (
|
||||
|
|
@ -108,18 +109,15 @@ const (
|
|||
trienodeHistoryValueSectionTable = "trienode.value"
|
||||
)
|
||||
|
||||
// TrienodeHistoryTailGroup is the tail group shared by all trienode history tables.
|
||||
const TrienodeHistoryTailGroup = "history"
|
||||
|
||||
// trienodeFreezerTableConfigs configures the settings for tables in the trienode freezer.
|
||||
var trienodeFreezerTableConfigs = map[string]freezerTableConfig{
|
||||
trienodeHistoryHeaderTable: {noSnappy: false, tailGroup: TrienodeHistoryTailGroup},
|
||||
trienodeHistoryHeaderTable: {noSnappy: false, tailGroup: DefaultHistoryGroup},
|
||||
|
||||
// Disable snappy compression to allow efficient partial read.
|
||||
trienodeHistoryKeySectionTable: {noSnappy: true, tailGroup: TrienodeHistoryTailGroup},
|
||||
trienodeHistoryKeySectionTable: {noSnappy: true, tailGroup: DefaultHistoryGroup},
|
||||
|
||||
// Disable snappy compression to allow efficient partial read.
|
||||
trienodeHistoryValueSectionTable: {noSnappy: true, tailGroup: TrienodeHistoryTailGroup},
|
||||
trienodeHistoryValueSectionTable: {noSnappy: true, tailGroup: DefaultHistoryGroup},
|
||||
}
|
||||
|
||||
// The list of identifiers of ancient stores.
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ const freezerTableSize = 2 * 1000 * 1000 * 1000
|
|||
// - The in-order data ensures that disk reads are always optimized.
|
||||
type Freezer struct {
|
||||
datadir string
|
||||
head atomic.Uint64 // Number of items stored (including items removed from tail)
|
||||
head atomic.Uint64 // Number of items stored (including items removed from tail)
|
||||
tails map[string]*atomic.Uint64 // Per-group tail cache, keyed by tail group name
|
||||
|
||||
// This lock synchronizes writers and the truncate operation, as well as
|
||||
// the "atomic" (batched) read operations.
|
||||
|
|
@ -117,6 +118,7 @@ func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize ui
|
|||
datadir: datadir,
|
||||
readonly: readonly,
|
||||
tables: make(map[string]*freezerTable),
|
||||
tails: make(map[string]*atomic.Uint64),
|
||||
instanceLock: lock,
|
||||
}
|
||||
|
||||
|
|
@ -216,32 +218,18 @@ func (f *Freezer) Ancients() (uint64, error) {
|
|||
}
|
||||
|
||||
// Tail returns the lowest accessible item index for the given tail group.
|
||||
// All tables sharing this group must agree on the tail; an empty group name
|
||||
// refers to non-prunable tables and always returns 0.
|
||||
// All tables sharing this group agree on the tail; an empty group name
|
||||
// refers to non-prunable tables and always returns 0. Unknown groups return
|
||||
// an error.
|
||||
func (f *Freezer) Tail(group string) (uint64, error) {
|
||||
if group == "" {
|
||||
return 0, nil
|
||||
}
|
||||
var (
|
||||
tail uint64
|
||||
found bool
|
||||
)
|
||||
for _, table := range f.tables {
|
||||
if table.config.tailGroup != group {
|
||||
continue
|
||||
}
|
||||
h := table.itemHidden.Load()
|
||||
if !found {
|
||||
tail = h
|
||||
found = true
|
||||
} else if h != tail {
|
||||
return 0, fmt.Errorf("inconsistent tail in group %q: %d vs %d", group, h, tail)
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
tail, ok := f.tails[group]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("unknown tail group: %q", group)
|
||||
}
|
||||
return tail, nil
|
||||
return tail.Load(), nil
|
||||
}
|
||||
|
||||
// AncientSize returns the ancient size of the specified category.
|
||||
|
|
@ -333,25 +321,14 @@ func (f *Freezer) TruncateTail(group string, tail uint64) (uint64, error) {
|
|||
if group == "" {
|
||||
return 0, errors.New("empty tail group")
|
||||
}
|
||||
cached, ok := f.tails[group]
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("unknown tail group: %q", group)
|
||||
}
|
||||
f.writeLock.Lock()
|
||||
defer f.writeLock.Unlock()
|
||||
|
||||
var (
|
||||
prev uint64
|
||||
found bool
|
||||
)
|
||||
for _, table := range f.tables {
|
||||
if table.config.tailGroup != group {
|
||||
continue
|
||||
}
|
||||
if !found {
|
||||
prev = table.itemHidden.Load()
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
return 0, fmt.Errorf("unknown tail group: %q", group)
|
||||
}
|
||||
prev := cached.Load()
|
||||
for _, table := range f.tables {
|
||||
if table.config.tailGroup != group {
|
||||
continue
|
||||
|
|
@ -360,6 +337,9 @@ func (f *Freezer) TruncateTail(group string, tail uint64) (uint64, error) {
|
|||
return 0, err
|
||||
}
|
||||
}
|
||||
if tail > prev {
|
||||
cached.Store(tail)
|
||||
}
|
||||
// Update the head if the requested tail exceeds the current head.
|
||||
if f.head.Load() < tail {
|
||||
f.head.Store(tail)
|
||||
|
|
@ -388,11 +368,12 @@ func (f *Freezer) validate() error {
|
|||
return nil
|
||||
}
|
||||
var (
|
||||
head uint64
|
||||
headSet bool
|
||||
groupTails = make(map[string]uint64)
|
||||
head uint64
|
||||
headSet bool
|
||||
tails = make(map[string]uint64)
|
||||
)
|
||||
for kind, table := range f.tables {
|
||||
// Validate the table head
|
||||
items := table.items.Load()
|
||||
if !headSet {
|
||||
head = items
|
||||
|
|
@ -400,6 +381,7 @@ func (f *Freezer) validate() error {
|
|||
} else if items != head {
|
||||
return fmt.Errorf("freezer table %s has a differing head: %d != %d", kind, items, head)
|
||||
}
|
||||
// Validate the table tail
|
||||
if table.config.tailGroup == "" {
|
||||
if table.itemHidden.Load() != 0 {
|
||||
return fmt.Errorf("non-prunable freezer table '%s' has a non-zero tail: %d", kind, table.itemHidden.Load())
|
||||
|
|
@ -407,15 +389,21 @@ func (f *Freezer) validate() error {
|
|||
continue
|
||||
}
|
||||
hidden := table.itemHidden.Load()
|
||||
if t, ok := groupTails[table.config.tailGroup]; ok {
|
||||
if t, ok := tails[table.config.tailGroup]; ok {
|
||||
if t != hidden {
|
||||
return fmt.Errorf("freezer table %s has differing tail in group %q: %d != %d", kind, table.config.tailGroup, hidden, t)
|
||||
}
|
||||
} else {
|
||||
groupTails[table.config.tailGroup] = hidden
|
||||
tails[table.config.tailGroup] = hidden
|
||||
}
|
||||
}
|
||||
f.head.Store(head)
|
||||
|
||||
for group, tail := range tails {
|
||||
counter := new(atomic.Uint64)
|
||||
counter.Store(tail)
|
||||
f.tails[group] = counter
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -463,7 +451,7 @@ func (f *Freezer) repair() error {
|
|||
}
|
||||
// Per-group tail alignment: take the maximum tail in each group and apply
|
||||
// it to all members. Non-prunable tables must remain at tail 0.
|
||||
groupTails := make(map[string]uint64)
|
||||
tails := make(map[string]uint64)
|
||||
for kind, table := range f.tables {
|
||||
if table.config.tailGroup == "" {
|
||||
if table.itemHidden.Load() != 0 {
|
||||
|
|
@ -472,18 +460,24 @@ func (f *Freezer) repair() error {
|
|||
continue
|
||||
}
|
||||
hidden := table.itemHidden.Load()
|
||||
if t, ok := groupTails[table.config.tailGroup]; !ok || hidden > t {
|
||||
groupTails[table.config.tailGroup] = hidden
|
||||
if t, ok := tails[table.config.tailGroup]; !ok || hidden > t {
|
||||
tails[table.config.tailGroup] = hidden
|
||||
}
|
||||
}
|
||||
for _, table := range f.tables {
|
||||
if table.config.tailGroup == "" {
|
||||
continue
|
||||
}
|
||||
if err := table.truncateTail(groupTails[table.config.tailGroup]); err != nil {
|
||||
if err := table.truncateTail(tails[table.config.tailGroup]); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
f.head.Store(head)
|
||||
|
||||
for group, tail := range tails {
|
||||
counter := new(atomic.Uint64)
|
||||
counter.Store(tail)
|
||||
f.tails[group] = counter
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -378,7 +378,7 @@ func (dl *diskLayer) writeHistory(typ historyType, diff *diffLayer) (bool, error
|
|||
if limit == 0 {
|
||||
return false, nil
|
||||
}
|
||||
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
|
||||
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
|
||||
if err != nil {
|
||||
return false, err
|
||||
} // firstID = tail+1
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ func truncateFromHead(store ethdb.AncientStore, typ historyType, nhead uint64) (
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
otail, err := store.Tail(rawdb.StateHistoryTailGroup)
|
||||
otail, err := store.Tail(rawdb.DefaultHistoryGroup)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -303,13 +303,7 @@ func truncateFromTail(store ethdb.AncientStore, typ historyType, ntail uint64) (
|
|||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
var group string
|
||||
if typ == typeStateHistory {
|
||||
group = rawdb.StateHistoryTailGroup
|
||||
} else {
|
||||
group = rawdb.TrienodeHistoryTailGroup
|
||||
}
|
||||
otail, err := store.Tail(group)
|
||||
otail, err := store.Tail(rawdb.DefaultHistoryGroup)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -321,7 +315,7 @@ func truncateFromTail(store ethdb.AncientStore, typ historyType, ntail uint64) (
|
|||
if otail == ntail {
|
||||
return 0, nil
|
||||
}
|
||||
otail, err = store.TruncateTail(group, ntail)
|
||||
otail, err = store.TruncateTail(rawdb.DefaultHistoryGroup, ntail)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
@ -436,7 +430,7 @@ func repairHistory(db ethdb.Database, isUBT bool, readOnly bool, stateID uint64,
|
|||
truncTo = min(truncTo, thead)
|
||||
} else {
|
||||
if thead == 0 {
|
||||
_, err = trienodes.TruncateTail(rawdb.TrienodeHistoryTailGroup, stateID)
|
||||
_, err = trienodes.TruncateTail(rawdb.DefaultHistoryGroup, stateID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -542,7 +542,7 @@ func (i *indexIniter) run(recover bool) {
|
|||
|
||||
// next returns the ID of the next state history to be indexed.
|
||||
func (i *indexIniter) next() (uint64, error) {
|
||||
tail, err := i.freezer.Tail(rawdb.StateHistoryTailGroup)
|
||||
tail, err := i.freezer.Tail(rawdb.DefaultHistoryGroup)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ type HistoryStats struct {
|
|||
// sanitizeRange limits the given range to fit within the local history store.
|
||||
func sanitizeRange(start, end uint64, freezer ethdb.AncientReader) (uint64, uint64, error) {
|
||||
// Load the id of the first history object in local store.
|
||||
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
|
||||
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ func storageHistory(freezer ethdb.AncientReader, address common.Address, slot co
|
|||
// historyRange returns the block number range of local state histories.
|
||||
func historyRange(freezer ethdb.AncientReader) (uint64, uint64, error) {
|
||||
// Load the id of the first history object in local store.
|
||||
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
|
||||
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ func checkStateAvail(state stateIdent, exptyp historyType, freezer ethdb.Ancient
|
|||
return 0, fmt.Errorf("unsupported history type: %d, want: %v", toHistoryType(state.typ), exptyp)
|
||||
}
|
||||
// firstID = tail+1
|
||||
tail, err := freezer.Tail(rawdb.StateHistoryTailGroup)
|
||||
tail, err := freezer.Tail(rawdb.DefaultHistoryGroup)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue