Go實踐:用Sync.Map實現簡易記憶體快取系統

轻荇發表於2024-04-14

介紹

定義了一個Cache結構體,其中使用sync.Map作為底層資料結構來儲存快取項。Set方法用於設定快取項,指定鍵、值以及過期時間。Get方法用於獲取快取項,如果快取項存在且未過期,則返回值和true,否則返回nil和false。方法的接受者為指標型別,是為了對Cache物件進行操作,並在方法內部訪問和修改物件的資料。
在main函式中,建立了一個Cache例項,並設定了兩個快取項。然後,我們嘗試獲取一個存在的快取項,並在控制檯上列印值。接著,我們等待6秒,再次嘗試獲取同一個快取項,這次應該返回Key not found,因為該快取項已過期。

程式碼

GoPratice/memcache/v0/simple.go at main · honlu/GoPratice

package main

import (
	"fmt"
	"sync"
	"time"
)

type Cache struct {
	data sync.Map
}

type cacheItem struct {
	value   interface{} // 值
	expired time.Time   // 過期時間
}

// Set 指標型別的方法接受者,才可以保證在方法內部訪問和修改物件的資料。
func (c *Cache) Set(key string, value interface{}, duration time.Duration) {
	c.data.Store(key, cacheItem{
		value:   value,
		expired: time.Now().Add(duration),
	})
}

func (c *Cache) Get(key string) (interface{}, bool) {
	item, ok := c.data.Load(key)
	if !ok {
		return nil, false
	}

	cacheItem := item.(cacheItem)
	if time.Now().After(cacheItem.expired) { // 判斷是否過期
		c.data.Delete(key)
		return nil, false
	}

	return cacheItem.value, true
}

func main() {
	cache := &Cache{}

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

	value1, found1 := cache.Get("key1")
	if found1 {
		fmt.Printf("Value1:%v\n", value1)
	} else {
		fmt.Printf("Key1 not found\n")
	}

	value2, found2 := cache.Get("key2")
	if found2 {
		fmt.Printf("Value2:%v\n", value2)
	} else {
		fmt.Printf("Key2 not found\n")
	}

	time.Sleep(6 * time.Second)

	value1, found1 = cache.Get("key1")
	if found1 {
		fmt.Printf("Value1:%v\n", value1)
	} else {
		fmt.Printf("Key1 not found\n")
	}
	value2, found2 = cache.Get("key2")
	if found2 {
		fmt.Printf("Value2:%v\n", value2)
	} else {
		fmt.Printf("Key2 not found\n")
	}
}

後續

可以考慮具體需求進行擴充套件和最佳化,例如新增快取淘汰策略、高併發等。

備註:

內容首發在個人知乎文章, 原始碼在Github.

相關文章