github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/replay/cuckoo.go (about)

     1  package replay
     2  
     3  /*
     4  import (
     5  	"sync"
     6  	"time"
     7  
     8  	"github.com/seiflotfy/cuckoofilter"
     9  )
    10  
    11  const defaultCapacity = 100000
    12  
    13  func NewCuckoo(interval time.Duration) *CuckooFilter {
    14  	return &CuckooFilter{
    15  		poolA:    cuckoo.NewFilter(defaultCapacity),
    16  		poolB:    cuckoo.NewFilter(defaultCapacity),
    17  		lastSwap: time.Now(),
    18  		interval: interval,
    19  	}
    20  }
    21  
    22  type CuckooFilter struct {
    23  	access   sync.Mutex
    24  	poolA    *cuckoo.Filter
    25  	poolB    *cuckoo.Filter
    26  	poolSwap bool
    27  	lastSwap time.Time
    28  	interval time.Duration
    29  }
    30  
    31  func (f *CuckooFilter) Check(sum []byte) bool {
    32  	f.access.Lock()
    33  	defer f.access.Unlock()
    34  
    35  	now := time.Now()
    36  
    37  	elapsed := now.Sub(f.lastSwap)
    38  	if elapsed >= f.interval {
    39  		if f.poolSwap {
    40  			f.poolA.Reset()
    41  		} else {
    42  			f.poolB.Reset()
    43  		}
    44  		f.poolSwap = !f.poolSwap
    45  		f.lastSwap = now
    46  	}
    47  
    48  	return f.poolA.InsertUnique(sum) && f.poolB.InsertUnique(sum)
    49  }
    50  */