|
|
@@ -1,38 +1,70 @@
|
|
|
package core
|
|
|
|
|
|
import (
|
|
|
- "encoding/base64"
|
|
|
+ "time"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ updateIntervalSec = 10
|
|
|
+ cacheDurationSec = 120
|
|
|
)
|
|
|
|
|
|
type UserSet struct {
|
|
|
- validUserIds []ID
|
|
|
- userIdsAskHash map[string]int
|
|
|
+ validUserIds []ID
|
|
|
+ userHashes map[string]int
|
|
|
+}
|
|
|
+
|
|
|
+type hashEntry struct {
|
|
|
+ hash string
|
|
|
+ timeSec int64
|
|
|
}
|
|
|
|
|
|
func NewUserSet() *UserSet {
|
|
|
vuSet := new(UserSet)
|
|
|
vuSet.validUserIds = make([]ID, 0, 16)
|
|
|
- vuSet.userIdsAskHash = make(map[string]int)
|
|
|
+ vuSet.userHashes = make(map[string]int)
|
|
|
+
|
|
|
+ go vuSet.updateUserHash(time.Tick(updateIntervalSec * time.Second))
|
|
|
return vuSet
|
|
|
}
|
|
|
|
|
|
-func hashBytesToString(hash []byte) string {
|
|
|
- return base64.StdEncoding.EncodeToString(hash)
|
|
|
+func (us *UserSet) updateUserHash(tick <-chan time.Time) {
|
|
|
+ now := time.Now().UTC()
|
|
|
+ lastSec := now.Unix() - cacheDurationSec
|
|
|
+
|
|
|
+ hash2Remove := make(chan hashEntry, updateIntervalSec*2)
|
|
|
+ lastSec2Remove := now.Unix() + cacheDurationSec
|
|
|
+ for {
|
|
|
+ now := <-tick
|
|
|
+ nowSec := now.UTC().Unix()
|
|
|
+
|
|
|
+ remove2Sec := nowSec - cacheDurationSec
|
|
|
+ if remove2Sec > lastSec2Remove {
|
|
|
+ for lastSec2Remove+1 < remove2Sec {
|
|
|
+ entry := <-hash2Remove
|
|
|
+ lastSec2Remove = entry.timeSec
|
|
|
+ delete(us.userHashes, entry.hash)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for i := lastSec + 1; i <= nowSec; i++ {
|
|
|
+ for idx, id := range us.validUserIds {
|
|
|
+ idHash := id.TimeHash(i)
|
|
|
+ hash2Remove <- hashEntry{string(idHash), i}
|
|
|
+ us.userHashes[string(idHash)] = idx
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
func (us *UserSet) AddUser(user User) error {
|
|
|
id := user.Id
|
|
|
us.validUserIds = append(us.validUserIds, id)
|
|
|
-
|
|
|
- idBase64 := hashBytesToString(id.Hash([]byte("ASK")))
|
|
|
- us.userIdsAskHash[idBase64] = len(us.validUserIds) - 1
|
|
|
-
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (us UserSet) IsValidUserId(askHash []byte) (*ID, bool) {
|
|
|
- askBase64 := hashBytesToString(askHash)
|
|
|
- idIndex, found := us.userIdsAskHash[askBase64]
|
|
|
+func (us UserSet) IsValidUserId(userHash []byte) (*ID, bool) {
|
|
|
+ idIndex, found := us.userHashes[string(userHash)]
|
|
|
if found {
|
|
|
return &us.validUserIds[idIndex], true
|
|
|
}
|