github.com/chain5j/chain5j-pkg@v1.0.7/collection/lookup/lookup.go (about)

     1  // Package lookup
     2  //
     3  // @author: xwc1125
     4  package lookup
     5  
     6  import (
     7  	"sync"
     8  	"time"
     9  
    10  	"github.com/allegro/bigcache/v2"
    11  )
    12  
    13  type Lookup struct {
    14  	mu         sync.RWMutex
    15  	cache      *bigcache.BigCache
    16  	allKeyList map[string]struct{}
    17  }
    18  
    19  func NewLookup(txConfig *PoolConfig, OnRemoveWithReason func(key string, entry []byte, reason bigcache.RemoveReason)) *Lookup {
    20  	cache, _ := bigcache.NewBigCache(getCacheConfig(txConfig, OnRemoveWithReason))
    21  	return &Lookup{
    22  		cache:      cache,
    23  		allKeyList: map[string]struct{}{},
    24  	}
    25  }
    26  
    27  func getCacheConfig(txConfig *PoolConfig, OnRemoveWithReason func(key string, entry []byte, reason bigcache.RemoveReason)) bigcache.Config {
    28  	// bigcache.DefaultConfig(10 * time.Minute)
    29  	config := bigcache.Config{
    30  		// number of shards (must be a power of 2)
    31  		Shards: 16384,
    32  
    33  		// time after which entry can be evicted
    34  		LifeWindow: txConfig.TxLifeTime * time.Minute, // 过期时间,10分钟后,自动删除
    35  
    36  		// Interval between removing expired entries (clean up).
    37  		// If set to <= 0 then no action is performed.
    38  		// Setting to < 1 second is counterproductive — bigcache has a one second resolution.
    39  		// CleanWindow: 5 * time.Minute,
    40  		CleanWindow: txConfig.TxTaskTime * time.Second,
    41  
    42  		// rps * lifeWindow, used only in initial memory allocation
    43  		MaxEntriesInWindow: 1000 * 10 * 60,
    44  
    45  		// max entry size in bytes, used only in initial memory allocation
    46  		MaxEntrySize: 1024,
    47  
    48  		// prints information about additional memory allocation
    49  		Verbose: true,
    50  
    51  		// cache will not allocate more memory than this limit, value in MB
    52  		// if value is reached then the oldest entries can be overridden for the new ones
    53  		// 0 value means no size limit
    54  		HardMaxCacheSize: 8192,
    55  
    56  		// callback fired when the oldest entry is removed because of its expiration time or no space left
    57  		// for the new entry, or because delete was called. A bitmask representing the reason will be returned.
    58  		// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
    59  		OnRemove: nil,
    60  
    61  		// OnRemoveWithReason is a callback fired when the oldest entry is removed because of its expiration time or no space left
    62  		// for the new entry, or because delete was called. A constant representing the reason will be passed through.
    63  		// Default value is nil which means no callback and it prevents from unwrapping the oldest entry.
    64  		// Ignored if OnRemove is specified.
    65  		OnRemoveWithReason: OnRemoveWithReason,
    66  	}
    67  	return config
    68  }
    69  
    70  func (tl *Lookup) Len() uint64 {
    71  	tl.mu.RLock()
    72  	defer tl.mu.RUnlock()
    73  	return uint64(len(tl.allKeyList))
    74  }
    75  
    76  func (tl *Lookup) Exist(hash string) bool {
    77  	// tl.mu.RLock()
    78  	// defer tl.mu.RUnlock()
    79  	_, err := tl.cache.Get(hash)
    80  	if err != nil {
    81  		return false
    82  	}
    83  	return true
    84  }
    85  func (tl *Lookup) Get(hash string) ([]byte, error) {
    86  	// tl.mu.RLock()
    87  	// defer tl.mu.RUnlock()
    88  	return tl.cache.Get(hash)
    89  }
    90  
    91  // 添加hash==> 节点peer
    92  func (tl *Lookup) Add(hash string, data []byte) {
    93  	tl.mu.Lock()
    94  	tl.allKeyList[hash] = struct{}{}
    95  	tl.mu.Unlock()
    96  	tl.cache.Set(hash, data)
    97  }
    98  
    99  func (tl *Lookup) Del(hash string) {
   100  	flag := false
   101  	tl.mu.Lock()
   102  	if _, ok := tl.allKeyList[hash]; ok {
   103  		flag = ok
   104  	}
   105  	if flag {
   106  		delete(tl.allKeyList, hash)
   107  	}
   108  	tl.mu.Unlock()
   109  	if flag {
   110  		tl.cache.Delete(hash)
   111  	}
   112  }
   113  
   114  func (tl *Lookup) GetAllKeys() []string {
   115  	tl.mu.RLock()
   116  	defer tl.mu.RUnlock()
   117  	var allKey []string
   118  	for k, _ := range tl.allKeyList {
   119  		allKey = append(allKey, k)
   120  	}
   121  	return allKey
   122  }