github.com/turingchain2020/turingchain@v1.1.21/p2p/utils/filterrepeatdata.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package utils 6 7 import ( 8 "sync" 9 "sync/atomic" 10 "time" 11 12 log "github.com/turingchain2020/turingchain/common/log/log15" 13 14 "github.com/turingchain2020/turingchain/types" 15 lru "github.com/hashicorp/golang-lru" 16 ) 17 18 // NewFilter produce a filter object 19 func NewFilter(num int) *Filterdata { 20 filter := new(Filterdata) 21 var err error 22 filter.regRData, err = lru.New(num) 23 if err != nil { 24 panic(err) 25 } 26 return filter 27 } 28 29 // Filterdata filter data attribute 30 type Filterdata struct { 31 isclose int32 32 regRData *lru.Cache 33 atomicLock sync.Mutex 34 } 35 36 // GetAtomicLock get lock 37 func (f *Filterdata) GetAtomicLock() { 38 f.atomicLock.Lock() 39 } 40 41 // ReleaseAtomicLock release lock 42 func (f *Filterdata) ReleaseAtomicLock() { 43 f.atomicLock.Unlock() 44 } 45 46 // Contains query receive data by key 47 func (f *Filterdata) Contains(key string) bool { 48 ok := f.regRData.Contains(key) 49 return ok 50 51 } 52 53 // Remove remove receive data by key 54 func (f *Filterdata) Remove(key string) { 55 f.regRData.Remove(key) 56 } 57 58 // Close the filter object 59 func (f *Filterdata) Close() { 60 atomic.StoreInt32(&f.isclose, 1) 61 } 62 63 func (f *Filterdata) isClose() bool { 64 return atomic.LoadInt32(&f.isclose) == 1 65 } 66 67 // ManageRecvFilter manager receive filter 68 func (f *Filterdata) ManageRecvFilter(tickTime time.Duration) { 69 ticker := time.NewTicker(tickTime) 70 var timeout int64 = 60 71 defer ticker.Stop() 72 for { 73 <-ticker.C 74 now := types.Now().Unix() 75 for _, key := range f.regRData.Keys() { 76 regtime, exist := f.regRData.Get(key) 77 if !exist { 78 log.Warn("Not found in regRData", "Key", key) 79 continue 80 } 81 if now-regtime.(int64) < timeout { 82 break 83 } 84 f.regRData.Remove(key) 85 } 86 87 if f.isClose() { 88 return 89 } 90 } 91 } 92 93 // Add add val 94 func (f *Filterdata) Add(key string, val interface{}) bool { 95 96 return f.regRData.Add(key, val) 97 } 98 99 // Get get val 100 func (f *Filterdata) Get(key string) (interface{}, bool) { 101 val, ok := f.regRData.Get(key) 102 return val, ok 103 } 104 105 //AddWithCheckAtomic add key if key not exist with atomic lock, return true if exist 106 func (f *Filterdata) AddWithCheckAtomic(key string, val interface{}) (exist bool) { 107 108 f.GetAtomicLock() 109 defer f.ReleaseAtomicLock() 110 if f.Contains(key) { 111 return true 112 } 113 f.Add(key, val) 114 return false 115 }