mirror of
https://gitlab.com/pulsechaincom/prysm-pulse.git
synced 2025-01-06 01:32:18 +00:00
106 lines
3.1 KiB
Go
106 lines
3.1 KiB
Go
package cache
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"sync"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
"github.com/prysmaticlabs/prysm/shared/featureconfig"
|
|
"github.com/prysmaticlabs/prysm/shared/params"
|
|
"k8s.io/client-go/tools/cache"
|
|
)
|
|
|
|
var (
|
|
// ErrNotStartShardInfo will be returned when a cache object is not a pointer to
|
|
// a StartShardByEpoch struct.
|
|
ErrNotStartShardInfo = errors.New("object is not a start shard obj")
|
|
|
|
// maxStartShardListSize defines the max number of start shard can cache.
|
|
maxStartShardListSize = int(params.BeaconConfig().ShardCount)
|
|
|
|
// Metrics.
|
|
startShardCacheMiss = promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "start_shard_cache_miss",
|
|
Help: "The number of start shard requests that aren't present in the cache.",
|
|
})
|
|
startShardCacheHit = promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "start_shard_cache_hit",
|
|
Help: "The number of start shard requests that are present in the cache.",
|
|
})
|
|
)
|
|
|
|
// StartShardByEpoch defines the start shard of the epoch.
|
|
type StartShardByEpoch struct {
|
|
Epoch uint64
|
|
StartShard uint64
|
|
}
|
|
|
|
// StartShardCache is a struct with 1 queue for looking up start shard by epoch.
|
|
type StartShardCache struct {
|
|
startShardCache *cache.FIFO
|
|
lock sync.RWMutex
|
|
}
|
|
|
|
// startShardKeyFn takes the epoch as the key for the start shard of a given epoch.
|
|
func startShardKeyFn(obj interface{}) (string, error) {
|
|
sInfo, ok := obj.(*StartShardByEpoch)
|
|
if !ok {
|
|
return "", ErrNotStartShardInfo
|
|
}
|
|
|
|
return strconv.Itoa(int(sInfo.Epoch)), nil
|
|
}
|
|
|
|
// NewStartShardCache creates a new start shard cache for storing/accessing start shard.
|
|
func NewStartShardCache() *StartShardCache {
|
|
return &StartShardCache{
|
|
startShardCache: cache.NewFIFO(startShardKeyFn),
|
|
}
|
|
}
|
|
|
|
// StartShardInEpoch fetches StartShardByEpoch by epoch. Returns true with a
|
|
// reference to the StartShardInEpoch info, if exists. Otherwise returns false, nil.
|
|
func (c *StartShardCache) StartShardInEpoch(epoch uint64) (uint64, error) {
|
|
if !featureconfig.FeatureConfig().EnableStartShardCache {
|
|
// Return a miss result if cache is not enabled.
|
|
startShardCacheMiss.Inc()
|
|
return params.BeaconConfig().FarFutureEpoch, nil
|
|
}
|
|
|
|
c.lock.RLock()
|
|
defer c.lock.RUnlock()
|
|
obj, exists, err := c.startShardCache.GetByKey(strconv.Itoa(int(epoch)))
|
|
if err != nil {
|
|
return params.BeaconConfig().FarFutureEpoch, err
|
|
}
|
|
|
|
if exists {
|
|
startShardCacheHit.Inc()
|
|
} else {
|
|
startShardCacheMiss.Inc()
|
|
return params.BeaconConfig().FarFutureEpoch, nil
|
|
}
|
|
|
|
sInfo, ok := obj.(*StartShardByEpoch)
|
|
if !ok {
|
|
return params.BeaconConfig().FarFutureEpoch, ErrNotStartShardInfo
|
|
}
|
|
|
|
return sInfo.StartShard, nil
|
|
}
|
|
|
|
// AddStartShard adds StartShardByEpoch object to the cache. This method also trims the least
|
|
// recently added StartShardByEpoch object if the cache size has ready the max cache size limit.
|
|
func (c *StartShardCache) AddStartShard(startShard *StartShardByEpoch) error {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
if err := c.startShardCache.AddIfNotPresent(startShard); err != nil {
|
|
return err
|
|
}
|
|
|
|
trim(c.startShardCache, maxStartShardListSize)
|
|
return nil
|
|
}
|