/
top.go
116 lines (104 loc) · 3.02 KB
/
top.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
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
}