1 Star 0 Fork 0

BUPT-ZKJC / fabric

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
cache.go 4.33 KB
一键复制 编辑 原始数据 按行查看 历史
MJL 提交于 2021-08-06 18:37 . first commit
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package statecouchdb
import (
"github.com/VictoriaMetrics/fastcache"
"github.com/golang/protobuf/proto"
)
var (
keySep = []byte{0x00}
)
// cache holds both the system and user cache
type cache struct {
sysCache *fastcache.Cache
usrCache *fastcache.Cache
sysNamespaces []string
}
// newCache creates a Cache. The cache consists of both system state cache (for lscc, _lifecycle)
// and user state cache (for all user deployed chaincodes). The size of the
// system state cache is 64 MB, by default. The size of the user state cache, in terms of MB, is
// specified via usrCacheSize parameter. Note that the maximum memory consumption of fastcache
// would be in the multiples of 32 MB (due to 512 buckets & an equal number of 64 KB chunks per bucket).
// If the usrCacheSizeMBs is not a multiple of 32 MB, the fastcache would round the size
// to the next multiple of 32 MB.
func newCache(usrCacheSizeMBs int, sysNamespaces []string) *cache {
cache := &cache{}
// By default, 64 MB is allocated for the system cache
cache.sysCache = fastcache.New(64 * 1024 * 1024)
cache.sysNamespaces = sysNamespaces
// User passed size is used to allocate memory for the user cache
if usrCacheSizeMBs <= 0 {
return cache
}
cache.usrCache = fastcache.New(usrCacheSizeMBs * 1024 * 1024)
return cache
}
// enabled returns true if the cache is enabled for a given namespace.
// Namespace can be of two types: system namespace (such as lscc) and user
// namespace (all user's chaincode states).
func (c *cache) enabled(namespace string) bool {
for _, ns := range c.sysNamespaces {
if namespace == ns {
return true
}
}
return c.usrCache != nil
}
// getState returns the value for a given namespace and key from
// a cache associated with the chainID.
func (c *cache) getState(chainID, namespace, key string) (*CacheValue, error) {
cache := c.getCache(namespace)
if cache == nil {
return nil, nil
}
cacheKey := constructCacheKey(chainID, namespace, key)
if !cache.Has(cacheKey) {
return nil, nil
}
cacheValue := &CacheValue{}
valBytes := cache.Get(nil, cacheKey)
if err := proto.Unmarshal(valBytes, cacheValue); err != nil {
return nil, err
}
return cacheValue, nil
}
// PutState stores a given value in a cache associated with the chainID.
func (c *cache) putState(chainID, namespace, key string, cacheValue *CacheValue) error {
cache := c.getCache(namespace)
if cache == nil {
return nil
}
cacheKey := constructCacheKey(chainID, namespace, key)
valBytes, err := proto.Marshal(cacheValue)
if err != nil {
return err
}
if cache.Has(cacheKey) {
cache.Del(cacheKey)
}
cache.Set(cacheKey, valBytes)
return nil
}
// CacheUpdates is a map from a namespace to a set of cache KV updates
type cacheUpdates map[string]cacheKVs
// CacheKVs is a map from a key to a cache value
type cacheKVs map[string]*CacheValue
// Add adds the given cacheKVs to the CacheUpdates
func (u cacheUpdates) add(namespace string, ckvs cacheKVs) {
nsu, ok := u[namespace]
if !ok {
nsu = cacheKVs{}
u[namespace] = nsu
}
for k, v := range ckvs {
nsu[k] = v
}
}
// UpdateStates updates only the existing entries in the cache associated with
// the chainID.
func (c *cache) UpdateStates(chainID string, updates cacheUpdates) error {
for ns, kvs := range updates {
cache := c.getCache(ns)
if cache == nil {
continue
}
for key, newVal := range kvs {
cacheKey := constructCacheKey(chainID, ns, key)
if newVal == nil {
cache.Del(cacheKey)
continue
}
if cache.Has(cacheKey) {
newValBytes, err := proto.Marshal(newVal)
if err != nil {
return err
}
cache.Del(cacheKey)
cache.Set(cacheKey, newValBytes)
}
}
}
return nil
}
// Reset removes all the items from the cache.
func (c *cache) Reset() {
c.sysCache.Reset()
if c.usrCache != nil {
c.usrCache.Reset()
}
}
func (c *cache) getCache(namespace string) *fastcache.Cache {
for _, ns := range c.sysNamespaces {
if namespace == ns {
return c.sysCache
}
}
return c.usrCache
}
func constructCacheKey(chainID, namespace, key string) []byte {
var cacheKey []byte
cacheKey = append(cacheKey, []byte(chainID)...)
cacheKey = append(cacheKey, keySep...)
cacheKey = append(cacheKey, []byte(namespace)...)
cacheKey = append(cacheKey, keySep...)
return append(cacheKey, []byte(key)...)
}
1
https://gitee.com/bupt-zkjc/fabric.git
git@gitee.com:bupt-zkjc/fabric.git
bupt-zkjc
fabric
fabric
98d302355562

搜索帮助