這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
學習開源緩衝庫,cache2g0是作為Go新手來說,比較容易上手的library。
Cache2go
Concurrency-safe golang caching library with expiration capabilities.
cache2g0是一個key-value格式的保證並發安全並帶有到期控制的緩衝庫。
你如何來設計一個緩衝庫呢?
最方便的方式: key-value形式。類似redis那樣,我先畫一張表,然後在表中存放n個key-value。
cache_design.png
Cache2go的實現就是這個實現原理,在基礎上添加了安全性和到期控制等功能。
部分Cache2go源碼解讀
先讓我們來看看Cache2go中有關的結構體:CacheTable,CacheItem
//CacheTabletype CacheTable struct { sync.RWMutex // 互斥鎖 name string // 表名 items map[interface{}]*CacheItem // item的集合 cleanupTimer *time.Timer // 設定清理時間(處於等待狀態) cleanupInterval time.Duration // 設定清理時間段 logger *log.Logger // 設定日誌 loadData func(key interface{}, args ...interface{}) *CacheItem addedItem func(item *CacheItem) aboutToDeleteItem func(item *CacheItem)}//CacheItemtype CacheItem struct { sync.RWMutex // 互斥鎖 key interface{} // data-key data interface{} // data-value lifeSpan time.Duration // 生命週期 createdOn time.Time // 建立時間 accessedOn time.Time // 最後訪問時間 accessCount int64 // 訪問次數 aboutToExpire func(key interface{}) // TODO}
為了保證其並發安全性,都帶有sync.RWMutex,維持操作的原子性。並帶有時間戳記來實現到期控制。至於那些回呼函數,我也是第一次看見這種寫法。
Cache2go的作者們,根據這兩個struct分別開放了許多getter&setter方法,使用者只需調用即可,代碼實現過程中也有對使用者是否設定過屬性進行判斷,來確保程式的健壯性。
舉個例子:
CacheTable中包含logger欄位,並且編寫了SetLogger(logger)來讓使用者實現logger列印,並實現了log(v...)方法,讓使用者可選實現SetLogger(logger),如果使用者不想列印日誌,那麼不需要調用SetLogger(logger)。
func (table *CacheTable) log(v ...interface{}) { if table.logger == nil { return } table.logger.Println(v)}
建立表並添加Item
通過建立一個緩衝表並添加緩衝Item來剖析源碼,實現代碼如下:
// new Cache cache := cache2go.Cache("myCache") // set logger logger := log.New(os.Stdout, "DEBUG", log.Ltime) cache.SetLogger(logger) // will storage data val := myStruct{"This is a test!", []byte{}} // Add Item : key, duration, stor_data cache.Add("someKey", 5*time.Second, &val)
建立一個表
Cache2go中調用Cache(tableName)方法來實現建立,內部使用map來實現的,先通過tableName關鍵字在map中尋找,如果存在則直接返回,否則先出建立,之後返回。
Cache
向表中添加CacheItem
- 通過調用
NewCacheItem(key, lifeSpan, value)來完成CacheItem的初始化
- 接下裡需要添加將CacheItem添加到CacheTable中
- CacheTable的對象通過調用自身的
addInternal(cacheItem)完成添加,並檢查是否有到期的緩衝
- 在
addInternal(cacheItem)中調用自身的expiraionCheck()來完成檢查.
add.png
這裡只是代碼簡單描述了下,主要掌握其設計思想就好啦。詳情還請移步cache2g0
需要擴充的知識點(後續更新...)
- struct中的回呼函數
- sync.RWMutex源碼的解讀
- time源碼的解讀
精彩文章,持續更新,請關注公眾號:
帥哥美女掃一掃