beego cache模組原始碼分析筆記四

weixin_34162695發表於2018-12-26

beego cache模組下的ssdb原始碼,這段原始碼是在gossdb包的基礎上進行封裝。

整個原始碼在230行左右,內容主要有Cache介面卡,建立這個介面卡的函式,以及介面卡的方法內容。
1、type Cache struct

type Cache struct {
    conn     *ssdb.Client
    conninfo []string
}

2、func NewSsdbCache() cache.Cache

func NewSsdbCache() cache.Cache {
    return &Cache{}
}

3、
1)func (rc *Cache) Get(key string) interface{}
根據鍵獲取值

func (rc *Cache) Get(key string) interface{} {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return nil
        }
    }
    value, err := rc.conn.Get(key)
    if err == nil {
        return value
    }
    return nil
}

2)func (rc *Cache) GetMulti(keys []string) []interface{}
用多個鍵獲取多個值

func (rc *Cache) GetMulti(keys []string) []interface{} {
    size := len(keys)
    var values []interface{}
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            for i := 0; i < size; i++ {
                values = append(values, err)
            }
            return values
        }
    }
    res, err := rc.conn.Do("multi_get", keys)
    resSize := len(res)
    if err == nil {
        for i := 1; i < resSize; i += 2 {
            values = append(values, res[i+1])
        }
        return values
    }
    for i := 0; i < size; i++ {
        values = append(values, err)
    }
    return values
}

3)func (rc *Cache) DelMulti(keys []string) error
傳入多個鍵,進行相應的刪除

func (rc *Cache) DelMulti(keys []string) error {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return err
        }
    }
    _, err := rc.conn.Do("multi_del", keys)
    return err
}

4)func (rc *Cache) Put(key string, value interface{}, timeout time.Duration) error
根據鍵值進行儲存

func (rc *Cache) Put(key string, value interface{}, timeout time.Duration) error {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return err
        }
    }
    v, ok := value.(string)
    if !ok {
        return errors.New("value must string")
    }
    var resp []string
    var err error
    ttl := int(timeout / time.Second)
    if ttl < 0 {
        resp, err = rc.conn.Do("set", key, v)
    } else {
        resp, err = rc.conn.Do("setx", key, v, ttl)
    }
    if err != nil {
        return err
    }
    if len(resp) == 2 && resp[0] == "ok" {
        return nil
    }
    return errors.New("bad response")
}

5)func (rc *Cache) Delete(key string) error
刪除一個鍵值對

func (rc *Cache) Delete(key string) error {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return err
        }
    }
    _, err := rc.conn.Del(key)
    return err
}

6)func (rc *Cache) Incr(key string) error
傳入鍵,讓值自加一

func (rc *Cache) Incr(key string) error {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return err
        }
    }
    _, err := rc.conn.Do("incr", key, 1)
    return err
}

7)func (rc *Cache) Decr(key string) error
傳入鍵,讓值自減一

func (rc *Cache) Decr(key string) error {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return err
        }
    }
    _, err := rc.conn.Do("incr", key, -1)
    return err
}

8)func (rc *Cache) IsExist(key string) bool
判斷鍵是否存在

    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return false
        }
    }
    resp, err := rc.conn.Do("exists", key)
    if err != nil {
        return false
    }
    if len(resp) == 2 && resp[1] == "1" {
        return true
    }
    return false
}

9)func (rc *Cache) ClearAll() error
清除cache中快取的所有快取

func (rc *Cache) ClearAll() error {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return err
        }
    }
    keyStart, keyEnd, limit := "", "", 50
    resp, err := rc.Scan(keyStart, keyEnd, limit)
    for err == nil {
        size := len(resp)
        if size == 1 {
            return nil
        }
        keys := []string{}
        for i := 1; i < size; i += 2 {
            keys = append(keys, resp[i])
        }
        _, e := rc.conn.Do("multi_del", keys)
        if e != nil {
            return e
        }
        keyStart = resp[size-2]
        resp, err = rc.Scan(keyStart, keyEnd, limit)
    }
    return err
}

10)func (rc *Cache) Scan(keyStart string, keyEnd string, limit int) ([]string, error)

func (rc *Cache) Scan(keyStart string, keyEnd string, limit int) ([]string, error) {
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return nil, err
        }
    }
    resp, err := rc.conn.Do("scan", keyStart, keyEnd, limit)
    if err != nil {
        return nil, err
    }
    return resp, nil
}

11)func (rc *Cache) StartAndGC(config string) error

func (rc *Cache) StartAndGC(config string) error {
    var cf map[string]string
    json.Unmarshal([]byte(config), &cf)
    if _, ok := cf["conn"]; !ok {
        return errors.New("config has no conn key")
    }
    rc.conninfo = strings.Split(cf["conn"], ";")
    if rc.conn == nil {
        if err := rc.connectInit(); err != nil {
            return err
        }
    }
    return nil
}
func (rc *Cache) connectInit() error {
    conninfoArray := strings.Split(rc.conninfo[0], ":")
    host := conninfoArray[0]
    port, e := strconv.Atoi(conninfoArray[1])
    if e != nil {
        return e
    }
    var err error
    rc.conn, err = ssdb.Connect(host, port)
    return err
}

func init() {
    cache.Register("ssdb", NewSsdbCache)
}

相關文章