Occupants LRU: cached reverse id-by-nickname lookups

This commit is contained in:
Bohdan Horbeshko 2025-07-31 10:10:27 -04:00
parent 3a18e9dc80
commit ca75d38169
2 changed files with 21 additions and 6 deletions

View file

@ -52,6 +52,7 @@ func NewMUCState() *MUCState {
type MUCOccupantsLRU struct { type MUCOccupantsLRU struct {
m map[int64]*MUCOccupant m map[int64]*MUCOccupant
rev map[string]int64
oldest *MUCOccupant oldest *MUCOccupant
newest *MUCOccupant newest *MUCOccupant
lock sync.Mutex lock sync.Mutex
@ -60,6 +61,7 @@ type MUCOccupantsLRU struct {
func NewMUCOccupantsLRU() *MUCOccupantsLRU { func NewMUCOccupantsLRU() *MUCOccupantsLRU {
return &MUCOccupantsLRU{ return &MUCOccupantsLRU{
m: make(map[int64]*MUCOccupant), m: make(map[int64]*MUCOccupant),
rev: make(map[string]int64),
} }
} }
@ -71,6 +73,14 @@ func (lru *MUCOccupantsLRU) Get(id int64) (*MUCOccupant, bool) {
return occupant, ok return occupant, ok
} }
func (lru *MUCOccupantsLRU) GetIdByNickname(nickname string) (int64, bool) {
lru.lock.Lock()
defer lru.lock.Unlock()
id, ok := lru.rev[nickname]
return id, ok
}
func (lru *MUCOccupantsLRU) cutOut(oldOccupant *MUCOccupant) (prev, next *MUCOccupant) { func (lru *MUCOccupantsLRU) cutOut(oldOccupant *MUCOccupant) (prev, next *MUCOccupant) {
prev, next = oldOccupant.cutOut() prev, next = oldOccupant.cutOut()
if lru.oldest == oldOccupant { if lru.oldest == oldOccupant {
@ -102,6 +112,9 @@ func (lru *MUCOccupantsLRU) Set(id int64, occupant *MUCOccupant) (deleted *MUCOc
if oldOk { if oldOk {
lru.cutOut(oldOccupant) lru.cutOut(oldOccupant)
delete(lru.rev, oldOccupant.Nickname)
lru.rev[occupant.Nickname] = id
} }
if (lru.oldest == nil) != (lru.newest == nil) { if (lru.oldest == nil) != (lru.newest == nil) {
@ -120,6 +133,7 @@ func (lru *MUCOccupantsLRU) Set(id int64, occupant *MUCOccupant) (deleted *MUCOc
if len(lru.m) > int(MUCOccupantsLimit) && lru.oldest != nil { if len(lru.m) > int(MUCOccupantsLimit) && lru.oldest != nil {
deleted = lru.oldest deleted = lru.oldest
delete(lru.m, lru.oldest.id) delete(lru.m, lru.oldest.id)
delete(lru.rev, lru.oldest.Nickname)
lru.cutOut(lru.oldest) lru.cutOut(lru.oldest)
} }
@ -136,6 +150,7 @@ func (lru *MUCOccupantsLRU) Delete(id int64) {
if oldOk { if oldOk {
lru.cutOut(oldOccupant) lru.cutOut(oldOccupant)
delete(lru.rev, oldOccupant.Nickname)
} }
} }
@ -183,6 +198,7 @@ func (lru *MUCOccupantsLRU) Clear() {
occupant.next = nil occupant.next = nil
} }
lru.m = make(map[int64]*MUCOccupant) lru.m = make(map[int64]*MUCOccupant)
lru.rev = make(map[string]int64)
lru.oldest = nil lru.oldest = nil
lru.newest = nil lru.newest = nil

View file

@ -984,7 +984,7 @@ func (c *Client) GetMyMUCNickname(chatID int64) (string, bool) {
return occupant.Nickname, true return occupant.Nickname, true
} }
// GetMUCMemberIdByNickname looks up the telegram ID by the MUC nickname (slow yet! (TODO)) // GetMUCMemberIdByNickname looks up the telegram ID by the MUC nickname
func (c *Client) GetMUCMemberIdByNickname(chatID int64, nickname string) int64 { func (c *Client) GetMUCMemberIdByNickname(chatID int64, nickname string) int64 {
c.locks.mucCacheLock.Lock() c.locks.mucCacheLock.Lock()
defer c.locks.mucCacheLock.Unlock() defer c.locks.mucCacheLock.Unlock()
@ -994,10 +994,9 @@ func (c *Client) GetMUCMemberIdByNickname(chatID int64, nickname string) int64 {
return 0 return 0
} }
for occupant := range mucState.Occupants.Range() { id, ok := mucState.Occupants.GetIdByNickname(nickname)
if occupant.Nickname == nickname { if ok {
return occupant.id return id
}
} }
return 0 return 0