Switch UserPerms to cmap and fix panic

This commit is contained in:
kayos@tcp.direct 2022-07-11 22:36:36 -07:00
parent 61ef265c6c
commit 32f2b078c3
Signed by: kayos
GPG Key ID: 4B841471B4BEE979
4 changed files with 16 additions and 20 deletions

2
go.mod

@ -6,3 +6,5 @@ require (
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de
github.com/orcaman/concurrent-map v1.0.0 github.com/orcaman/concurrent-map v1.0.0
) )
require github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece // indirect

2
go.sum

@ -2,6 +2,8 @@ github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhP
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw= github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de/go.mod h1:DCaWoUhZrYW9p1lxo/cm8EmUOOzAPSEZNGF2DK1dJgw=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece h1:6BGhEtGBmkgr8TKLjMBBMpvM/fK0GHj4prrkK1tYPcA=
github.com/dvyukov/go-fuzz v0.0.0-20220220162807-a217d9bdbece/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY= github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=

@ -7,7 +7,8 @@ package girc
import ( import (
"encoding/json" "encoding/json"
"strings" "strings"
"sync"
cmap "github.com/orcaman/concurrent-map"
) )
// CMode represents a single step of a given mode change. // CMode represents a single step of a given mode change.
@ -395,50 +396,41 @@ func (s *state) userPrefixes() string {
// UserPerms contains all of the permissions for each channel the user is // UserPerms contains all of the permissions for each channel the user is
// in. // in.
type UserPerms struct { type UserPerms struct {
mu sync.RWMutex channels cmap.ConcurrentMap
channels map[string]Perms
} }
// Copy returns a deep copy of the channel permissions. // Copy returns a deep copy of the channel permissions.
func (p *UserPerms) Copy() (perms *UserPerms) { func (p *UserPerms) Copy() (perms *UserPerms) {
np := &UserPerms{ np := &UserPerms{
channels: make(map[string]Perms), channels: cmap.New(),
} }
for key := range p.channels { for tuple := range p.channels.IterBuffered() {
np.channels[key] = p.channels[key] np.channels.Set(tuple.Key, tuple.Val)
} }
return np return np
} }
// MarshalJSON implements json.Marshaler. // MarshalJSON implements json.Marshaler.
func (p *UserPerms) MarshalJSON() ([]byte, error) { func (p *UserPerms) MarshalJSON() ([]byte, error) {
p.mu.Lock()
out, err := json.Marshal(&p.channels) out, err := json.Marshal(&p.channels)
p.mu.Unlock()
return out, err return out, err
} }
// Lookup looks up the users permissions for a given channel. ok is false // Lookup looks up the users permissions for a given channel. ok is false
// if the user is not in the given channel. // if the user is not in the given channel.
func (p *UserPerms) Lookup(channel string) (perms Perms, ok bool) { func (p *UserPerms) Lookup(channel string) (perms Perms, ok bool) {
p.mu.RLock() var permsi interface{}
defer p.mu.RUnlock() permsi, ok = p.channels.Get(ToRFC1459(channel))
perms, ok = p.channels[ToRFC1459(channel)] perms = permsi.(Perms)
return perms, ok return perms, ok
} }
func (p *UserPerms) set(channel string, perms Perms) { func (p *UserPerms) set(channel string, perms Perms) {
p.mu.Lock() p.channels.Set(ToRFC1459(channel), perms)
p.channels[ToRFC1459(channel)] = perms
p.mu.Unlock()
} }
func (p *UserPerms) remove(channel string) { func (p *UserPerms) remove(channel string) {
p.mu.Lock() p.channels.Remove(ToRFC1459(channel))
delete(p.channels, ToRFC1459(channel))
p.mu.Unlock()
} }
// Perms contains all channel-based user permissions. The minimum op, and // Perms contains all channel-based user permissions. The minimum op, and

@ -459,7 +459,7 @@ func (s *state) createUser(src *Source) (u *User, ok bool) {
FirstSeen: time.Now(), FirstSeen: time.Now(),
LastActive: time.Now(), LastActive: time.Now(),
Network: s.client.NetworkName(), Network: s.client.NetworkName(),
Perms: &UserPerms{channels: make(map[string]Perms)}, Perms: &UserPerms{channels: cmap.New()},
} }
s.users.Set(src.ID(), u) s.users.Set(src.ID(), u)