userset.go 1.5 KB

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