userset.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package core
  2. import (
  3. "time"
  4. )
  5. const (
  6. updateIntervalSec = 10
  7. cacheDurationSec = 120
  8. )
  9. type UserSet interface {
  10. AddUser(user User) error
  11. GetUser(timeHash []byte) (*ID, bool)
  12. }
  13. type TimedUserSet struct {
  14. validUserIds []ID
  15. userHashes map[string]int
  16. }
  17. type hashEntry struct {
  18. hash string
  19. timeSec int64
  20. }
  21. func NewTimedUserSet() UserSet {
  22. vuSet := new(TimedUserSet)
  23. vuSet.validUserIds = make([]ID, 0, 16)
  24. vuSet.userHashes = make(map[string]int)
  25. go vuSet.updateUserHash(time.Tick(updateIntervalSec * time.Second))
  26. return vuSet
  27. }
  28. func (us *TimedUserSet) updateUserHash(tick <-chan time.Time) {
  29. now := time.Now().UTC()
  30. lastSec := now.Unix() - cacheDurationSec
  31. hash2Remove := make(chan hashEntry, cacheDurationSec*2*len(us.validUserIds))
  32. lastSec2Remove := now.Unix()
  33. for {
  34. now := <-tick
  35. nowSec := now.UTC().Unix()
  36. remove2Sec := nowSec - cacheDurationSec
  37. if remove2Sec > lastSec2Remove {
  38. for lastSec2Remove+1 < remove2Sec {
  39. entry := <-hash2Remove
  40. lastSec2Remove = entry.timeSec
  41. delete(us.userHashes, entry.hash)
  42. }
  43. }
  44. for lastSec < nowSec + cacheDurationSec {
  45. for idx, id := range us.validUserIds {
  46. idHash := id.TimeHash(lastSec)
  47. hash2Remove <- hashEntry{string(idHash), lastSec}
  48. us.userHashes[string(idHash)] = idx
  49. }
  50. lastSec ++
  51. }
  52. }
  53. }
  54. func (us *TimedUserSet) AddUser(user User) error {
  55. id := user.Id
  56. us.validUserIds = append(us.validUserIds, id)
  57. return nil
  58. }
  59. func (us TimedUserSet) GetUser(userHash []byte) (*ID, bool) {
  60. idIndex, found := us.userHashes[string(userHash)]
  61. if found {
  62. return &us.validUserIds[idIndex], true
  63. }
  64. return nil, false
  65. }