package main
import ( <font>"fmt" "sync" "time" )
// CacheItem represents an individual item in the cache<i> type CacheItem struct { Value interface{} Expiration int64 // Unix timestamp for expiration<i> }
//SieveCache 表示篩選快取<i> type SieveCache struct { store sync.Map ttl time.Duration sieveFilter func(key string, value interface{}) bool //自定義過濾邏輯<i> cleanupTicker *time.Ticker stopCleanup chan struct{} }
// NewSieveCache 建立 SieveCache 的新例項<i> func NewSieveCache(ttl time.Duration, sieveFilter func(key string, value interface{}) bool) *SieveCache { cache := &SieveCache{ ttl: ttl, sieveFilter: sieveFilter, stopCleanup: make(chan struct{}), } cache.cleanupTicker = time.NewTicker(ttl / 2) // Cleanup runs at half the TTL interval<i> go cache.cleanupExpiredItems() return cache }
// 如果透過了篩選過濾器,則 Set 將新專案新增到快取中<i> func (c *SieveCache) Set(key string, value interface{}) { if c.sieveFilter(key, value) { c.store.Store(key, CacheItem{ Value: value, Expiration: time.Now().Add(c.ttl).Unix(), }) } }
// Get retrieves an item from the cache if it exists and is not expired<i> func (c *SieveCache) Get(key string) (interface{}, bool) { item, exists := c.store.Load(key) if !exists { return nil, false }
cacheItem := item.(CacheItem) if time.Now().Unix() > cacheItem.Expiration { c.store.Delete(key) return nil, false } return cacheItem.Value, true }
// Delete removes an item from the cache<i> func (c *SieveCache) Delete(key string) { c.store.Delete(key) }
//cleanupExpiredItems 定期從快取中刪除過期專案<i> func (c *SieveCache) cleanupExpiredItems() { for { select { case <-c.cleanupTicker.C: c.store.Range(func(key, value interface{}) bool { cacheItem := value.(CacheItem) if time.Now().Unix() > cacheItem.Expiration { c.store.Delete(key) } return true }) case <-c.stopCleanup: return } } }
// Stop stops the cleanup goroutine<i> func (c *SieveCache) Stop() { close(c.stopCleanup) c.cleanupTicker.Stop() }
func main() { // 自定義篩選過濾器:僅快取長度 > 3 的字串<i> filter := func(key string, value interface{}) bool { str, ok := value.(string) return ok && len(str) > 3 }
// 建立一個具有 10 秒 TTL 的篩選快取 cache<i> cache := NewSieveCache(10*time.Second, filter) defer cache.Stop()
// Add items to the cache<i> cache.Set("key1", "short") // Won't be cached (length <= 3)<i> cache.Set("key2", "longerString") // Will be cached<i>
// Retrieve items from the cache<i> if value, ok := cache.Get("key2"); ok { fmt.Println("Found key2:", value) } else { fmt.Println("key2 not found") }
// 等待 11 秒測試過期<i> time.Sleep(11 * time.Second) if _, ok := cache.Get("key2"); !ok { fmt.Println("key2 expired") } }
|