core, eth, trie: Beginnings of a migration process for direct cache

This commit is contained in:
Nick Johnson 2016-10-27 17:04:01 +01:00
parent 3262254496
commit 548487b968
3 changed files with 47 additions and 18 deletions

View file

@ -42,7 +42,6 @@ var StartingNonce uint64
var MaxTrieCacheGen = uint16(120)
var DirectCachePrefix = []byte("accounthashcache:")
var DirectStateCacheCompleteKey = []byte("directstatecache:complete")
const (
// Number of past tries to keep. This value is chosen such that
@ -193,12 +192,12 @@ func (self *StateDB) SetBlockContext(blockHash common.Hash, blockNum uint64, val
// Check if cache population has completed
if !self.cacheComplete {
if value, err := self.db.Get(DirectStateCacheCompleteKey); err == nil && value != nil {
if _, status := trie.GetMigrationState(DirectCachePrefix, self.db); status == trie.Complete {
self.cacheComplete = true
}
}
storage := trie.NewDirectCache(self.trie, self.db, DirectCachePrefix, blockNum, blockHash, validator, true)
storage := trie.NewDirectCache(self.trie, self.db, DirectCachePrefix, blockNum, blockHash, validator, self.cacheComplete)
self.storage = trie.NewSecure(storage, self.db)
}

View file

@ -355,9 +355,6 @@ func addMipmapBloomBins(db ethdb.Database) (err error) {
return nil
}
//struct upgradeState
func populateDirectCache(db ethdb.Database, blockchain *core.BlockChain) error {
return nil
}

View file

@ -30,13 +30,22 @@ import (
)
var (
directCacheLock = &sync.Mutex{}
directCacheLocked = false
directCacheWrites = metrics.NewCounter("directcache/writes")
directCacheHits = metrics.NewCounter("directcache/hits")
directCacheMisses = metrics.NewCounter("directcache/misses")
directCacheTimer = metrics.NewTimer("directcache/timer")
NotFound = errors.New("Cache entry not found")
directCacheLock = &sync.Mutex{}
directCacheLocked = false
directCacheWrites = metrics.NewCounter("directcache/writes")
directCacheHits = metrics.NewCounter("directcache/hits")
directCacheMisses = metrics.NewCounter("directcache/misses")
directCacheTimer = metrics.NewTimer("directcache/timer")
NotFound = errors.New("Cache entry not found")
MigrationPrefix = []byte("directstatecachemigration:")
)
type MigrationStatus int
const (
NotStarted = iota
Running = iota
Complete = iota
)
// CacheValidator can check whether a certain block is in the current canonical chain.
@ -206,10 +215,6 @@ type cachedValue struct {
}
func DirectCacheTransaction(tx func() (error)) error {
if directCacheLocked {
return fmt.Errorf("Reentrant calls to DirectCacheTransaction are not permitted")
}
directCacheLock.Lock()
directCacheLocked = true
defer func() {
@ -250,7 +255,7 @@ func GetDirectCache(prefix, key []byte, db Database) ([]byte, uint64, common.Has
}
var data cachedValue
if err := rlp.DecodeBytes(enc, &data); err != nil && glog.V(logger.Error) {
if err := rlp.DecodeBytes(enc, &data); err != nil {
return nil, 0, common.Hash{}, fmt.Errorf("Can't decode cached object at %x: %v", key, err)
}
return data.Value, data.BlockNum, data.BlockHash, nil
@ -264,6 +269,34 @@ func HasDirectCache(prefix, key []byte, db Database) bool {
return false
}
type migrationState struct {
Status MigrationStatus
Number uint64
}
// GetMigrationState returns the block number of the migration to the direct cache, and
// whether or not it's complete.
func GetMigrationState(prefix []byte, db Database) (uint64, MigrationStatus) {
enc, _ := db.Get(append(MigrationPrefix, prefix...))
if len(enc) == 0 {
return 0, NotStarted
}
var data migrationState
if err := rlp.DecodeBytes(enc, &data); err != nil {
glog.Errorf("Could not decode migration status: %v", err)
return 0, NotStarted
}
return data.Number, data.Status
}
// SetMigrationState updates the migration state in the database
func SetMigrationState(prefix []byte, blockNum uint64, status MigrationStatus, db Database) error {
enc, _ := rlp.EncodeToBytes(migrationState{status, blockNum})
return db.Put(append(MigrationPrefix, prefix...), enc)
}
// DirectCacheReads retrieves a global counter measuring the number of direct
// cache reads from the disk since process startup. This isn't useful for anything
// apart from trie debugging purposes.