Changeset 350 in code for trunk/irc.go


Ignore:
Timestamp:
Jul 6, 2020, 9:06:20 AM (5 years ago)
Author:
contact
Message:

Sort and split JOIN messages

Sort channels so that channels with a key appear first. Split JOIN
messages so that we don't reach the message size limit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/irc.go

    r346 r350  
    33import (
    44        "fmt"
     5        "sort"
    56        "strings"
    67
     
    1819
    1920const maxMessageLength = 512
     21
     22// The server-time layout, as defined in the IRCv3 spec.
     23const serverTimeLayout = "2006-01-02T15:04:05.000Z"
    2024
    2125type userModes string
     
    294298}
    295299
    296 // The server-time layout, as defined in the IRCv3 spec.
    297 const serverTimeLayout = "2006-01-02T15:04:05.000Z"
     300func join(channels, keys []string) []*irc.Message {
     301        // Put channels with a key first
     302        js := joinSorter{channels, keys}
     303        sort.Sort(&js)
     304
     305        // Two spaces because there are three words (JOIN, channels and keys)
     306        maxLength := maxMessageLength - (len("JOIN") + 2)
     307
     308        var msgs []*irc.Message
     309        var channelsBuf, keysBuf strings.Builder
     310        for i, channel := range channels {
     311                key := keys[i]
     312
     313                n := channelsBuf.Len() + keysBuf.Len() + 1 + len(channel)
     314                if key != "" {
     315                        n += 1 + len(key)
     316                }
     317
     318                if channelsBuf.Len() > 0 && n > maxLength {
     319                        // No room for the new channel in this message
     320                        params := []string{channelsBuf.String()}
     321                        if keysBuf.Len() > 0 {
     322                                params = append(params, keysBuf.String())
     323                        }
     324                        msgs = append(msgs, &irc.Message{Command: "JOIN", Params: params})
     325                        channelsBuf.Reset()
     326                        keysBuf.Reset()
     327                }
     328
     329                if channelsBuf.Len() > 0 {
     330                        channelsBuf.WriteByte(',')
     331                }
     332                channelsBuf.WriteString(channel)
     333                if key != "" {
     334                        if keysBuf.Len() > 0 {
     335                                keysBuf.WriteByte(',')
     336                        }
     337                        keysBuf.WriteString(key)
     338                }
     339        }
     340        if channelsBuf.Len() > 0 {
     341                params := []string{channelsBuf.String()}
     342                if keysBuf.Len() > 0 {
     343                        params = append(params, keysBuf.String())
     344                }
     345                msgs = append(msgs, &irc.Message{Command: "JOIN", Params: params})
     346        }
     347
     348        return msgs
     349}
     350
     351type joinSorter struct {
     352        channels []string
     353        keys     []string
     354}
     355
     356func (js *joinSorter) Len() int {
     357        return len(js.channels)
     358}
     359
     360func (js *joinSorter) Less(i, j int) bool {
     361        if (js.keys[i] != "") != (js.keys[j] != "") {
     362                // Only one of the channels has a key
     363                return js.keys[i] != ""
     364        }
     365        return js.channels[i] < js.channels[j]
     366}
     367
     368func (js *joinSorter) Swap(i, j int) {
     369        js.channels[i], js.channels[j] = js.channels[j], js.channels[i]
     370        js.keys[i], js.keys[j] = js.keys[j], js.keys[i]
     371}
Note: See TracChangeset for help on using the changeset viewer.