| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- package combomatch
- import (
- "bet24.com/log"
- "bet24.com/redis"
- "encoding/json"
- "strconv"
- "sync"
- "time"
- )
- var freeCountMgr *userfreecount
- func getFreeCountManager() *userfreecount {
- if freeCountMgr == nil {
- freeCountMgr = new(userfreecount)
- }
- return freeCountMgr
- }
- type freeInfo struct {
- MatchId int
- FreeCount int
- }
- type userfreecount struct {
- lock *sync.RWMutex
- userFreeInfo map[int][]freeInfo
- isDirty bool
- lastCheckDay int
- }
- const refresh_usercount_config_sec = 600
- func (m *userfreecount) run() {
- log.Release("combomatch.userfreecount.run()")
- m.lock = &sync.RWMutex{}
- m.userFreeInfo = make(map[int][]freeInfo)
- m.loadFromRedis()
- m.lastCheckDay = time.Now().Day()
- m.flush()
- }
- func getUserFreeCountRedisKey() string {
- return "combomatch:userfreecount"
- }
- func (m *userfreecount) loadFromRedis() {
- data, ok := redis.String_Get(getUserFreeCountRedisKey())
- if data == "" || !ok {
- return
- }
- m.lock.Lock()
- err := json.Unmarshal([]byte(data), &m.userFreeInfo)
- m.lock.Unlock()
- if err != nil {
- log.Release("userfreecount.loadFromRedis Unmarshal failed err:%v,%s", err, data)
- return
- }
- }
- func (m *userfreecount) doFlush() {
- m.isDirty = true
- m.flush()
- }
- func (m *userfreecount) flush() {
- time.AfterFunc(refresh_usercount_config_sec*time.Second, m.flush)
- m.lock.RLock()
- if !m.isDirty {
- m.lock.RUnlock()
- return
- }
- m.isDirty = false
- d, _ := json.Marshal(m.userFreeInfo)
- m.lock.RUnlock()
- go redis.String_Set(getUserFreeCountRedisKey(), string(d))
- }
- func (m *userfreecount) dump(userIdStr string) {
- log.Release("-------------------------------")
- log.Release("userfreecount.dumpUser[%s]", userIdStr)
- defer func() {
- log.Release("+++++++++++++++++++++++++++++++")
- log.Release("")
- }()
- userId, err := strconv.Atoi(userIdStr)
- if err != nil {
- log.Release(" atoi error %v", err)
- return
- }
- fi := m.getUserFreeInfo(userId)
- if len(fi) == 0 {
- log.Release(" user has no free count")
- return
- }
- for _, v := range fi {
- log.Release(" MatchId[%d],Count[%d]", v.MatchId, v.FreeCount)
- }
- }
- func (m *userfreecount) addFreeCount(userId int, matchId int) {
- m.checkDayRefresh()
- fi := m.getUserFreeInfo(userId)
- added := false
- for i := 0; i < len(fi); i++ {
- if fi[i].MatchId == matchId {
- fi[i].FreeCount++
- added = true
- break
- }
- }
- // 之前没有
- if !added {
- fi = append(fi, freeInfo{MatchId: matchId, FreeCount: 1})
- }
- m.lock.Lock()
- m.userFreeInfo[userId] = fi
- m.lock.Unlock()
- m.isDirty = true
- return
- }
- func (m *userfreecount) reduceFreeCount(userId int, matchId int) {
- m.checkDayRefresh()
- fi := m.getUserFreeInfo(userId)
- for i := 0; i < len(fi); i++ {
- if fi[i].MatchId == matchId {
- fi[i].FreeCount--
- if fi[i].FreeCount < 0 {
- fi[i].FreeCount = 0
- }
- break
- }
- }
- m.lock.Lock()
- m.userFreeInfo[userId] = fi
- m.lock.Unlock()
- m.isDirty = true
- return
- }
- func (m *userfreecount) checkDayRefresh() {
- nowDay := time.Now().Day()
- if nowDay == m.lastCheckDay {
- return
- }
- m.lastCheckDay = nowDay
- // 清理数据
- m.lock.Lock()
- m.userFreeInfo = make(map[int][]freeInfo)
- m.lock.Unlock()
- m.isDirty = true
- }
- func (m *userfreecount) getUserFreeInfo(userId int) []freeInfo {
- m.lock.RLock()
- defer m.lock.RUnlock()
- ret, ok := m.userFreeInfo[userId]
- if !ok {
- return []freeInfo{}
- }
- return ret
- }
- func (m *userfreecount) getUserFreeCount(userId, matchId int) int {
- fi := m.getUserFreeInfo(userId)
- for _, v := range fi {
- if v.MatchId == matchId {
- return v.FreeCount
- }
- }
- return 0
- }
|