github.com/TeaOSLab/EdgeNode@v1.3.8/internal/firewalls/nftables/expration.go (about)

     1  // Copyright 2023 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
     2  
     3  package nftables
     4  
     5  import (
     6  	"sync"
     7  	"time"
     8  )
     9  
    10  type Expiration struct {
    11  	m map[string]time.Time // key => expires time
    12  
    13  	lastGCAt int64
    14  
    15  	locker sync.RWMutex
    16  }
    17  
    18  func NewExpiration() *Expiration {
    19  	return &Expiration{
    20  		m: map[string]time.Time{},
    21  	}
    22  }
    23  
    24  func (this *Expiration) AddUnsafe(key []byte, expires time.Time) {
    25  	this.m[string(key)] = expires
    26  }
    27  
    28  func (this *Expiration) Add(key []byte, expires time.Time) {
    29  	this.locker.Lock()
    30  	this.m[string(key)] = expires
    31  	this.gc()
    32  	this.locker.Unlock()
    33  }
    34  
    35  func (this *Expiration) Remove(key []byte) {
    36  	this.locker.Lock()
    37  	delete(this.m, string(key))
    38  	this.locker.Unlock()
    39  }
    40  
    41  func (this *Expiration) Contains(key []byte) bool {
    42  	this.locker.RLock()
    43  	expires, ok := this.m[string(key)]
    44  	if ok && expires.Year() > 2000 && time.Now().After(expires) {
    45  		ok = false
    46  	}
    47  	this.locker.RUnlock()
    48  	return ok
    49  }
    50  
    51  func (this *Expiration) gc() {
    52  	// we won't gc too frequently
    53  	var currentTime = time.Now().Unix()
    54  	if this.lastGCAt >= currentTime {
    55  		return
    56  	}
    57  	this.lastGCAt = currentTime
    58  
    59  	var now = time.Now().Add(-10 * time.Second) // gc elements expired before 10 seconds ago
    60  	for key, expires := range this.m {
    61  		if expires.Year() > 2000 && now.After(expires) {
    62  			delete(this.m, key)
    63  		}
    64  	}
    65  }