Proportion.go 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package dao
  2. import (
  3. "strconv"
  4. "strings"
  5. "go-common/app/interface/main/push-archive/conf"
  6. "go-common/app/interface/main/push-archive/model"
  7. "go-common/library/log"
  8. )
  9. // Proportion 普通关注粉丝的灰度比例
  10. type Proportion struct {
  11. // 粉丝的后2位的最值
  12. MinValue int
  13. MaxValue int
  14. }
  15. // NewProportion new
  16. func NewProportion(config []conf.Proportion) (ps []Proportion) {
  17. var ppt float64
  18. for _, g := range config {
  19. valueStartFloat, err := strconv.ParseFloat(strings.TrimSpace(g.ProportionStartFrom), 64)
  20. if err != nil {
  21. log.Error("NewProportions config ArcPush.FanGroup.ProportionStartFrom strconv.ParseFloat(%s) error(%v)", g.ProportionStartFrom, err)
  22. return
  23. }
  24. valueStartFrom := int(valueStartFloat)
  25. // 比例验证
  26. prop, err := strconv.ParseFloat(strings.TrimSpace(g.Proportion), 64)
  27. if err != nil {
  28. log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s) strconv.ParseFloat err(%v)", g.Proportion, err)
  29. return nil
  30. }
  31. if prop*100-float64(int(prop*100)) != 0 {
  32. // 比例最多保留2位小数
  33. log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s) must keep at most 2 bits", g.Proportion)
  34. return nil
  35. }
  36. ppt += prop
  37. if prop <= 0 || prop > 1 || ppt > 1 || ppt <= 0 {
  38. // 单个数在(0,1]区间,总和在(0, 1]区间
  39. log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s) must in (0, 1] and sum(%f) in (0, 1]", g.Proportion, ppt)
  40. return nil
  41. }
  42. // 起始值和比例之和必须在00~99之间
  43. maxValue := int(100*prop-1) + valueStartFrom
  44. if maxValue >= 100 {
  45. log.Error("NewProportions config ArcPush.FanGroup.Proportion(%s)+ProportionStartFrom must in [0, 99]", g.Proportion)
  46. return
  47. }
  48. p := Proportion{
  49. MinValue: valueStartFrom,
  50. MaxValue: maxValue,
  51. }
  52. ps = append(ps, p)
  53. }
  54. return
  55. }
  56. // FansByProportion 根据比例分配该关注类型的粉丝, 以全站所有用户作为分母
  57. func (d *Dao) FansByProportion(upper int64, fans map[int64]int) (attentions []int64, specials []int64) {
  58. for mid, relationType := range fans {
  59. if relationType == model.RelationSpecial {
  60. specials = append(specials, mid)
  61. continue
  62. }
  63. if len(d.Proportions) == 0 {
  64. attentions = append(attentions, mid)
  65. continue
  66. }
  67. // mid最后2位是否在抽样区间内
  68. last2Digits := int(mid % 100)
  69. for _, g := range d.Proportions {
  70. if last2Digits >= g.MinValue && last2Digits <= g.MaxValue {
  71. attentions = append(attentions, mid)
  72. break
  73. }
  74. }
  75. }
  76. return
  77. }