go開源專案學習--cache2go
阿新 • • 發佈:2019-01-01
地址:https://github.com/muesli/cache2go
主要特點:
1、併發安全,使用RWMutex鎖來保證併發執行
2、可設定過期時間,過期自動刪除
3、可設定操作的回撥函式,如增加、刪除時的回撥函式
主要結構和關係為:
cache:map型別,快取器,根據設定的快取資料名稱來存取相應的快取表CacheTable
CacheTable:快取表,儲存一類資料的快取結構,結構裡的map維護了一個key到快取項的對映,定義如下:
type CacheTable struct { sync.RWMutex //鎖,為了併發安全 name string //表名 items map[interface{}]*CacheItem //快取專案 cleanupTimer *time.Timer //定時器,檢查快取項是否超時 cleanupInterval time.Duration //下次檢查超時的時間間隔 logger *log.Logger //輸出使用的logger //訪問一個不存在的項時,會呼叫此函式生成新資料專案, 呼叫SetDataLoader進行設定 loadData func(key interface{}, args ...interface{}) *CacheItem addedItem func(item *CacheItem) //增加新快取項時呼叫此函式,呼叫SetAddedItemCallback進行設定 aboutToDeleteItem func(item *CacheItem) //刪除快取項時呼叫此函式,呼叫SetAboutToDeleteItemCallback進行設定 }
CacheItem:快取項,儲存資料的結構,定義如下:
type CacheItem struct { sync.RWMutex //讀寫鎖 key interface{} //快取項的key data interface{} //快取項的value lifeSpan time.Duration //資料的過期時間,為0則不過期 createdOn time.Time //資料的加入時間 accessedOn time.Time //上次訪問時間,根據此值和lifeSpan判斷是否過期 accessCount int64 //訪問次數統計 aboutToExpire func(key interface{}) //超時回撥函式 }
以下是自己測試寫的例子,測試了Foreach、SetDataLoader、SetLogger和超時處理:
package main import ( "fmt" "log" "os" "time" "github.com/muesli/cache2go" ) type student struct { id int name string age int score int } func main() { cache := cache2go.Cache("studentInfo") jack := &student{1, "jack", 12, 90} tom := &student{2, "tom", 13, 65} tony := &student{3, "tony", 12, 80} saveTime := 5 * time.Second cache.Add(1, saveTime, jack) cache.Add(2, saveTime, tom) cache.Add(3, saveTime, tony) fmt.Println("students num:", cache.Count()) printFunc := func(key interface{}, stu *cache2go.CacheItem) { fmt.Println(key, stu.Data()) } cache.Foreach(printFunc) loadFunc := func(key interface{}, args ...interface{}) *cache2go.CacheItem { ftmp := &student{key.(int), "", 0, 0} item := cache2go.NewCacheItem(key, 0, ftmp) return item } cache.SetDataLoader(loadFunc) tmp, ok := cache.Value(4) if ok == nil { fmt.Println(tmp.Data()) } logFile, err := os.Create("./log.txt") if err != nil { fmt.Println(err) } defer logFile.Close() logger := log.New(logFile, "mytest_", log.Ldate|log.Ltime|log.Lshortfile) logger.Println("this is test line") cache.SetLogger(logger) time.Sleep(7 * time.Second) }
輸出結果:
students num: 3
1 &{1 jack 12 90}
2 &{2 tom 13 65}
3 &{3 tony 12 80}
&{4 0 0}
日誌列印結果:
mytest_2018/12/31 09:52:51 mytest.go:51: this is test line
mytest_2018/12/31 09:52:56 cachetable.go:330: Expiration check triggered after 5s for table studentInfo
mytest_2018/12/31 09:52:56 cachetable.go:330: Deleting item with key 1 created on 2018-12-31 09:52:51.7731682 +0800 CST m=+0.014991301 and hit 0 times from table studentInfo
mytest_2018/12/31 09:52:56 cachetable.go:330: Deleting item with key 2 created on 2018-12-31 09:52:51.7731682 +0800 CST m=+0.014991301 and hit 0 times from table studentInfo
mytest_2018/12/31 09:52:56 cachetable.go:330: Deleting item with key 3 created on 2018-12-31 09:52:51.7731682 +0800 CST m=+0.014991301 and hit 0 times from table studentInfo