From 8b0929b4bc8dcf7675ac7e0a38eb97c30e9f1c86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=82=85=E5=B0=8F=E9=BB=91?= Date: Sun, 22 Dec 2013 13:35:02 +0800 Subject: [PATCH] add comments in cache package files. --- cache/cache.go | 22 +++++++++++++++++++++- cache/conv.go | 6 ++++++ cache/file.go | 42 +++++++++++++++++++++++++++++++++--------- cache/memcache.go | 15 +++++++++++++++ cache/memory.go | 20 +++++++++++++++++--- cache/redis.go | 16 ++++++++++++++++ 6 files changed, 108 insertions(+), 13 deletions(-) diff --git a/cache/cache.go b/cache/cache.go index 074d1091..244f9d38 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -4,14 +4,32 @@ import ( "fmt" ) +// Cache interface contains all behaviors for cache adapter. +// usage: +// cache.Register("file",cache.NewFileCache()) // this operation is run in init method of file.go. +// c := cache.NewCache("file","{....}") +// c.Put("key",value,3600) +// v := c.Get("key") +// +// c.Incr("counter") // now is 1 +// c.Incr("counter") // now is 2 +// count := c.Get("counter").(int) type Cache interface { + // get cached value by key. Get(key string) interface{} + // set cached value with key and expire time. Put(key string, val interface{}, timeout int64) error + // delete cached value by key. Delete(key string) error + // increase cached int value by key, as a counter. Incr(key string) error + // decrease cached int value by key, as a counter. Decr(key string) error + // check cached value is existed or not. IsExist(key string) bool + // clear all cache. ClearAll() error + // start gc routine via config string setting. StartAndGC(config string) error } @@ -30,7 +48,9 @@ func Register(name string, adapter Cache) { adapters[name] = adapter } -// config need to be correct JSON as string: {"interval":360} +// Create a new cache driver by adapter and config string. +// config need to be correct JSON as string: {"interval":360}. +// it will start gc automatically. func NewCache(adapterName, config string) (Cache, error) { adapter, ok := adapters[adapterName] if !ok { diff --git a/cache/conv.go b/cache/conv.go index ff47239f..818dc0c7 100644 --- a/cache/conv.go +++ b/cache/conv.go @@ -5,6 +5,7 @@ import ( "strconv" ) +// convert interface to string. func GetString(v interface{}) string { switch result := v.(type) { case string: @@ -20,6 +21,7 @@ func GetString(v interface{}) string { } } +// convert interface to int. func GetInt(v interface{}) int { switch result := v.(type) { case int: @@ -40,6 +42,7 @@ func GetInt(v interface{}) int { return 0 } +// convert interface to int64. func GetInt64(v interface{}) int64 { switch result := v.(type) { case int: @@ -60,6 +63,7 @@ func GetInt64(v interface{}) int64 { return 0 } +// convert interface to float64. func GetFloat64(v interface{}) float64 { switch result := v.(type) { case float64: @@ -76,6 +80,7 @@ func GetFloat64(v interface{}) float64 { return 0 } +// convert interface to bool. func GetBool(v interface{}) bool { switch result := v.(type) { case bool: @@ -92,6 +97,7 @@ func GetBool(v interface{}) bool { return false } +// convert interface to byte slice. func getByteArray(v interface{}) []byte { switch result := v.(type) { case []byte: diff --git a/cache/file.go b/cache/file.go index 4612ee16..777b2330 100644 --- a/cache/file.go +++ b/cache/file.go @@ -24,6 +24,8 @@ func init() { Register("file", NewFileCache()) } +// FileCacheItem is basic unit of file cache adapter. +// it contains data and expire time. type FileCacheItem struct { Data interface{} Lastaccess int64 @@ -31,15 +33,13 @@ type FileCacheItem struct { } var ( - FileCachePath string = "cache" - FileCacheFileSuffix string = ".bin" - FileCacheDirectoryLevel int = 2 - /** - * 默认永不过期 - */ - FileCacheEmbedExpiry int64 = 0 + FileCachePath string = "cache" // cache directory + FileCacheFileSuffix string = ".bin" // cache file suffix + FileCacheDirectoryLevel int = 2 // cache file deep level if auto generated cache files. + FileCacheEmbedExpiry int64 = 0 // cache expire time, default is no expire forever. ) +// FileCache is cache adapter for file storage. type FileCache struct { CachePath string FileSuffix string @@ -47,11 +47,14 @@ type FileCache struct { EmbedExpiry int } +// Create new file cache with default directory and suffix. +// the level and expiry need set in method StartAndGC as config string. func NewFileCache() *FileCache { - // return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix} return &FileCache{} } +// Start and begin gc for file cache. +// the config need to be like {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0} func (this *FileCache) StartAndGC(config string) error { var cfg map[string]string @@ -78,6 +81,7 @@ func (this *FileCache) StartAndGC(config string) error { return nil } +// Init will make new dir for file cache if not exist. func (this *FileCache) Init() { app := filepath.Dir(os.Args[0]) this.CachePath = filepath.Join(app, this.CachePath) @@ -93,6 +97,7 @@ func (this *FileCache) Init() { //fmt.Println(this.getCacheFileName("123456")); } +// get cached file name. it's md5 encoded. func (this *FileCache) getCacheFileName(key string) string { m := md5.New() io.WriteString(m, key) @@ -119,6 +124,8 @@ func (this *FileCache) getCacheFileName(key string) string { return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, this.FileSuffix)) } +// Get value from file cache. +// if non-exist or expired, return empty string. func (this *FileCache) Get(key string) interface{} { filename := this.getCacheFileName(key) filedata, err := File_get_contents(filename) @@ -134,6 +141,8 @@ func (this *FileCache) Get(key string) interface{} { return to.Data } +// Put value into file cache. +// timeout means how long to keep this file, unit of second. func (this *FileCache) Put(key string, val interface{}, timeout int64) error { filename := this.getCacheFileName(key) var item FileCacheItem @@ -152,6 +161,7 @@ func (this *FileCache) Put(key string, val interface{}, timeout int64) error { return err } +// Delete file cache value. func (this *FileCache) Delete(key string) error { filename := this.getCacheFileName(key) if ok, _ := exists(filename); ok { @@ -160,6 +170,8 @@ func (this *FileCache) Delete(key string) error { return nil } +// Increase cached int value. +// this value is saving forever unless Delete. func (this *FileCache) Incr(key string) error { data := this.Get(key) var incr int @@ -173,6 +185,7 @@ func (this *FileCache) Incr(key string) error { return nil } +// Decrease cached int value. func (this *FileCache) Decr(key string) error { data := this.Get(key) var decr int @@ -185,18 +198,22 @@ func (this *FileCache) Decr(key string) error { return nil } +// Check value is exist. func (this *FileCache) IsExist(key string) bool { filename := this.getCacheFileName(key) ret, _ := exists(filename) return ret } +// Clean cached files. +// not implemented. func (this *FileCache) ClearAll() error { //this.CachePath .递归删除 return nil } +// check file exist. func exists(path string) (bool, error) { _, err := os.Stat(path) if err == nil { @@ -208,7 +225,9 @@ func exists(path string) (bool, error) { return false, err } -func File_get_contents(filename string) ([]byte, error) { //文件不存在时自动创建 +// Get bytes to file. +// if non-exist, create this file. +func File_get_contents(filename string) ([]byte, error) { f, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm) if err != nil { return []byte(""), err @@ -226,6 +245,8 @@ func File_get_contents(filename string) ([]byte, error) { //文件不存在时 return []byte(""), err } +// Put bytes to file. +// if non-exist, create this file. func File_put_contents(filename string, content []byte) error { fp, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm) if err != nil { @@ -235,6 +256,8 @@ func File_put_contents(filename string, content []byte) error { _, err = fp.Write(content) return err } + +// Gob encodes file cache item. func Gob_encode(data interface{}) ([]byte, error) { buf := bytes.NewBuffer(nil) enc := gob.NewEncoder(buf) @@ -245,6 +268,7 @@ func Gob_encode(data interface{}) ([]byte, error) { return buf.Bytes(), err } +// Gob decodes file cache item. func Gob_decode(data []byte, to interface{}) error { buf := bytes.NewBuffer(data) dec := gob.NewDecoder(buf) diff --git a/cache/memcache.go b/cache/memcache.go index c0b726d0..15d3649c 100644 --- a/cache/memcache.go +++ b/cache/memcache.go @@ -7,15 +7,18 @@ import ( "github.com/beego/memcache" ) +// Memcache adapter. type MemcacheCache struct { c *memcache.Connection conninfo string } +// create new memcache adapter. func NewMemCache() *MemcacheCache { return &MemcacheCache{} } +// get value from memcache. func (rc *MemcacheCache) Get(key string) interface{} { if rc.c == nil { rc.c = rc.connectInit() @@ -33,6 +36,7 @@ func (rc *MemcacheCache) Get(key string) interface{} { return contain } +// put value to memcache. only support string. func (rc *MemcacheCache) Put(key string, val interface{}, timeout int64) error { if rc.c == nil { rc.c = rc.connectInit() @@ -48,6 +52,7 @@ func (rc *MemcacheCache) Put(key string, val interface{}, timeout int64) error { return err } +// delete value in memcache. func (rc *MemcacheCache) Delete(key string) error { if rc.c == nil { rc.c = rc.connectInit() @@ -56,14 +61,19 @@ func (rc *MemcacheCache) Delete(key string) error { return err } +// [Not Support] +// increase counter. func (rc *MemcacheCache) Incr(key string) error { return errors.New("not support in memcache") } +// [Not Support] +// decrease counter. func (rc *MemcacheCache) Decr(key string) error { return errors.New("not support in memcache") } +// check value exists in memcache. func (rc *MemcacheCache) IsExist(key string) bool { if rc.c == nil { rc.c = rc.connectInit() @@ -80,6 +90,7 @@ func (rc *MemcacheCache) IsExist(key string) bool { return true } +// clear all cached in memcache. func (rc *MemcacheCache) ClearAll() error { if rc.c == nil { rc.c = rc.connectInit() @@ -88,6 +99,9 @@ func (rc *MemcacheCache) ClearAll() error { return err } +// start memcache adapter. +// config string is like {"conn":"connection info"}. +// if connecting error, return. func (rc *MemcacheCache) StartAndGC(config string) error { var cf map[string]string json.Unmarshal([]byte(config), &cf) @@ -102,6 +116,7 @@ func (rc *MemcacheCache) StartAndGC(config string) error { return nil } +// connect to memcache and keep the connection. func (rc *MemcacheCache) connectInit() *memcache.Connection { c, err := memcache.Connect(rc.conninfo) if err != nil { diff --git a/cache/memory.go b/cache/memory.go index 65c43ddd..839fed72 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -9,28 +9,34 @@ import ( ) var ( + // clock time of recycling the expired cache items in memory. DefaultEvery int = 60 // 1 minute ) +// Memory cache item. type MemoryItem struct { val interface{} Lastaccess time.Time expired int64 } +// Memory cache adapter. +// it contains a RW locker for safe map storage. type MemoryCache struct { lock sync.RWMutex dur time.Duration items map[string]*MemoryItem - Every int // Run an expiration check Every seconds + Every int // run an expiration check Every cloc; time } -// NewDefaultCache returns a new FileCache with sane defaults. +// NewMemoryCache returns a new MemoryCache. func NewMemoryCache() *MemoryCache { cache := MemoryCache{items: make(map[string]*MemoryItem)} return &cache } +// Get cache from memory. +// if non-existed or expired, return nil. func (bc *MemoryCache) Get(name string) interface{} { bc.lock.RLock() defer bc.lock.RUnlock() @@ -45,6 +51,7 @@ func (bc *MemoryCache) Get(name string) interface{} { return itm.val } +// Put cache to memory. func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error { bc.lock.Lock() defer bc.lock.Unlock() @@ -57,6 +64,7 @@ func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error return nil } +/// Delete cache in memory. func (bc *MemoryCache) Delete(name string) error { bc.lock.Lock() defer bc.lock.Unlock() @@ -71,6 +79,8 @@ func (bc *MemoryCache) Delete(name string) error { return nil } +// Increase cache counter in memory. +// it supports int,int64,int32,uint,uint64,uint32. func (bc *MemoryCache) Incr(key string) error { bc.lock.RLock() defer bc.lock.RUnlock() @@ -97,6 +107,7 @@ func (bc *MemoryCache) Incr(key string) error { return nil } +// Decrease counter in memory. func (bc *MemoryCache) Decr(key string) error { bc.lock.RLock() defer bc.lock.RUnlock() @@ -135,6 +146,7 @@ func (bc *MemoryCache) Decr(key string) error { return nil } +// check cache exist in memory. func (bc *MemoryCache) IsExist(name string) bool { bc.lock.RLock() defer bc.lock.RUnlock() @@ -142,6 +154,7 @@ func (bc *MemoryCache) IsExist(name string) bool { return ok } +// delete all cache in memory. func (bc *MemoryCache) ClearAll() error { bc.lock.Lock() defer bc.lock.Unlock() @@ -149,7 +162,7 @@ func (bc *MemoryCache) ClearAll() error { return nil } -// Start activates the file cache; it will +// start memory cache. it will check expiration in every clock time. func (bc *MemoryCache) StartAndGC(config string) error { var cf map[string]int json.Unmarshal([]byte(config), &cf) @@ -167,6 +180,7 @@ func (bc *MemoryCache) StartAndGC(config string) error { return nil } +// check expiration. func (bc *MemoryCache) vaccuum() { if bc.Every < 1 { return diff --git a/cache/redis.go b/cache/redis.go index 27648416..b923a6df 100644 --- a/cache/redis.go +++ b/cache/redis.go @@ -8,19 +8,23 @@ import ( ) var ( + // the collection name of redis for cache adapter. DefaultKey string = "beecacheRedis" ) +// Redis cache adapter. type RedisCache struct { c redis.Conn conninfo string key string } +// create new redis cache with default collection name. func NewRedisCache() *RedisCache { return &RedisCache{key: DefaultKey} } +// Get cache from redis. func (rc *RedisCache) Get(key string) interface{} { if rc.c == nil { var err error @@ -36,6 +40,8 @@ func (rc *RedisCache) Get(key string) interface{} { return v } +// put cache to redis. +// timeout is ignored. func (rc *RedisCache) Put(key string, val interface{}, timeout int64) error { if rc.c == nil { var err error @@ -48,6 +54,7 @@ func (rc *RedisCache) Put(key string, val interface{}, timeout int64) error { return err } +// delete cache in redis. func (rc *RedisCache) Delete(key string) error { if rc.c == nil { var err error @@ -60,6 +67,7 @@ func (rc *RedisCache) Delete(key string) error { return err } +// check cache exist in redis. func (rc *RedisCache) IsExist(key string) bool { if rc.c == nil { var err error @@ -75,6 +83,7 @@ func (rc *RedisCache) IsExist(key string) bool { return v } +// increase counter in redis. func (rc *RedisCache) Incr(key string) error { if rc.c == nil { var err error @@ -90,6 +99,7 @@ func (rc *RedisCache) Incr(key string) error { return nil } +// decrease counter in redis. func (rc *RedisCache) Decr(key string) error { if rc.c == nil { var err error @@ -105,6 +115,7 @@ func (rc *RedisCache) Decr(key string) error { return nil } +// clean all cache in redis. delete this redis collection. func (rc *RedisCache) ClearAll() error { if rc.c == nil { var err error @@ -117,6 +128,10 @@ func (rc *RedisCache) ClearAll() error { return err } +// start redis cache adapter. +// config is like {"key":"collection key","conn":"connection info"} +// the cache item in redis are stored forever, +// so no gc operation. func (rc *RedisCache) StartAndGC(config string) error { var cf map[string]string json.Unmarshal([]byte(config), &cf) @@ -139,6 +154,7 @@ func (rc *RedisCache) StartAndGC(config string) error { return nil } +// connect to redis. func (rc *RedisCache) connectInit() (redis.Conn, error) { c, err := redis.Dial("tcp", rc.conninfo) if err != nil {