github.com/klaytn/klaytn@v1.12.1/storage/statedb/cache_fastcache.go (about)

     1  // Copyright 2020 The klaytn Authors
     2  // This file is part of the klaytn library.
     3  //
     4  // The klaytn library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The klaytn library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the klaytn library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package statedb
    18  
    19  import (
    20  	"time"
    21  
    22  	"github.com/VictoriaMetrics/fastcache"
    23  	"github.com/alecthomas/units"
    24  	"github.com/rcrowley/go-metrics"
    25  )
    26  
    27  var (
    28  	// metrics
    29  	memcacheFastMisses                 = metrics.NewRegisteredGauge("trie/memcache/fast/misses", nil)
    30  	memcacheFastCollisions             = metrics.NewRegisteredGauge("trie/memcache/fast/collisions", nil)
    31  	memcacheFastCorruptions            = metrics.NewRegisteredGauge("trie/memcache/fast/corruptions", nil)
    32  	memcacheFastEntriesCount           = metrics.NewRegisteredGauge("trie/memcache/fast/entries", nil)
    33  	memcacheFastBytesSize              = metrics.NewRegisteredGauge("trie/memcache/fast/size", nil)
    34  	memcacheFastGetBigCalls            = metrics.NewRegisteredGauge("trie/memcache/fast/get", nil)
    35  	memcacheFastSetBigCalls            = metrics.NewRegisteredGauge("trie/memcache/fast/set", nil)
    36  	memcacheFastTooBigKeyErrors        = metrics.NewRegisteredGauge("trie/memcache/fast/error/too/bigkey", nil)
    37  	memcacheFastInvalidMetavalueErrors = metrics.NewRegisteredGauge("trie/memcache/fast/error/invalid/matal", nil)
    38  	memcacheFastInvalidValueLenErrors  = metrics.NewRegisteredGauge("trie/memcache/fast/error/invalid/valuelen", nil)
    39  	memcacheFastInvalidValueHashErrors = metrics.NewRegisteredGauge("trie/memcache/fast/error/invalid/hash", nil)
    40  )
    41  
    42  type FastCache struct {
    43  	fast *fastcache.Cache
    44  }
    45  
    46  // newFastCache creates a FastCache with given cache size.
    47  // If you want auto-scaled cache size, set config.LocalCacheSizeMiB to AutoScaling.
    48  // It returns nil if the cache size is zero.
    49  func newFastCache(config *TrieNodeCacheConfig) TrieNodeCache {
    50  	if config.LocalCacheSizeMiB == AutoScaling {
    51  		config.LocalCacheSizeMiB = getTrieNodeCacheSizeMiB()
    52  	}
    53  
    54  	if config.LocalCacheSizeMiB <= 0 {
    55  		return nil
    56  	}
    57  
    58  	logger.Info("Initializing local trie node cache (fastCache)",
    59  		"MaxMiB", config.LocalCacheSizeMiB, "FilePath", config.FastCacheFileDir)
    60  
    61  	start := time.Now()
    62  	fc := &FastCache{fast: fastcache.LoadFromFileOrNew(config.FastCacheFileDir, config.LocalCacheSizeMiB*int(units.MiB))}
    63  	stats := fc.UpdateStats().(fastcache.Stats)
    64  
    65  	logger.Info("Initialized local trie node cache (fastCache)",
    66  		"LoadedMiB", stats.BytesSize/uint64(units.MiB), "LoadedEntries", stats.EntriesCount, "elapsed", time.Since(start))
    67  
    68  	return fc
    69  }
    70  
    71  func (cache *FastCache) Get(k []byte) []byte {
    72  	return cache.fast.Get(nil, k)
    73  }
    74  
    75  func (cache *FastCache) Set(k, v []byte) {
    76  	cache.fast.Set(k, v)
    77  }
    78  
    79  func (cache *FastCache) Has(k []byte) ([]byte, bool) {
    80  	return cache.fast.HasGet(nil, k)
    81  }
    82  
    83  func (cache *FastCache) UpdateStats() interface{} {
    84  	var stats fastcache.Stats
    85  	cache.fast.UpdateStats(&stats)
    86  
    87  	memcacheFastMisses.Update(int64(stats.Misses))
    88  	memcacheFastCollisions.Update(int64(stats.Collisions))
    89  	memcacheFastCorruptions.Update(int64(stats.Corruptions))
    90  	memcacheFastEntriesCount.Update(int64(stats.EntriesCount))
    91  	memcacheFastBytesSize.Update(int64(stats.BytesSize))
    92  	memcacheFastGetBigCalls.Update(int64(stats.GetBigCalls))
    93  	memcacheFastSetBigCalls.Update(int64(stats.SetBigCalls))
    94  	memcacheFastTooBigKeyErrors.Update(int64(stats.TooBigKeyErrors))
    95  	memcacheFastInvalidMetavalueErrors.Update(int64(stats.InvalidMetavalueErrors))
    96  	memcacheFastInvalidValueLenErrors.Update(int64(stats.InvalidValueLenErrors))
    97  	memcacheFastInvalidValueHashErrors.Update(int64(stats.InvalidValueHashErrors))
    98  
    99  	return stats
   100  }
   101  
   102  func (cache *FastCache) SaveToFile(filePath string, concurrency int) error {
   103  	return cache.fast.SaveToFileConcurrent(filePath, concurrency)
   104  }
   105  
   106  func (cache *FastCache) Close() error {
   107  	return nil
   108  }