mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-22 11:59:40 +01:00
Performance optimization for determining friends in WHO <mask>.
Construct a hash set of the user's channels and check that rather than querying channel membership, to reduce the number of locks that need to be acquired.
This commit is contained in:
parent
b3cfcc1289
commit
a6e4a26cbb
@ -1022,21 +1022,6 @@ func (client *Client) ModeString() (str string) {
|
|||||||
return "+" + client.modes.String()
|
return "+" + client.modes.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsFriend() returns true if the given otherClient shares a channel with this client, or if they are the same user.
|
|
||||||
func (client *Client) IsFriend(otherClient *Client) bool {
|
|
||||||
if client == otherClient {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, channel := range client.Channels() {
|
|
||||||
if channel.hasClient(otherClient) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Friends refers to clients that share a channel with this client.
|
// Friends refers to clients that share a channel with this client.
|
||||||
func (client *Client) Friends(capabs ...caps.Capability) (result map[*Session]bool) {
|
func (client *Client) Friends(capabs ...caps.Capability) (result map[*Session]bool) {
|
||||||
result = make(map[*Session]bool)
|
result = make(map[*Session]bool)
|
||||||
|
@ -2636,8 +2636,28 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Construct set of channels the client is in.
|
||||||
|
userChannels := make(map[*Channel]bool)
|
||||||
|
for _, channel := range client.Channels() {
|
||||||
|
userChannels[channel] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Another client is a friend if they share at least one channel, or they are the same client.
|
||||||
|
isFriend := func(otherClient *Client) bool {
|
||||||
|
if client == otherClient {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, channel := range otherClient.Channels() {
|
||||||
|
if userChannels[channel] {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
for mclient := range server.clients.FindAll(mask) {
|
for mclient := range server.clients.FindAll(mask) {
|
||||||
if isOper || !mclient.HasMode(modes.Invisible) || mclient.IsFriend(client) {
|
if isOper || !mclient.HasMode(modes.Invisible) || isFriend(mclient) {
|
||||||
client.rplWhoReply(nil, mclient, rb)
|
client.rplWhoReply(nil, mclient, rb)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user