go-common/app/interface/main/push-archive/dao/Proportion.go
2019-04-22 18:49:16 +08:00

83 lines
2.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dao
import (
"strconv"
"strings"
"go-common/app/interface/main/push-archive/conf"
"go-common/app/interface/main/push-archive/model"
"go-common/library/log"
)
// Proportion 普通关注粉丝的灰度比例
type Proportion struct {
// 粉丝的后2位的最值
MinValue int
MaxValue int
}
// NewProportion new
func NewProportion(config []conf.Proportion) (ps []Proportion) {
var ppt float64
for _, g := range config {
valueStartFloat, err := strconv.ParseFloat(strings.TrimSpace(g.ProportionStartFrom), 64)
if err != nil {
log.Error("NewProportions config ArcPush.FanGroup.ProportionStartFrom strconv.ParseFloat(%s) error(%v)", g.ProportionStartFrom, err)
return
}
valueStartFrom := int(valueStartFloat)
// 比例验证
prop, err := strconv.ParseFloat(strings.TrimSpace(g.Proportion), 64)
if err != nil {
log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s) strconv.ParseFloat err(%v)", g.Proportion, err)
return nil
}
if prop*100-float64(int(prop*100)) != 0 {
// 比例最多保留2位小数
log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s) must keep at most 2 bits", g.Proportion)
return nil
}
ppt += prop
if prop <= 0 || prop > 1 || ppt > 1 || ppt <= 0 {
// 单个数在(0,1]区间,总和在(0, 1]区间
log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s) must in (0, 1] and sum(%f) in (0, 1]", g.Proportion, ppt)
return nil
}
// 起始值和比例之和必须在0099之间
maxValue := int(100*prop-1) + valueStartFrom
if maxValue >= 100 {
log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s)+ProportionStartFrom must in [0, 99]", g.Proportion)
return
}
p := Proportion{
MinValue: valueStartFrom,
MaxValue: maxValue,
}
ps = append(ps, p)
}
return
}
// FansByProportion 根据比例分配该关注类型的粉丝, 以全站所有用户作为分母
func (d *Dao) FansByProportion(upper int64, fans map[int64]int) (attentions []int64, specials []int64) {
for mid, relationType := range fans {
if relationType == model.RelationSpecial {
specials = append(specials, mid)
continue
}
if len(d.Proportions) == 0 {
attentions = append(attentions, mid)
continue
}
// mid最后2位是否在抽样区间内
last2Digits := int(mid % 100)
for _, g := range d.Proportions {
if last2Digits >= g.MinValue && last2Digits <= g.MaxValue {
attentions = append(attentions, mid)
break
}
}
}
return
}