2019-04-22 02:59:20 +00:00

207 lines
5.0 KiB
Go

package bplus
import (
"context"
"strconv"
"go-common/app/interface/main/app-interface/model"
"go-common/app/interface/main/app-interface/model/space"
"go-common/library/cache/redis"
"go-common/library/log"
xtime "go-common/library/time"
"github.com/pkg/errors"
)
const (
_prefixContributeAttr = "cba_"
_prefixContribute = "cb_"
)
func keyContributeAttr(vmid int64) string {
return _prefixContributeAttr + strconv.FormatInt(vmid, 10)
}
func keyContribute(vmid int64) string {
return _prefixContribute + strconv.FormatInt(vmid, 10)
}
// AddContributeCache .
func (d *Dao) AddContributeCache(c context.Context, vmid int64, attrs *space.Attrs, items []*space.Item) (err error) {
var attr int32
conn := d.redis.Get(c)
key := keyContribute(vmid)
defer conn.Close()
for _, item := range items {
score := item.CTime.Time().Unix()
item.FormatKey()
if err = conn.Send("ZADD", key, score, item.Member); err != nil {
err = errors.Wrapf(err, "conn.Send(ZADD,%s,%d,%d)", key, score, item.Member)
return
}
}
keyAttr := keyContributeAttr(vmid)
if attrs != nil {
if attrs.Archive {
attr = model.AttrSet(attr, model.AttrYes, model.AttrBitArchive)
}
if attrs.Article {
attr = model.AttrSet(attr, model.AttrYes, model.AttrBitArticle)
}
if attrs.Clip {
attr = model.AttrSet(attr, model.AttrYes, model.AttrBitClip)
}
if attrs.Album {
attr = model.AttrSet(attr, model.AttrYes, model.AttrBitAlbum)
}
if attrs.Audio {
attr = model.AttrSet(attr, model.AttrYes, model.AttrBitAudio)
}
}
if err = conn.Send("SET", keyAttr, attr); err != nil {
err = errors.Wrapf(err, "conn.Send(SET,%s,%d)", keyAttr, attr)
return
}
if err = conn.Flush(); err != nil {
return
}
for i := 0; i < len(items)+1; i++ {
if _, err = conn.Receive(); err != nil {
return
}
}
return
}
// RangeContributeCache .
func (d *Dao) RangeContributeCache(c context.Context, vmid int64, pn, ps int) (items []*space.Item, err error) {
conn := d.redis.Get(c)
key := keyContribute(vmid)
start := (pn - 1) * ps
stop := pn*ps - 1
defer conn.Close()
var vs []interface{}
if vs, err = redis.Values(conn.Do("ZREVRANGE", key, start, stop, "WITHSCORES")); err != nil {
err = errors.Wrapf(err, "conn.Do(ZREVRANGE,%s,%d,%d)", key, start, stop)
return
} else if len(vs) == 0 {
return
}
items = make([]*space.Item, 0, ps)
for len(vs) > 0 {
var (
member int64
score int64
)
if vs, err = redis.Scan(vs, &member, &score); err != nil {
log.Error("redis.Scan(%v) error(%v)", vs, err)
err = nil
continue
}
if member != 0 && score != 0 {
item := &space.Item{Member: member, CTime: xtime.Time(score)}
item.ParseKey()
if item.Goto != "" {
items = append(items, item)
}
}
}
return
}
func (d *Dao) RangeContributionCache(c context.Context, vmid int64, cursor *model.Cursor) (items []*space.Item, err error) {
conn := d.redis.Get(c)
key := keyContribute(vmid)
defer conn.Close()
var (
vs []interface{}
rank int64
start, stop int64
)
if cursor.MoveUpward() || cursor.MoveDownward() {
if rank, err = redis.Int64(conn.Do("ZREVRANK", key, cursor.Current)); err != nil {
if err == redis.ErrNil {
err = nil
return
}
err = errors.Wrapf(err, "conn.Do(ZREVRANK,%s,%d)", key, cursor.Current)
return
}
}
if cursor.Latest() {
start = 0
stop = rank + int64(cursor.Size) - 1
} else if cursor.MoveUpward() {
if rank == 0 {
return
}
if start = rank - int64(cursor.Size); start < 0 {
start = 0
}
stop = rank - 1
} else if cursor.MoveDownward() {
start = rank + 1
stop = rank + int64(cursor.Size)
}
if vs, err = redis.Values(conn.Do("ZREVRANGE", key, start, stop, "WITHSCORES")); err != nil {
err = errors.Wrapf(err, "conn.Do(ZREVRANGE,%s,%d,%d)", key, start, stop)
return
}
if len(vs) == 0 {
return
}
items = make([]*space.Item, 0, len(vs))
for len(vs) > 0 {
var (
member int64
score int64
)
if vs, err = redis.Scan(vs, &member, &score); err != nil {
log.Error("redis.Scan(%v) error(%v)", vs, err)
err = nil
continue
}
if member != 0 && score != 0 {
item := &space.Item{Member: member, CTime: xtime.Time(score)}
item.ParseKey()
if item.Goto != "" {
items = append(items, item)
}
}
}
return
}
// AttrCache .
func (d *Dao) AttrCache(c context.Context, vmid int64) (attrs *space.Attrs, err error) {
var attr int64
conn := d.redis.Get(c)
key := keyContributeAttr(vmid)
if attr, err = redis.Int64(conn.Do("GET", key)); err != nil {
if err == redis.ErrNil {
err = nil
return
}
err = errors.Wrapf(err, "conn.Do(GET,%s)", key)
return
}
conn.Close()
attrs = &space.Attrs{}
if model.AttrVal(int32(attr), model.AttrBitArchive) == model.AttrYes {
attrs.Archive = true
}
if model.AttrVal(int32(attr), model.AttrBitArticle) == model.AttrYes {
attrs.Article = true
}
if model.AttrVal(int32(attr), model.AttrBitClip) == model.AttrYes {
attrs.Clip = true
}
if model.AttrVal(int32(attr), model.AttrBitAlbum) == model.AttrYes {
attrs.Album = true
}
if model.AttrVal(int32(attr), model.AttrBitAudio) == model.AttrYes {
attrs.Audio = true
}
return
}