go-common/app/job/main/figure-timer/dao/hbase.go
2019-04-22 18:49:16 +08:00

354 lines
13 KiB
Go

package dao
import (
"bytes"
"context"
"encoding/binary"
"fmt"
"io"
"math"
"strconv"
"strings"
"time"
"go-common/app/job/main/figure-timer/model"
"go-common/library/log"
"github.com/pkg/errors"
"github.com/tsuna/gohbase/hrpc"
)
var (
// record
_hbaseRecordTable = "ugc:figurecalcrecord"
_hbaseRecordFC = "x"
_hbaseRecordQLawfulPosX = "pos_lawful"
_hbaseRecordQLawfulNegX = "neg_lawful"
_hbaseRecordQWidePosX = "pos_wide"
_hbaseRecordQWideNegX = "neg_wide"
_hbaseRecordQFriendlyPosX = "pos_friendly"
_hbaseRecordQFriendlyNegX = "neg_friendly"
_hbaseRecordQCreativityPosX = "pos_creativity"
_hbaseRecordQCreativityNegX = "neg_creativity"
_hbaseRecordQBountyPosX = "pos_bounty"
_hbaseRecordQBountyNegX = "neg_bounty"
// UserInfo
_hbaseUserTable = "ugc:figureuserstatus"
_hbaseUserFC = "user"
_hbaseUserQExp = "exp"
_hbaseUserQSpy = "spy_score"
_hbaseUserQArchiveViews = "archive_views"
_hbaseUserQVip = "vip_status"
_hbaseUserQDisciplineCommittee = "discipline_committee"
// ActionCounter
_hbaseActionTable = "ugc:figureactioncounter"
_hbaseActionFC = "user"
_hbaseActionQCoinCount = "coins"
_hbaseActionQReplyCount = "replies"
_hbaseActionQDanmakuCount = "danmaku"
_hbaseActionQCoinLowRisk = "coin_low_risk"
_hbaseActionQCoinHighRisk = "coin_high_risk"
_hbaseActionQReplyLowRisk = "reply_low_risk"
_hbaseActionQReplyHighRisk = "reply_high_risk"
_hbaseActionQReplyLiked = "reply_liked"
_hbaseActionQReplyUnLiked = "reply_hate"
_hbaseActionQReportReplyPassed = "report_reply_passed"
_hbaseActionQReportDanmakuPassed = "report_danmaku_passed"
_hbaseActionQPublishReplyDeleted = "publish_reply_deleted"
_hbaseActionQPublishDanmakuDeleted = "publish_danmaku_deleted"
_hbaseActionQPayMoney = "pay_money"
_hbaseActionQPayLiveMoney = "pay_live_money"
)
func rowKeyFigureRecord(mid int64, weekTS int64) (key string) {
return fmt.Sprintf("%d_%d", mid, weekTS)
}
func rowKeyUserInfo(mid int64) (key string) {
return fmt.Sprintf("%d", mid)
}
func rowKeyActionCounter(mid int64, dayTS int64) (key string) {
return fmt.Sprintf("%d_%d", mid, dayTS)
}
// UserInfo get it from hbase
func (d *Dao) UserInfo(c context.Context, mid int64, weekVer int64) (userInfo *model.UserInfo, err error) {
var (
result *hrpc.Result
key = rowKeyUserInfo(mid)
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
)
defer cancel()
if result, err = d.hbase.GetStr(ctx, _hbaseUserTable, key); err != nil {
err = errors.Wrapf(err, "hbase.GetStr(%s,%s)", _hbaseUserTable, key)
return
}
userInfo = &model.UserInfo{Mid: mid, SpyScore: math.MaxUint64}
for _, c := range result.Cells {
if c == nil {
continue
}
if bytes.Equal([]byte(_hbaseUserFC), c.Family) {
switch string(c.Qualifier) {
case _hbaseUserQExp:
userInfo.Exp = binary.BigEndian.Uint64(c.Value)
case _hbaseUserQSpy:
userInfo.SpyScore = binary.BigEndian.Uint64(c.Value)
case _hbaseUserQArchiveViews:
userInfo.ArchiveViews = binary.BigEndian.Uint64(c.Value)
case _hbaseUserQVip:
userInfo.VIPStatus = binary.BigEndian.Uint64(c.Value)
case _hbaseUserQDisciplineCommittee:
userInfo.DisciplineCommittee = binary.BigEndian.Uint16(c.Value)
}
}
}
// 未获取到spy分值特殊处理
if userInfo.SpyScore == math.MaxUint64 {
userInfo.SpyScore = 100
}
log.Info("User Info [%+v]", userInfo)
return
}
// PutCalcRecord put record all the params x.
func (d *Dao) PutCalcRecord(c context.Context, record *model.FigureRecord, weekTS int64) (err error) {
var (
key = rowKeyFigureRecord(record.Mid, weekTS)
lawfulPosX = make([]byte, 8)
lawfulNegX = make([]byte, 8)
widePosX = make([]byte, 8)
wideNegX = make([]byte, 8)
friendlyPosX = make([]byte, 8)
friendlyNegX = make([]byte, 8)
creativityPosX = make([]byte, 8)
creativityNegX = make([]byte, 8)
bountyPosX = make([]byte, 8)
bountyNegX = make([]byte, 8)
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.WriteTimeout))
)
defer cancel()
binary.BigEndian.PutUint64(lawfulPosX, uint64(record.XPosLawful))
binary.BigEndian.PutUint64(lawfulNegX, uint64(record.XNegLawful))
binary.BigEndian.PutUint64(widePosX, uint64(record.XPosWide))
binary.BigEndian.PutUint64(wideNegX, uint64(record.XNegWide))
binary.BigEndian.PutUint64(friendlyPosX, uint64(record.XPosFriendly))
binary.BigEndian.PutUint64(friendlyNegX, uint64(record.XNegFriendly))
binary.BigEndian.PutUint64(creativityPosX, uint64(record.XPosCreativity))
binary.BigEndian.PutUint64(creativityNegX, uint64(record.XNegCreativity))
binary.BigEndian.PutUint64(bountyPosX, uint64(record.XPosBounty))
binary.BigEndian.PutUint64(bountyNegX, uint64(record.XNegBounty))
values := map[string]map[string][]byte{_hbaseRecordFC: {
_hbaseRecordQLawfulPosX: lawfulPosX,
_hbaseRecordQLawfulNegX: lawfulNegX,
_hbaseRecordQWideNegX: wideNegX,
_hbaseRecordQFriendlyPosX: friendlyPosX,
_hbaseRecordQFriendlyNegX: friendlyNegX,
_hbaseRecordQCreativityPosX: creativityPosX,
_hbaseRecordQCreativityNegX: creativityNegX,
_hbaseRecordQBountyPosX: bountyPosX,
_hbaseRecordQBountyNegX: bountyNegX,
}}
if _, err = d.hbase.PutStr(ctx, _hbaseRecordTable, key, values); err != nil {
err = errors.Wrapf(err, "hbase.Put(%s,%s,%+v) error(%v)", _hbaseRecordTable, key, values, err)
}
return
}
// CalcRecords get it from hbase
func (d *Dao) CalcRecords(c context.Context, mid int64, weekTSFrom, weekTSTo int64) (figureRecords []*model.FigureRecord, err error) {
var (
scanner hrpc.Scanner
keyFrom = rowKeyFigureRecord(mid, weekTSFrom)
keyTo = rowKeyFigureRecord(mid, weekTSTo)
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
)
defer cancel()
if scanner, err = d.hbase.ScanRangeStr(ctx, _hbaseRecordTable, keyFrom, keyTo); err != nil {
err = errors.Wrapf(err, "hbase.ScanRangeStr(%s,%s,%s)", _hbaseRecordTable, keyFrom, keyTo)
return
}
for {
res, err := scanner.Next()
if err != nil {
if err != io.EOF {
err = errors.WithStack(err)
return nil, err
}
break
}
figureRecord := &model.FigureRecord{Mid: mid}
for i, c := range res.Cells {
if c == nil {
continue
}
if bytes.Equal([]byte(_hbaseRecordFC), c.Family) {
switch string(c.Qualifier) {
case _hbaseRecordQLawfulPosX:
figureRecord.XPosLawful = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQLawfulNegX:
figureRecord.XNegLawful = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQWidePosX:
figureRecord.XPosWide = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQWideNegX:
figureRecord.XNegWide = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQFriendlyPosX:
figureRecord.XPosFriendly = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQFriendlyNegX:
figureRecord.XNegFriendly = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQCreativityPosX:
figureRecord.XPosCreativity = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQCreativityNegX:
figureRecord.XNegCreativity = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQBountyPosX:
figureRecord.XPosBounty = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseRecordQBountyNegX:
figureRecord.XNegBounty = int64(binary.BigEndian.Uint64(c.Value))
}
}
if i == 0 {
figureRecord.Version = time.Unix(parseVersion(string(c.Row), c.Timestamp), 0)
}
}
log.Info("User figure record [%+v]", figureRecord)
figureRecords = append(figureRecords, figureRecord)
}
return
}
// ActionCounter .
func (d *Dao) ActionCounter(c context.Context, mid int64, ts int64) (actionCounter *model.ActionCounter, err error) {
var (
result *hrpc.Result
key = rowKeyActionCounter(mid, ts)
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
)
defer cancel()
log.Info("Get mid [%d] key [%s]", mid, key)
if result, err = d.hbase.GetStr(ctx, _hbaseActionTable, key); err != nil {
err = errors.Wrapf(err, "hbase.GetStr(%s,%s)", _hbaseActionTable, key)
return
}
actionCounter = &model.ActionCounter{Mid: mid}
for i, c := range result.Cells {
if c == nil {
continue
}
if bytes.Equal([]byte(_hbaseActionFC), c.Family) {
switch string(c.Qualifier) {
case _hbaseActionQCoinCount:
actionCounter.CoinCount = binary.BigEndian.Uint64(c.Value)
case _hbaseActionQReplyCount:
actionCounter.ReplyCount = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQDanmakuCount:
actionCounter.DanmakuCount = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQCoinLowRisk:
actionCounter.CoinLowRisk = binary.BigEndian.Uint64(c.Value)
case _hbaseActionQCoinHighRisk:
actionCounter.CoinHighRisk = binary.BigEndian.Uint64(c.Value)
case _hbaseActionQReplyLowRisk:
actionCounter.ReplyLowRisk = binary.BigEndian.Uint64(c.Value)
case _hbaseActionQReplyHighRisk:
actionCounter.ReplyHighRisk = binary.BigEndian.Uint64(c.Value)
case _hbaseActionQReplyLiked:
actionCounter.ReplyLiked = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQReplyUnLiked:
actionCounter.ReplyUnliked = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQReportReplyPassed:
actionCounter.ReportReplyPassed = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQReportDanmakuPassed:
actionCounter.ReportDanmakuPassed = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQPublishReplyDeleted:
actionCounter.PublishReplyDeleted = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQPublishDanmakuDeleted:
actionCounter.PublishDanmakuDeleted = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQPayMoney:
actionCounter.PayMoney = int64(binary.BigEndian.Uint64(c.Value))
case _hbaseActionQPayLiveMoney:
actionCounter.PayLiveMoney = int64(binary.BigEndian.Uint64(c.Value))
}
}
if i == 0 {
actionCounter.Version = time.Unix(parseVersion(string(c.Row), c.Timestamp), 0)
}
}
log.Info("User action counter [%+v]", actionCounter)
return
}
// // ActionCounters .
// func (d *Dao) ActionCounters(c context.Context, mid int64, tsfrom int64, tsto int64) (actionCounters []*model.ActionCounter, err error) {
// var (
// scan *hrpc.Scan
// results []*hrpc.Result
// keyFrom = rowKeyActionCounter(mid, tsfrom)
// keyTo = rowKeyActionCounter(mid, tsto)
// ctx, cancel = context.WithTimeout(c, time.Duration(d.c.Hbase.ReadTimeout))
// )
// defer cancel()
// log.Info("Scan mid [%d] keyFrom [%s] keyTo [%s]", mid, keyFrom, keyTo)
// if scan, err = hrpc.NewScanRangeStr(ctx, _hbaseActionTable, keyFrom, keyTo); err != nil {
// err = errors.Wrapf(err, "hrcp.NewScanRangeStr(%s,%s,%s)", _hbaseActionTable, keyFrom, keyTo)
// return
// }
// if results, err = d.hbase.Scan(ctx, scan); err != nil {
// err = errors.Wrapf(err, "hbase.Scan(%s,%s,%s)", _hbaseActionTable, keyFrom, keyTo)
// return
// }
// if len(results) == 0 {
// return
// }
// for _, res := range results {
// if res == nil {
// continue
// }
// actionCounter := &model.ActionCounter{Mid: mid}
// for i, c := range res.Cells {
// if c == nil {
// continue
// }
// if bytes.Equal([]byte(_hbaseActionFC), c.Family) {
// switch string(c.Qualifier) {
// case _hbaseActionQCoinCount:
// actionCounter.CoinCount = binary.BigEndian.Uint64(c.Value)
// case _hbaseActionQReplyCount:
// actionCounter.ReplyCount = int64(binary.BigEndian.Uint64(c.Value))
// case _hbaseActionQCoinLowRisk:
// actionCounter.CoinLowRisk = binary.BigEndian.Uint64(c.Value)
// case _hbaseActionQCoinHighRisk:
// actionCounter.CoinHighRisk = binary.BigEndian.Uint64(c.Value)
// case _hbaseActionQReplyLowRisk:
// actionCounter.ReplyLowRisk = binary.BigEndian.Uint64(c.Value)
// case _hbaseActionQReplyHighRisk:
// actionCounter.ReplyHighRisk = binary.BigEndian.Uint64(c.Value)
// case _hbaseActionQReplyLiked:
// actionCounter.ReplyLiked = int64(binary.BigEndian.Uint64(c.Value))
// case _hbaseActionQReplyUnLiked:
// actionCounter.ReplyUnliked = int64(binary.BigEndian.Uint64(c.Value))
// }
// }
// if i == 0 {
// actionCounter.Version = time.Unix(parseVersion(string(c.Row), c.Timestamp), 0)
// }
// }
// log.Info("User action counter [%+v]", actionCounter)
// actionCounters = append(actionCounters, actionCounter)
// }
// return
// }
func parseVersion(rowKey string, timestamp *uint64) (ts int64) {
strs := strings.Split(rowKey, "_")
if len(strs) < 2 {
return int64(*timestamp)
}
var err error
if ts, err = strconv.ParseInt(strs[1], 10, 64); err != nil {
return int64(*timestamp)
}
return ts
}