memcache.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. package archive
  2. import (
  3. "context"
  4. "strconv"
  5. "go-common/app/service/main/archive/api"
  6. "go-common/library/cache/memcache"
  7. "go-common/library/log"
  8. "github.com/pkg/errors"
  9. )
  10. const (
  11. _prefixArchive = "a3p_"
  12. _prefixStat = "stp_"
  13. )
  14. func keyArc(aid int64) string {
  15. return _prefixArchive + strconv.FormatInt(aid, 10)
  16. }
  17. func keyStat(aid int64) string {
  18. return _prefixStat + strconv.FormatInt(aid, 10)
  19. }
  20. // arcsCache get archives cache.
  21. func (d *Dao) arcsCache(c context.Context, aids []int64) (cached map[int64]*api.Arc, missed []int64, err error) {
  22. cached = make(map[int64]*api.Arc, len(aids))
  23. var rs map[string]*memcache.Item
  24. conn := d.arcMc.Get(c)
  25. keys := make([]string, 0, len(aids))
  26. aidmap := make(map[string]int64, len(aids))
  27. defer conn.Close()
  28. for _, aid := range aids {
  29. k := keyArc(aid)
  30. if _, ok := aidmap[k]; !ok {
  31. keys = append(keys, k)
  32. aidmap[k] = aid
  33. }
  34. }
  35. if rs, err = conn.GetMulti(keys); err != nil {
  36. err = errors.Wrapf(err, "%v", keys)
  37. return
  38. }
  39. for k, r := range rs {
  40. a := &api.Arc{}
  41. if err = conn.Scan(r, a); err != nil {
  42. log.Error("conn.Scan(%s) error(%v)", r.Value, err)
  43. err = nil
  44. continue
  45. }
  46. cached[aidmap[k]] = a
  47. // delete hit key
  48. delete(aidmap, k)
  49. }
  50. // missed key
  51. missed = make([]int64, 0, len(aidmap))
  52. for _, aid := range aidmap {
  53. missed = append(missed, aid)
  54. }
  55. return
  56. }
  57. // statsCache get stat cache by aids
  58. func (d *Dao) statsCache(c context.Context, aids []int64) (cached map[int64]*api.Stat, missed []int64, err error) {
  59. cached = make(map[int64]*api.Stat, len(aids))
  60. var rs map[string]*memcache.Item
  61. conn := d.arcMc.Get(c)
  62. keys := make([]string, 0, len(aids))
  63. defer conn.Close()
  64. for _, aid := range aids {
  65. keys = append(keys, keyStat(aid))
  66. }
  67. if rs, err = conn.GetMulti(keys); err != nil {
  68. err = errors.Wrapf(err, "%v", keys)
  69. return
  70. }
  71. for _, r := range rs {
  72. st := &api.Stat{}
  73. if err = conn.Scan(r, st); err != nil {
  74. log.Error("conn.Scan(%s) error(%v)", r.Value, err)
  75. err = nil
  76. continue
  77. }
  78. cached[st.Aid] = st
  79. }
  80. if len(cached) == len(aids) {
  81. return
  82. }
  83. for _, aid := range aids {
  84. if _, ok := cached[aid]; !ok {
  85. missed = append(missed, aid)
  86. }
  87. }
  88. return
  89. }
  90. func (d *Dao) avWithStCaches(c context.Context, aids []int64) (cached map[int64]*api.Arc, avMissed, stMissed []int64, err error) {
  91. cached = make(map[int64]*api.Arc, len(aids))
  92. conn := d.arcMc.Get(c)
  93. defer conn.Close()
  94. keys := make([]string, 0, len(aids)*2)
  95. avm := make(map[string]int64, len(aids))
  96. stm := make(map[string]int64, len(aids))
  97. for _, aid := range aids {
  98. ak := keyArc(aid)
  99. if _, ok := avm[ak]; !ok {
  100. keys = append(keys, ak)
  101. avm[ak] = aid
  102. }
  103. sk := keyStat(aid)
  104. if _, ok := stm[sk]; !ok {
  105. keys = append(keys, sk)
  106. stm[sk] = aid
  107. }
  108. }
  109. rs, err := conn.GetMulti(keys)
  110. if err != nil {
  111. err = errors.Wrapf(err, "%v", keys)
  112. return
  113. }
  114. stCached := make(map[string]*api.Stat, len(aids))
  115. for k, r := range rs {
  116. if aid, ok := avm[k]; ok {
  117. a := &api.Arc{}
  118. if err = conn.Scan(r, a); err != nil {
  119. log.Error("conn.Scan(%s) error(%v)", r.Value, err)
  120. err = nil
  121. continue
  122. }
  123. cached[aid] = a
  124. // delete hit key
  125. delete(avm, k)
  126. }
  127. if _, ok := stm[k]; ok {
  128. st := &api.Stat{}
  129. if err = conn.Scan(r, st); err != nil {
  130. log.Error("conn.Scan(%s) error(%v)", r.Value, err)
  131. err = nil
  132. continue
  133. }
  134. stCached[k] = st
  135. }
  136. }
  137. for k, st := range stCached {
  138. if a, ok := cached[st.Aid]; ok {
  139. a.Stat = *st
  140. // delete hit key
  141. delete(stm, k)
  142. }
  143. }
  144. // missed key
  145. avMissed = make([]int64, 0, len(avm))
  146. for _, aid := range avm {
  147. avMissed = append(avMissed, aid)
  148. }
  149. stMissed = make([]int64, 0, len(stm))
  150. for _, aid := range stm {
  151. stMissed = append(stMissed, aid)
  152. }
  153. return
  154. }