207 lines
5.0 KiB
Go
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
|
|
}
|