溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

高效Go緩存:HashMap與緩存數(shù)據(jù)過期自動(dòng)清理

發(fā)布時(shí)間:2024-11-09 00:25:37 來源:億速云 閱讀:81 作者:小樊 欄目:編程語言

在Go語言中,實(shí)現(xiàn)高效的緩存系統(tǒng)通常需要考慮以下幾個(gè)方面:

  1. 緩存存儲(chǔ):可以使用map來實(shí)現(xiàn)簡單的鍵值對存儲(chǔ)。
  2. 緩存過期:需要一種機(jī)制來自動(dòng)清理過期的緩存數(shù)據(jù)。
  3. 并發(fā)安全:在高并發(fā)環(huán)境下,需要確保緩存的讀寫操作是線程安全的。

下面是一個(gè)簡單的示例,展示了如何使用map來實(shí)現(xiàn)一個(gè)帶有過期功能的緩存系統(tǒng):

package main

import (
	"container/list"
	"fmt"
	"sync"
	"time"
)

// CacheItem 表示緩存項(xiàng)
type CacheItem struct {
	key         string
	value       interface{}
	expiration time.Time
}

// LRUCache 是一個(gè)簡單的LRU緩存實(shí)現(xiàn)
type LRUCache struct {
	capacity int
	cache    map[string]*list.Element
	evictList *list.List
	mu        sync.Mutex
}

// NewLRUCache 創(chuàng)建一個(gè)新的LRU緩存
func NewLRUCache(capacity int) *LRUCache {
	return &LRUCache{
		capacity: capacity,
		cache:    make(map[string]*list.Element),
		evictList: list.New(),
	}
}

// Add 添加一個(gè)新的緩存項(xiàng)
func (c *LRUCache) Add(key string, value interface{}, ttl time.Duration) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if elem, exists := c.cache[key]; exists {
		c.evictList.MoveToFront(elem)
		elem.Value.(*CacheItem).value = value
		elem.Value.(*CacheItem).expiration = time.Now().Add(ttl)
		return
	}

	if c.evictList.Len() >= c.capacity {
		lastElem := c.evictList.Back()
		delete(c.cache, lastElem.Value.(*CacheItem).key)
		c.evictList.Remove(lastElem)
	}

	item := &CacheItem{
		key:         key,
		value:       value,
		expiration: time.Now().Add(ttl),
	}

	elem := c.evictList.PushFront(item)
	c.cache[key] = elem
}

// Get 獲取緩存項(xiàng),如果不存在則返回nil
func (c *LRUCache) Get(key string) interface{} {
	c.mu.Lock()
	defer c.mu.Unlock()

	if elem, exists := c.cache[key]; exists {
		item := elem.Value.(*CacheItem)
		if time.Now().Before(item.expiration) {
			c.evictList.MoveToFront(elem)
			return item.value
		}
		c.removeElement(elem)
	}
	return nil
}

// removeElement 從鏈表和緩存中移除元素
func (c *LRUCache) removeElement(elem *list.Element) {
	c.evictList.Remove(elem)
	delete(c.cache, elem.Value.(*CacheItem).key)
}

func main() {
	cache := NewLRUCache(2)

	cache.Add("key1", "value1", 5*time.Second)
	cache.Add("key2", "value2", 10*time.Second)

	fmt.Println(cache.Get("key1")) // 輸出: value1

	time.Sleep(6 * time.Second)

	fmt.Println(cache.Get("key1")) // 輸出: nil,因?yàn)閗ey1已經(jīng)過期

	cache.Add("key3", "value3", 5*time.Second)

	fmt.Println(cache.Get("key2")) // 輸出: nil,因?yàn)閗ey2已經(jīng)被移除
	fmt.Println(cache.Get("key3")) // 輸出: value3
}

解釋

  1. CacheItem:表示緩存項(xiàng),包含鍵、值和過期時(shí)間。
  2. LRUCache:實(shí)現(xiàn)LRU緩存的結(jié)構(gòu)體,包含容量、緩存映射、過期列表和互斥鎖。
  3. NewLRUCache:創(chuàng)建一個(gè)新的LRU緩存實(shí)例。
  4. Add:添加一個(gè)新的緩存項(xiàng),如果緩存已滿則移除最久未使用的項(xiàng)。
  5. Get:獲取緩存項(xiàng),如果存在且未過期則返回值,否則返回nil。
  6. removeElement:從鏈表和緩存中移除元素。

這個(gè)示例展示了如何使用map和雙向鏈表來實(shí)現(xiàn)一個(gè)簡單的LRU緩存,并且具備自動(dòng)清理過期數(shù)據(jù)的能力。在高并發(fā)環(huán)境下,可以考慮使用sync.RWMutex來進(jìn)一步優(yōu)化讀寫性能。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

go
AI