You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
3.0 KiB
116 lines
3.0 KiB
package service |
|
|
|
import ( |
|
"bytes" |
|
"container/heap" |
|
"context" |
|
"strconv" |
|
"time" |
|
|
|
"go-common/app/job/main/up-rating/model" |
|
) |
|
|
|
// ratingTop get top ups |
|
func (s *Service) ratingTop(c context.Context, date time.Time, source chan []*model.Rating) (topRating map[int]map[int64]*RatingHeap, err error) { |
|
topRating = make(map[int]map[int64]*RatingHeap) // map[ctype][tagID] |
|
topRating[CreativeType] = make(map[int64]*RatingHeap) |
|
topRating[InfluenceType] = make(map[int64]*RatingHeap) |
|
for rating := range source { |
|
for _, r := range rating { |
|
if _, ok := topRating[CreativeType][r.TagID]; !ok { |
|
topRating[CreativeType][r.TagID] = &RatingHeap{} |
|
} |
|
pushTopRating(topRating[CreativeType][r.TagID], CreativeType, r) |
|
if _, ok := topRating[InfluenceType][r.TagID]; !ok { |
|
topRating[InfluenceType][r.TagID] = &RatingHeap{} |
|
} |
|
pushTopRating(topRating[InfluenceType][r.TagID], InfluenceType, r) |
|
} |
|
} |
|
return |
|
} |
|
|
|
func pushTopRating(h *RatingHeap, ctype int, r *model.Rating) { |
|
tr := &model.TopRating{ |
|
MID: r.MID, |
|
CType: ctype, |
|
TagID: r.TagID, |
|
} |
|
switch ctype { |
|
case CreativeType: |
|
tr.Score = r.CreativityScore |
|
case InfluenceType: |
|
tr.Score = r.InfluenceScore |
|
} |
|
heap.Push(h, tr) |
|
if h.Len() > 10 { |
|
heap.Pop(h) |
|
} |
|
} |
|
|
|
func (s *Service) insertTopRating(c context.Context, date time.Time, topRating map[int]map[int64]*RatingHeap, baseInfo map[int64]*model.BaseInfo) (rows int64, err error) { |
|
return s.dao.InsertTopRating(c, assemberTopRating(date, topRating, baseInfo)) |
|
} |
|
|
|
func assemberTopRating(date time.Time, topRating map[int]map[int64]*RatingHeap, baseInfo map[int64]*model.BaseInfo) (vals string) { |
|
var buf bytes.Buffer |
|
for _, tagTop := range topRating { |
|
for _, h := range tagTop { |
|
for h.Len() > 0 { |
|
tr := heap.Pop(h).(*model.TopRating) |
|
info := baseInfo[tr.MID] |
|
if info == nil { |
|
info = &model.BaseInfo{} |
|
} |
|
buf.WriteString("(") |
|
buf.WriteString(strconv.FormatInt(tr.MID, 10)) |
|
buf.WriteByte(',') |
|
buf.WriteString(strconv.Itoa(tr.CType)) |
|
buf.WriteByte(',') |
|
buf.WriteString(strconv.FormatInt(tr.TagID, 10)) |
|
buf.WriteByte(',') |
|
buf.WriteString(strconv.FormatInt(tr.Score, 10)) |
|
buf.WriteByte(',') |
|
buf.WriteString(strconv.FormatInt(info.TotalFans, 10)) |
|
buf.WriteByte(',') |
|
buf.WriteString(strconv.FormatInt(info.TotalPlay, 10)) |
|
buf.WriteByte(',') |
|
buf.WriteString("'" + date.Format(_layout) + "'") |
|
buf.WriteString(")") |
|
buf.WriteByte(',') |
|
} |
|
} |
|
} |
|
if buf.Len() > 0 { |
|
buf.Truncate(buf.Len() - 1) |
|
} |
|
vals = buf.String() |
|
buf.Reset() |
|
return |
|
} |
|
|
|
// RatingHeap rating heap for topK |
|
type RatingHeap []*model.TopRating |
|
|
|
// Len len |
|
func (r RatingHeap) Len() int { return len(r) } |
|
|
|
// Less less |
|
func (r RatingHeap) Less(i, j int) bool { return r[i].Score < r[j].Score } |
|
|
|
// Swap swap |
|
func (r RatingHeap) Swap(i, j int) { r[i], r[j] = r[j], r[i] } |
|
|
|
// Push push to heap |
|
func (r *RatingHeap) Push(x interface{}) { |
|
*r = append(*r, x.(*model.TopRating)) |
|
} |
|
|
|
// Pop pop from heap |
|
func (r *RatingHeap) Pop() interface{} { |
|
old := *r |
|
n := len(old) |
|
x := old[n-1] |
|
*r = old[0 : n-1] |
|
return x |
|
}
|
|
|