mirror of
https://dev.narayana.im/narayana/telegabber.git
synced 2026-08-05 12:17:06 +00:00
Upgrade MUC occupants map to LRU
This commit is contained in:
parent
a909b86831
commit
f3eeba7273
5 changed files with 618 additions and 39 deletions
|
|
@ -21,27 +21,6 @@ type DelayedStatus struct {
|
|||
TimestampExpired int64
|
||||
}
|
||||
|
||||
// MUCState holds MUC metadata
|
||||
type MUCState struct {
|
||||
Resources map[string]bool
|
||||
Occupants map[int64]*MUCOccupant
|
||||
}
|
||||
|
||||
// MUCOccupant represents a MUC occupant
|
||||
type MUCOccupant struct {
|
||||
Nickname string
|
||||
Affiliation string
|
||||
Role string
|
||||
Status client.ChatMemberStatus
|
||||
}
|
||||
|
||||
func NewMUCState() *MUCState {
|
||||
return &MUCState{
|
||||
Resources: make(map[string]bool),
|
||||
Occupants: make(map[int64]*MUCOccupant),
|
||||
}
|
||||
}
|
||||
|
||||
// HashedAvatar stores a SHA-1 hash and a Telegram file ID
|
||||
type HashedAvatar struct {
|
||||
Hash string
|
||||
|
|
|
|||
|
|
@ -506,7 +506,7 @@ func (c *Client) updateBasicGroupFullInfo(update *client.UpdateBasicGroupFullInf
|
|||
|
||||
mucState, ok := c.mucCache[chatID]
|
||||
if ok && mucState != nil {
|
||||
mucState.Occupants = make(map[int64]*MUCOccupant)
|
||||
mucState.Occupants.Clear()
|
||||
c.updateMUCOccupants(mucState, chatID, update.BasicGroupFullInfo.Members)
|
||||
}
|
||||
|
||||
|
|
@ -528,7 +528,7 @@ func (c *Client) updateChatPermissions(update *client.UpdateChatPermissions) {
|
|||
mucState, ok := c.mucCache[update.ChatId]
|
||||
if ok && mucState != nil {
|
||||
_, toJids := c.getMUCJoinedJIDs(update.ChatId, mucState, false)
|
||||
for memberID, occupant := range mucState.Occupants {
|
||||
for occupant := range mucState.Occupants.Range() {
|
||||
affiliation, role := c.memberStatusToAffiliationAndRole(occupant.Status, chat)
|
||||
if affiliation != occupant.Affiliation || role != occupant.Role {
|
||||
occupant.Affiliation = affiliation
|
||||
|
|
@ -538,7 +538,7 @@ func (c *Client) updateChatPermissions(update *client.UpdateChatPermissions) {
|
|||
gateway.SPFrom(gateway.MUCNODE(update.ChatId)),
|
||||
gateway.SPResource(occupant.Nickname),
|
||||
gateway.SPImmed(true),
|
||||
gateway.SPMUCJid(gateway.CHATJID(memberID, true)),
|
||||
gateway.SPMUCJid(gateway.CHATJID(occupant.key, true)),
|
||||
gateway.SPMUCAffiliation(affiliation),
|
||||
gateway.SPMUCRole(role),
|
||||
gateway.SPToJids(toJids),
|
||||
|
|
|
|||
181
telegram/muc.go
Normal file
181
telegram/muc.go
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
package telegram
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/zelenin/go-tdlib/client"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const MUCOccupantsLimit int32 = 200
|
||||
|
||||
// MUCState holds MUC metadata
|
||||
type MUCState struct {
|
||||
Resources map[string]bool
|
||||
Occupants *MUCOccupantsLRU
|
||||
}
|
||||
|
||||
// MUCOccupant represents a MUC occupant
|
||||
type MUCOccupant struct {
|
||||
Nickname string
|
||||
Affiliation string
|
||||
Role string
|
||||
Status client.ChatMemberStatus
|
||||
prev *MUCOccupant
|
||||
next *MUCOccupant
|
||||
key int64
|
||||
}
|
||||
|
||||
func (o *MUCOccupant) cutOut() (prev, next *MUCOccupant) {
|
||||
prev = o.prev
|
||||
next = o.next
|
||||
|
||||
// -- * --- * -X- * -X- * --- * --
|
||||
o.prev = nil
|
||||
o.next = nil
|
||||
if prev != nil {
|
||||
prev.next = next
|
||||
}
|
||||
if next != nil {
|
||||
next.prev = prev
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func NewMUCState() *MUCState {
|
||||
return &MUCState{
|
||||
Resources: make(map[string]bool),
|
||||
Occupants: NewMUCOccupantsLRU(),
|
||||
}
|
||||
}
|
||||
|
||||
type MUCOccupantsLRU struct {
|
||||
m map[int64]*MUCOccupant
|
||||
oldest *MUCOccupant
|
||||
newest *MUCOccupant
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
func NewMUCOccupantsLRU() *MUCOccupantsLRU {
|
||||
return &MUCOccupantsLRU{
|
||||
m: make(map[int64]*MUCOccupant),
|
||||
}
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) Get(key int64) (*MUCOccupant, bool) {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
||||
occupant, ok := lru.m[key]
|
||||
return occupant, ok
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) cutOut(oldOccupant *MUCOccupant) (prev, next *MUCOccupant) {
|
||||
prev, next = oldOccupant.cutOut()
|
||||
if lru.oldest == oldOccupant {
|
||||
lru.oldest = next
|
||||
}
|
||||
if lru.newest == oldOccupant {
|
||||
lru.newest = prev
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) insertNewest(occupant *MUCOccupant) {
|
||||
lru.newest.next = occupant
|
||||
occupant.prev = lru.newest
|
||||
occupant.next = nil
|
||||
lru.newest = occupant
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) Set(key int64, occupant *MUCOccupant) {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
||||
occupant.key = key
|
||||
|
||||
oldOccupant, oldOk := lru.m[key]
|
||||
lru.m[key] = occupant
|
||||
|
||||
if oldOk {
|
||||
lru.cutOut(oldOccupant)
|
||||
}
|
||||
|
||||
if (lru.oldest == nil) != (lru.newest == nil) {
|
||||
log.Fatal("MRD MUDAQ")
|
||||
}
|
||||
|
||||
if lru.oldest == nil && lru.newest == nil {
|
||||
lru.oldest = occupant
|
||||
lru.newest = occupant
|
||||
occupant.prev = nil
|
||||
occupant.next = nil
|
||||
} else {
|
||||
lru.insertNewest(occupant)
|
||||
}
|
||||
|
||||
if len(lru.m) > int(MUCOccupantsLimit) && lru.oldest != nil {
|
||||
delete(lru.m, lru.oldest.key)
|
||||
lru.cutOut(lru.oldest)
|
||||
}
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) Delete(key int64) {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
||||
oldOccupant, oldOk := lru.m[key]
|
||||
delete(lru.m, key)
|
||||
|
||||
if oldOk {
|
||||
lru.cutOut(oldOccupant)
|
||||
}
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) Bump(occupant *MUCOccupant) {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
||||
if lru.newest == occupant {
|
||||
// already at the top, nothing to do
|
||||
return
|
||||
}
|
||||
|
||||
lru.cutOut(occupant)
|
||||
lru.insertNewest(occupant)
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) Range() chan *MUCOccupant {
|
||||
lru.lock.Lock()
|
||||
|
||||
occupantChan := make(chan *MUCOccupant, 1)
|
||||
|
||||
go func() {
|
||||
defer func() {
|
||||
lru.lock.Unlock()
|
||||
close(occupantChan)
|
||||
}()
|
||||
|
||||
for _, occupant := range lru.m {
|
||||
occupantChan <- occupant
|
||||
}
|
||||
}()
|
||||
|
||||
return occupantChan
|
||||
}
|
||||
|
||||
func (lru *MUCOccupantsLRU) Clear() {
|
||||
lru.lock.Lock()
|
||||
defer lru.lock.Unlock()
|
||||
|
||||
for _, occupant := range lru.m {
|
||||
occupant.prev = nil
|
||||
occupant.next = nil
|
||||
}
|
||||
lru.m = make(map[int64]*MUCOccupant)
|
||||
|
||||
lru.oldest = nil
|
||||
lru.newest = nil
|
||||
}
|
||||
419
telegram/muc_test.go
Normal file
419
telegram/muc_test.go
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
package telegram
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
// -x->[]-x-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetInitiallyEmpty(t *testing.T) {
|
||||
// init
|
||||
occupants := NewMUCOccupantsLRU()
|
||||
|
||||
// addition
|
||||
newOccupant := &MUCOccupant{}
|
||||
occupants.Set(1, newOccupant)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != newOccupant || newOccupant.prev != nil || newOccupant.next != nil || occupants.newest != newOccupant {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
func testMUCOccupantsLRUChainOfOne() (occupants *MUCOccupantsLRU, occupant1 *MUCOccupant) {
|
||||
occupants = NewMUCOccupantsLRU()
|
||||
occupant1 = &MUCOccupant{}
|
||||
occupants.m[1] = occupant1
|
||||
occupants.oldest = occupant1
|
||||
occupants.newest = occupant1
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func testMUCOccupantsLRUChainOfThree() (occupants *MUCOccupantsLRU, occupant1, occupant2, occupant3 *MUCOccupant) {
|
||||
occupants = NewMUCOccupantsLRU()
|
||||
occupant1 = &MUCOccupant{}
|
||||
occupant2 = &MUCOccupant{}
|
||||
occupant3 = &MUCOccupant{}
|
||||
occupants.m[1] = occupant1
|
||||
occupants.m[2] = occupant2
|
||||
occupants.m[3] = occupant3
|
||||
occupants.oldest = occupant1
|
||||
occupants.newest = occupant3
|
||||
occupant1.next = occupant2
|
||||
occupant2.prev = occupant1
|
||||
occupant2.next = occupant3
|
||||
occupant3.prev = occupant2
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ->[]->()-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetOneOther(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1 := testMUCOccupantsLRUChainOfOne()
|
||||
|
||||
// addition
|
||||
newOccupant := &MUCOccupant{}
|
||||
occupants.Set(2, newOccupant)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 || occupant1.prev != nil || occupant1.next != newOccupant || newOccupant.prev != occupant1 || newOccupant.next != nil || occupants.newest != newOccupant {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->()->()-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetThreeOthers(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// addition
|
||||
newOccupant := &MUCOccupant{}
|
||||
occupants.Set(4, newOccupant)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant2 ||
|
||||
occupant2.prev != occupant1 ||
|
||||
occupant2.next != occupant3 ||
|
||||
occupant3.prev != occupant2 ||
|
||||
occupant3.next != newOccupant ||
|
||||
newOccupant.prev != occupant3 ||
|
||||
newOccupant.next != nil ||
|
||||
occupants.newest != newOccupant {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(.)->()->()-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceFirst(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// addition
|
||||
newOccupant := &MUCOccupant{}
|
||||
occupants.Set(1, newOccupant)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant2 ||
|
||||
occupant2.prev != nil ||
|
||||
occupant2.next != occupant3 ||
|
||||
occupant3.prev != occupant2 ||
|
||||
occupant3.next != newOccupant ||
|
||||
newOccupant.prev != occupant3 ||
|
||||
newOccupant.next != nil ||
|
||||
occupants.newest != newOccupant ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->(.)->()-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceMiddle(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// addition
|
||||
newOccupant := &MUCOccupant{}
|
||||
occupants.Set(2, newOccupant)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant3 ||
|
||||
occupant3.prev != occupant1 ||
|
||||
occupant3.next != newOccupant ||
|
||||
newOccupant.prev != occupant3 ||
|
||||
newOccupant.next != nil ||
|
||||
occupants.newest != newOccupant ||
|
||||
occupant2.prev != nil ||
|
||||
occupant2.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->()->(.)-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceLast(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// addition
|
||||
newOccupant := &MUCOccupant{}
|
||||
occupants.Set(3, newOccupant)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant2 ||
|
||||
occupant2.prev != occupant1 ||
|
||||
occupant2.next != newOccupant ||
|
||||
newOccupant.prev != occupant2 ||
|
||||
newOccupant.next != nil ||
|
||||
occupants.newest != newOccupant ||
|
||||
occupant3.prev != nil ||
|
||||
occupant3.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(.)-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceOnly(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1 := testMUCOccupantsLRUChainOfOne()
|
||||
|
||||
// addition
|
||||
newOccupant := &MUCOccupant{}
|
||||
occupants.Set(1, newOccupant)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != newOccupant ||
|
||||
occupants.newest != newOccupant ||
|
||||
newOccupant.prev != nil ||
|
||||
newOccupant.next != nil ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(.)->()->()-> +s(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceFirstWithSame(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// addition
|
||||
occupants.Set(1, occupant1)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant2 ||
|
||||
occupant2.prev != nil ||
|
||||
occupant2.next != occupant3 ||
|
||||
occupant3.prev != occupant2 ||
|
||||
occupant3.next != occupant1 ||
|
||||
occupant1.prev != occupant3 ||
|
||||
occupant1.next != nil ||
|
||||
occupants.newest != occupant1 {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->(.)->()-> +s(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceMiddleWithSame(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// addition
|
||||
occupants.Set(2, occupant2)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant3 ||
|
||||
occupant3.prev != occupant1 ||
|
||||
occupant3.next != occupant2 ||
|
||||
occupant2.prev != occupant3 ||
|
||||
occupant2.next != nil ||
|
||||
occupants.newest != occupant2 {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->()->(.)-> +s(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceLastWithSame(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// addition
|
||||
occupants.Set(3, occupant3)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant2 ||
|
||||
occupant2.prev != occupant1 ||
|
||||
occupant2.next != occupant3 ||
|
||||
occupant3.prev != occupant2 ||
|
||||
occupant3.next != nil ||
|
||||
occupants.newest != occupant3 {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(.)-> +(.)
|
||||
func TestSetMUCOccupantsLRUSetReplaceOnlyWithSame(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1 := testMUCOccupantsLRUChainOfOne()
|
||||
|
||||
// addition
|
||||
occupants.Set(1, occupant1)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupants.newest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(X)->
|
||||
func TestSetMUCOccupantsLRUDeleteOnly(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1 := testMUCOccupantsLRUChainOfOne()
|
||||
|
||||
// deletion
|
||||
occupants.Delete(1)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != nil ||
|
||||
occupants.newest != nil ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(X)->()->()->
|
||||
func TestSetMUCOccupantsLRUDeleteFirst(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// deletion
|
||||
occupants.Delete(1)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant2 ||
|
||||
occupant2.prev != nil ||
|
||||
occupant2.next != occupant3 ||
|
||||
occupant3.prev != occupant2 ||
|
||||
occupant3.next != nil ||
|
||||
occupants.newest != occupant3 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->(X)->()->
|
||||
func TestSetMUCOccupantsLRUDeleteMiddle(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// deletion
|
||||
occupants.Delete(2)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant3 ||
|
||||
occupant3.prev != occupant1 ||
|
||||
occupant3.next != nil ||
|
||||
occupants.newest != occupant3 ||
|
||||
occupant2.prev != nil ||
|
||||
occupant2.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->()->(X)->
|
||||
func TestSetMUCOccupantsLRUDeleteLast(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// deletion
|
||||
occupants.Delete(3)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant2 ||
|
||||
occupant2.prev != occupant1 ||
|
||||
occupant2.next != nil ||
|
||||
occupants.newest != occupant2 ||
|
||||
occupant3.prev != nil ||
|
||||
occupant3.next != nil {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(.)->
|
||||
func TestSetMUCOccupantsLRUBumpOnly(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1 := testMUCOccupantsLRUChainOfOne()
|
||||
|
||||
// bump
|
||||
occupants.Bump(occupant1)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != nil ||
|
||||
occupants.newest != occupant1 {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->(.)->()->()->
|
||||
func TestSetMUCOccupantsLRUBumpFirst(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// bump
|
||||
occupants.Bump(occupant1)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant2 ||
|
||||
occupant2.prev != nil ||
|
||||
occupant2.next != occupant3 ||
|
||||
occupant3.prev != occupant2 ||
|
||||
occupant3.next != occupant1 ||
|
||||
occupant1.prev != occupant3 ||
|
||||
occupant1.next != nil ||
|
||||
occupants.newest != occupant1 {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->(.)->()->
|
||||
func TestSetMUCOccupantsLRUBumpMiddle(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// bump
|
||||
occupants.Bump(occupant2)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant3 ||
|
||||
occupant3.prev != occupant1 ||
|
||||
occupant3.next != occupant2 ||
|
||||
occupant2.prev != occupant3 ||
|
||||
occupant2.next != nil ||
|
||||
occupants.newest != occupant2 {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
||||
// ->[]->()->()->(.)->
|
||||
func TestSetMUCOccupantsLRUBumpLast(t *testing.T) {
|
||||
// init
|
||||
occupants, occupant1, occupant2, occupant3 := testMUCOccupantsLRUChainOfThree()
|
||||
|
||||
// bump
|
||||
occupants.Bump(occupant3)
|
||||
|
||||
// checks
|
||||
if occupants.oldest != occupant1 ||
|
||||
occupant1.prev != nil ||
|
||||
occupant1.next != occupant2 ||
|
||||
occupant2.prev != occupant1 ||
|
||||
occupant2.next != occupant3 ||
|
||||
occupant3.prev != occupant2 ||
|
||||
occupant3.next != nil ||
|
||||
occupants.newest != occupant3 {
|
||||
t.Error("Broken")
|
||||
}
|
||||
}
|
||||
|
|
@ -565,7 +565,7 @@ func (c *Client) ProcessStatusUpdate(chatID int64, status string, show string, o
|
|||
c.locks.mucCacheLock.Lock()
|
||||
chatJid := gateway.CHATJID(chatID, true)
|
||||
for mucId, state := range c.mucCache {
|
||||
occupant, ok := state.Occupants[chatID]
|
||||
occupant, ok := state.Occupants.Get(chatID)
|
||||
if ok {
|
||||
_, toJids := c.getMUCJoinedJIDs(mucId, state, false)
|
||||
newMucArgs := append(
|
||||
|
|
@ -682,7 +682,7 @@ func (c *Client) sendMUCStatuses(chatID int64) {
|
|||
|
||||
members, err := c.client.SearchChatMembers(&client.SearchChatMembersRequest{
|
||||
ChatId: chatID,
|
||||
Limit: 200,
|
||||
Limit: MUCOccupantsLimit,
|
||||
Filter: &client.ChatMembersFilterMembers{},
|
||||
})
|
||||
if err == nil {
|
||||
|
|
@ -707,12 +707,12 @@ func (c *Client) updateMUCOccupants(mucState *MUCState, chatID int64, members []
|
|||
|
||||
for _, member := range members {
|
||||
senderId, nickname, affiliation, role := c.TgMemberToMUCOccupant(member, chat)
|
||||
mucState.Occupants[senderId] = &MUCOccupant{
|
||||
mucState.Occupants.Set(senderId, &MUCOccupant{
|
||||
Nickname: nickname,
|
||||
Affiliation: affiliation,
|
||||
Role: role,
|
||||
Status: member.Status,
|
||||
}
|
||||
})
|
||||
|
||||
if c.me != nil && senderId == c.me.Id {
|
||||
myNickname = nickname
|
||||
|
|
@ -753,7 +753,7 @@ func (c *Client) mucCacheHasOccupant(mucID int64, memberID int64) bool {
|
|||
return false // no MUC to be added to
|
||||
}
|
||||
|
||||
_, ok = mucState.Occupants[memberID]
|
||||
_, ok = mucState.Occupants.Get(memberID)
|
||||
return ok
|
||||
}
|
||||
|
||||
|
|
@ -780,12 +780,12 @@ func (c *Client) addMUCOccupant(mucID int64, memberID int64, affiliation, role s
|
|||
)
|
||||
|
||||
if err == nil {
|
||||
mucState.Occupants[memberID] = &MUCOccupant{
|
||||
mucState.Occupants.Set(memberID, &MUCOccupant{
|
||||
Nickname: nickname,
|
||||
Affiliation: affiliation,
|
||||
Role: role,
|
||||
Status: status,
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -830,14 +830,14 @@ func (c *Client) updateMUCsNickname(memberID int64, newNickname string) {
|
|||
|
||||
realJid := gateway.CHATJID(memberID, true)
|
||||
for mucId, state := range c.mucCache {
|
||||
oldOccupant, ok := state.Occupants[memberID]
|
||||
oldOccupant, ok := state.Occupants.Get(memberID)
|
||||
if ok {
|
||||
state.Occupants[memberID] = &MUCOccupant{
|
||||
state.Occupants.Set(memberID, &MUCOccupant{
|
||||
Nickname: newNickname,
|
||||
Affiliation: oldOccupant.Affiliation,
|
||||
Role: oldOccupant.Role,
|
||||
Status: oldOccupant.Status,
|
||||
}
|
||||
})
|
||||
|
||||
sMucId := gateway.MUCNODE(mucId)
|
||||
unavailableStatusCodes := []uint16{303, 210}
|
||||
|
|
@ -921,7 +921,7 @@ func (c *Client) GetMyMUCNickname(chatID int64) (string, bool) {
|
|||
if !ok || mucState == nil {
|
||||
return "", false
|
||||
}
|
||||
occupant, ok := mucState.Occupants[c.me.Id]
|
||||
occupant, ok := mucState.Occupants.Get(c.me.Id)
|
||||
if !ok {
|
||||
return "", false
|
||||
}
|
||||
|
|
@ -938,9 +938,9 @@ func (c *Client) GetMUCMemberIdByNickname(chatID int64, nickname string) int64 {
|
|||
return 0
|
||||
}
|
||||
|
||||
for memberId, occupant := range mucState.Occupants {
|
||||
for occupant := range mucState.Occupants.Range() {
|
||||
if occupant.Nickname == nickname {
|
||||
return memberId
|
||||
return occupant.key
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3068,9 +3068,9 @@ func (c *Client) mucOccupantRolePresence(chatID, userID int64, status ChatMember
|
|||
mucState, ok := c.mucCache[chatID]
|
||||
if ok && mucState != nil {
|
||||
if status == ChatMemberStatusKicked || status == ChatMemberStatusBanned {
|
||||
delete(mucState.Occupants, userID)
|
||||
mucState.Occupants.Delete(userID)
|
||||
} else {
|
||||
occupant, ok := mucState.Occupants[userID]
|
||||
occupant, ok := mucState.Occupants.Get(userID)
|
||||
if ok {
|
||||
occupant.Affiliation = newAffiliation
|
||||
occupant.Role = newRole
|
||||
|
|
|
|||
Loading…
Reference in a new issue