Kaynağa Gözat

upgrade to go 1.18, use generics

tags/v2.10.0-rc1
Shivaram Lingamneni 2 yıl önce
ebeveyn
işleme
a549827f17

+ 1
- 1
go.mod Dosyayı Görüntüle

1
 module github.com/ergochat/ergo
1
 module github.com/ergochat/ergo
2
 
2
 
3
-go 1.17
3
+go 1.18
4
 
4
 
5
 require (
5
 require (
6
 	code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48
6
 	code.cloudfoundry.org/bytefmt v0.0.0-20200131002437-cf55d5288a48

+ 1
- 4
irc/channel.go Dosyayı Görüntüle

177
 		info.Bans = channel.lists[modes.BanMask].Masks()
177
 		info.Bans = channel.lists[modes.BanMask].Masks()
178
 		info.Invites = channel.lists[modes.InviteMask].Masks()
178
 		info.Invites = channel.lists[modes.InviteMask].Masks()
179
 		info.Excepts = channel.lists[modes.ExceptMask].Masks()
179
 		info.Excepts = channel.lists[modes.ExceptMask].Masks()
180
-		info.AccountToUMode = make(map[string]modes.Mode)
181
-		for account, mode := range channel.accountToUMode {
182
-			info.AccountToUMode[account] = mode
183
-		}
180
+		info.AccountToUMode = utils.CopyMap(channel.accountToUMode)
184
 	}
181
 	}
185
 
182
 
186
 	if includeFlags&IncludeSettings != 0 {
183
 	if includeFlags&IncludeSettings != 0 {

+ 7
- 7
irc/channelmanager.go Dosyayı Görüntüle

26
 	sync.RWMutex // tier 2
26
 	sync.RWMutex // tier 2
27
 	// chans is the main data structure, mapping casefolded name -> *Channel
27
 	// chans is the main data structure, mapping casefolded name -> *Channel
28
 	chans               map[string]*channelManagerEntry
28
 	chans               map[string]*channelManagerEntry
29
-	chansSkeletons      utils.StringSet // skeletons of *unregistered* chans
30
-	registeredChannels  utils.StringSet // casefolds of registered chans
31
-	registeredSkeletons utils.StringSet // skeletons of registered chans
32
-	purgedChannels      utils.StringSet // casefolds of purged chans
29
+	chansSkeletons      utils.HashSet[string] // skeletons of *unregistered* chans
30
+	registeredChannels  utils.HashSet[string] // casefolds of registered chans
31
+	registeredSkeletons utils.HashSet[string] // skeletons of registered chans
32
+	purgedChannels      utils.HashSet[string] // casefolds of purged chans
33
 	server              *Server
33
 	server              *Server
34
 }
34
 }
35
 
35
 
36
 // NewChannelManager returns a new ChannelManager.
36
 // NewChannelManager returns a new ChannelManager.
37
 func (cm *ChannelManager) Initialize(server *Server) {
37
 func (cm *ChannelManager) Initialize(server *Server) {
38
 	cm.chans = make(map[string]*channelManagerEntry)
38
 	cm.chans = make(map[string]*channelManagerEntry)
39
-	cm.chansSkeletons = make(utils.StringSet)
39
+	cm.chansSkeletons = make(utils.HashSet[string])
40
 	cm.server = server
40
 	cm.server = server
41
 
41
 
42
 	// purging should work even if registration is disabled
42
 	// purging should work even if registration is disabled
66
 	cm.Lock()
66
 	cm.Lock()
67
 	defer cm.Unlock()
67
 	defer cm.Unlock()
68
 
68
 
69
-	cm.registeredChannels = make(utils.StringSet, len(rawNames))
70
-	cm.registeredSkeletons = make(utils.StringSet, len(rawNames))
69
+	cm.registeredChannels = make(utils.HashSet[string], len(rawNames))
70
+	cm.registeredSkeletons = make(utils.HashSet[string], len(rawNames))
71
 	for _, name := range rawNames {
71
 	for _, name := range rawNames {
72
 		cfname, err := CasefoldChannel(name)
72
 		cfname, err := CasefoldChannel(name)
73
 		if err == nil {
73
 		if err == nil {

+ 2
- 2
irc/channelreg.go Dosyayı Görüntüle

145
 }
145
 }
146
 
146
 
147
 // PurgedChannels returns the set of all casefolded channel names that have been purged
147
 // PurgedChannels returns the set of all casefolded channel names that have been purged
148
-func (reg *ChannelRegistry) PurgedChannels() (result utils.StringSet) {
149
-	result = make(utils.StringSet)
148
+func (reg *ChannelRegistry) PurgedChannels() (result utils.HashSet[string]) {
149
+	result = make(utils.HashSet[string])
150
 
150
 
151
 	prefix := fmt.Sprintf(keyChannelPurged, "")
151
 	prefix := fmt.Sprintf(keyChannelPurged, "")
152
 	reg.server.store.View(func(tx *buntdb.Tx) error {
152
 	reg.server.store.View(func(tx *buntdb.Tx) error {

+ 6
- 6
irc/client.go Dosyayı Görüntüle

994
 }
994
 }
995
 
995
 
996
 // Friends refers to clients that share a channel with this client.
996
 // Friends refers to clients that share a channel with this client.
997
-func (client *Client) Friends(capabs ...caps.Capability) (result map[*Session]empty) {
998
-	result = make(map[*Session]empty)
997
+func (client *Client) Friends(capabs ...caps.Capability) (result utils.HashSet[*Session]) {
998
+	result = make(utils.HashSet[*Session])
999
 
999
 
1000
 	// look at the client's own sessions
1000
 	// look at the client's own sessions
1001
 	addFriendsToSet(result, client, capabs...)
1001
 	addFriendsToSet(result, client, capabs...)
1010
 }
1010
 }
1011
 
1011
 
1012
 // Friends refers to clients that share a channel or extended-monitor this client.
1012
 // Friends refers to clients that share a channel or extended-monitor this client.
1013
-func (client *Client) FriendsMonitors(capabs ...caps.Capability) (result map[*Session]empty) {
1013
+func (client *Client) FriendsMonitors(capabs ...caps.Capability) (result utils.HashSet[*Session]) {
1014
 	result = client.Friends(capabs...)
1014
 	result = client.Friends(capabs...)
1015
 	client.server.monitorManager.AddMonitors(result, client.nickCasefolded, capabs...)
1015
 	client.server.monitorManager.AddMonitors(result, client.nickCasefolded, capabs...)
1016
 	return
1016
 	return
1017
 }
1017
 }
1018
 
1018
 
1019
 // helper for Friends
1019
 // helper for Friends
1020
-func addFriendsToSet(set map[*Session]empty, client *Client, capabs ...caps.Capability) {
1020
+func addFriendsToSet(set utils.HashSet[*Session], client *Client, capabs ...caps.Capability) {
1021
 	client.stateMutex.RLock()
1021
 	client.stateMutex.RLock()
1022
 	defer client.stateMutex.RUnlock()
1022
 	defer client.stateMutex.RUnlock()
1023
 	for _, session := range client.sessions {
1023
 	for _, session := range client.sessions {
1024
 		if session.capabilities.HasAll(capabs...) {
1024
 		if session.capabilities.HasAll(capabs...) {
1025
-			set[session] = empty{}
1025
+			set.Add(session)
1026
 		}
1026
 		}
1027
 	}
1027
 	}
1028
 }
1028
 }
1575
 	} else if client.oper == nil && len(client.channels) >= config.Channels.MaxChannelsPerClient {
1575
 	} else if client.oper == nil && len(client.channels) >= config.Channels.MaxChannelsPerClient {
1576
 		err = errTooManyChannels
1576
 		err = errTooManyChannels
1577
 	} else {
1577
 	} else {
1578
-		client.channels[channel] = empty{} // success
1578
+		client.channels.Add(channel) // success
1579
 	}
1579
 	}
1580
 	client.stateMutex.Unlock()
1580
 	client.stateMutex.Unlock()
1581
 
1581
 

+ 1
- 1
irc/client_test.go Dosyayı Görüntüle

11
 
11
 
12
 func TestGenerateBatchID(t *testing.T) {
12
 func TestGenerateBatchID(t *testing.T) {
13
 	var session Session
13
 	var session Session
14
-	s := make(utils.StringSet)
14
+	s := make(utils.HashSet[string])
15
 
15
 
16
 	count := 100000
16
 	count := 100000
17
 	for i := 0; i < count; i++ {
17
 	for i := 0; i < count; i++ {

+ 3
- 3
irc/config.go Dosyayı Görüntüle

704
 // OperClass defines an assembled operator class.
704
 // OperClass defines an assembled operator class.
705
 type OperClass struct {
705
 type OperClass struct {
706
 	Title        string
706
 	Title        string
707
-	WhoisLine    string          `yaml:"whois-line"`
708
-	Capabilities utils.StringSet // map to make lookups much easier
707
+	WhoisLine    string                `yaml:"whois-line"`
708
+	Capabilities utils.HashSet[string] // map to make lookups much easier
709
 }
709
 }
710
 
710
 
711
 // OperatorClasses returns a map of assembled operator classes from the given config.
711
 // OperatorClasses returns a map of assembled operator classes from the given config.
743
 
743
 
744
 			// create new operclass
744
 			// create new operclass
745
 			var oc OperClass
745
 			var oc OperClass
746
-			oc.Capabilities = make(utils.StringSet)
746
+			oc.Capabilities = make(utils.HashSet[string])
747
 
747
 
748
 			// get inhereted info from other operclasses
748
 			// get inhereted info from other operclasses
749
 			if len(info.Extends) > 0 {
749
 			if len(info.Extends) > 0 {

+ 2
- 2
irc/handlers.go Dosyayı Görüntüle

3424
 		// Construct set of channels the client is in.
3424
 		// Construct set of channels the client is in.
3425
 		userChannels := make(ChannelSet)
3425
 		userChannels := make(ChannelSet)
3426
 		for _, channel := range client.Channels() {
3426
 		for _, channel := range client.Channels() {
3427
-			userChannels[channel] = empty{}
3427
+			userChannels.Add(channel)
3428
 		}
3428
 		}
3429
 
3429
 
3430
 		// Another client is a friend if they share at least one channel, or they are the same client.
3430
 		// Another client is a friend if they share at least one channel, or they are the same client.
3437
 				if channel.flags.HasMode(modes.Auditorium) {
3437
 				if channel.flags.HasMode(modes.Auditorium) {
3438
 					return false // TODO this should respect +v etc.
3438
 					return false // TODO this should respect +v etc.
3439
 				}
3439
 				}
3440
-				if _, present := userChannels[channel]; present {
3440
+				if userChannels.Has(channel) {
3441
 					return true
3441
 					return true
3442
 				}
3442
 				}
3443
 			}
3443
 			}

+ 1
- 1
irc/history/history.go Dosyayı Görüntüle

203
 
203
 
204
 // returns all correspondents, in reverse time order
204
 // returns all correspondents, in reverse time order
205
 func (list *Buffer) allCorrespondents() (results []TargetListing) {
205
 func (list *Buffer) allCorrespondents() (results []TargetListing) {
206
-	seen := make(utils.StringSet)
206
+	seen := make(utils.HashSet[string])
207
 
207
 
208
 	list.RLock()
208
 	list.RLock()
209
 	defer list.RUnlock()
209
 	defer list.RUnlock()

+ 2
- 2
irc/import.go Dosyayı Görüntüle

54
 	Channels map[string]channelImport
54
 	Channels map[string]channelImport
55
 }
55
 }
56
 
56
 
57
-func serializeAmodes(raw map[string]string, validCfUsernames utils.StringSet) (result []byte, err error) {
57
+func serializeAmodes(raw map[string]string, validCfUsernames utils.HashSet[string]) (result []byte, err error) {
58
 	processed := make(map[string]int, len(raw))
58
 	processed := make(map[string]int, len(raw))
59
 	for accountName, mode := range raw {
59
 	for accountName, mode := range raw {
60
 		if len(mode) != 1 {
60
 		if len(mode) != 1 {
80
 	tx.Set(keySchemaVersion, strconv.Itoa(importDBSchemaVersion), nil)
80
 	tx.Set(keySchemaVersion, strconv.Itoa(importDBSchemaVersion), nil)
81
 	tx.Set(keyCloakSecret, utils.GenerateSecretKey(), nil)
81
 	tx.Set(keyCloakSecret, utils.GenerateSecretKey(), nil)
82
 
82
 
83
-	cfUsernames := make(utils.StringSet)
83
+	cfUsernames := make(utils.HashSet[string])
84
 	skeletonToUsername := make(map[string]string)
84
 	skeletonToUsername := make(map[string]string)
85
 	warnSkeletons := false
85
 	warnSkeletons := false
86
 
86
 

+ 9
- 8
irc/monitor.go Dosyayı Görüntüle

7
 	"sync"
7
 	"sync"
8
 
8
 
9
 	"github.com/ergochat/ergo/irc/caps"
9
 	"github.com/ergochat/ergo/irc/caps"
10
+	"github.com/ergochat/ergo/irc/utils"
10
 
11
 
11
 	"github.com/ergochat/irc-go/ircmsg"
12
 	"github.com/ergochat/irc-go/ircmsg"
12
 )
13
 )
17
 	// client -> (casefolded nick it's watching -> uncasefolded nick)
18
 	// client -> (casefolded nick it's watching -> uncasefolded nick)
18
 	watching map[*Session]map[string]string
19
 	watching map[*Session]map[string]string
19
 	// casefolded nick -> clients watching it
20
 	// casefolded nick -> clients watching it
20
-	watchedby map[string]map[*Session]empty
21
+	watchedby map[string]utils.HashSet[*Session]
21
 }
22
 }
22
 
23
 
23
 func (mm *MonitorManager) Initialize() {
24
 func (mm *MonitorManager) Initialize() {
24
 	mm.watching = make(map[*Session]map[string]string)
25
 	mm.watching = make(map[*Session]map[string]string)
25
-	mm.watchedby = make(map[string]map[*Session]empty)
26
+	mm.watchedby = make(map[string]utils.HashSet[*Session])
26
 }
27
 }
27
 
28
 
28
 // AddMonitors adds clients using extended-monitor monitoring `client`'s nick to the passed user set.
29
 // AddMonitors adds clients using extended-monitor monitoring `client`'s nick to the passed user set.
29
-func (manager *MonitorManager) AddMonitors(users map[*Session]empty, cfnick string, capabs ...caps.Capability) {
30
+func (manager *MonitorManager) AddMonitors(users utils.HashSet[*Session], cfnick string, capabs ...caps.Capability) {
30
 	manager.RLock()
31
 	manager.RLock()
31
 	defer manager.RUnlock()
32
 	defer manager.RUnlock()
32
 	for session := range manager.watchedby[cfnick] {
33
 	for session := range manager.watchedby[cfnick] {
33
 		if session.capabilities.Has(caps.ExtendedMonitor) && session.capabilities.HasAll(capabs...) {
34
 		if session.capabilities.Has(caps.ExtendedMonitor) && session.capabilities.HasAll(capabs...) {
34
-			users[session] = empty{}
35
+			users.Add(session)
35
 		}
36
 		}
36
 	}
37
 	}
37
 }
38
 }
70
 		manager.watching[session] = make(map[string]string)
71
 		manager.watching[session] = make(map[string]string)
71
 	}
72
 	}
72
 	if manager.watchedby[cfnick] == nil {
73
 	if manager.watchedby[cfnick] == nil {
73
-		manager.watchedby[cfnick] = make(map[*Session]empty)
74
+		manager.watchedby[cfnick] = make(utils.HashSet[*Session])
74
 	}
75
 	}
75
 
76
 
76
 	if len(manager.watching[session]) >= limit {
77
 	if len(manager.watching[session]) >= limit {
78
 	}
79
 	}
79
 
80
 
80
 	manager.watching[session][cfnick] = nick
81
 	manager.watching[session][cfnick] = nick
81
-	manager.watchedby[cfnick][session] = empty{}
82
+	manager.watchedby[cfnick].Add(session)
82
 	return nil
83
 	return nil
83
 }
84
 }
84
 
85
 
92
 	manager.Lock()
93
 	manager.Lock()
93
 	defer manager.Unlock()
94
 	defer manager.Unlock()
94
 	delete(manager.watching[session], cfnick)
95
 	delete(manager.watching[session], cfnick)
95
-	delete(manager.watchedby[cfnick], session)
96
+	manager.watchedby[cfnick].Remove(session)
96
 	return nil
97
 	return nil
97
 }
98
 }
98
 
99
 
102
 	defer manager.Unlock()
103
 	defer manager.Unlock()
103
 
104
 
104
 	for cfnick := range manager.watching[session] {
105
 	for cfnick := range manager.watching[session] {
105
-		delete(manager.watchedby[cfnick], session)
106
+		manager.watchedby[cfnick].Remove(session)
106
 	}
107
 	}
107
 	delete(manager.watching, session)
108
 	delete(manager.watching, session)
108
 }
109
 }

+ 2
- 2
irc/nickname.go Dosyayı Görüntüle

24
 		"MemoServ", "BotServ", "OperServ",
24
 		"MemoServ", "BotServ", "OperServ",
25
 	}
25
 	}
26
 
26
 
27
-	restrictedCasefoldedNicks = make(utils.StringSet)
28
-	restrictedSkeletons       = make(utils.StringSet)
27
+	restrictedCasefoldedNicks = make(utils.HashSet[string])
28
+	restrictedSkeletons       = make(utils.HashSet[string])
29
 )
29
 )
30
 
30
 
31
 func performNickChange(server *Server, client *Client, target *Client, session *Session, nickname string, rb *ResponseBuffer) error {
31
 func performNickChange(server *Server, client *Client, target *Client, session *Session, nickname string, rb *ResponseBuffer) error {

+ 3
- 20
irc/types.go Dosyayı Görüntüle

9
 	"time"
9
 	"time"
10
 
10
 
11
 	"github.com/ergochat/ergo/irc/modes"
11
 	"github.com/ergochat/ergo/irc/modes"
12
+	"github.com/ergochat/ergo/irc/utils"
12
 )
13
 )
13
 
14
 
14
-type empty struct{}
15
-
16
 // ClientSet is a set of clients.
15
 // ClientSet is a set of clients.
17
-type ClientSet map[*Client]empty
18
-
19
-// Add adds the given client to this set.
20
-func (clients ClientSet) Add(client *Client) {
21
-	clients[client] = empty{}
22
-}
23
-
24
-// Remove removes the given client from this set.
25
-func (clients ClientSet) Remove(client *Client) {
26
-	delete(clients, client)
27
-}
28
-
29
-// Has returns true if the given client is in this set.
30
-func (clients ClientSet) Has(client *Client) bool {
31
-	_, ok := clients[client]
32
-	return ok
33
-}
16
+type ClientSet = utils.HashSet[*Client]
34
 
17
 
35
 type memberData struct {
18
 type memberData struct {
36
 	modes    *modes.ModeSet
19
 	modes    *modes.ModeSet
60
 }
43
 }
61
 
44
 
62
 // ChannelSet is a set of channels.
45
 // ChannelSet is a set of channels.
63
-type ChannelSet map[*Channel]empty
46
+type ChannelSet = utils.HashSet[*Channel]

+ 17
- 5
irc/utils/types.go Dosyayı Görüntüle

5
 
5
 
6
 type empty struct{}
6
 type empty struct{}
7
 
7
 
8
-type StringSet map[string]empty
8
+type HashSet[T comparable] map[T]empty
9
 
9
 
10
-func (s StringSet) Has(str string) bool {
11
-	_, ok := s[str]
10
+func (s HashSet[T]) Has(elem T) bool {
11
+	_, ok := s[elem]
12
 	return ok
12
 	return ok
13
 }
13
 }
14
 
14
 
15
-func (s StringSet) Add(str string) {
16
-	s[str] = empty{}
15
+func (s HashSet[T]) Add(elem T) {
16
+	s[elem] = empty{}
17
+}
18
+
19
+func (s HashSet[T]) Remove(elem T) {
20
+	delete(s, elem)
21
+}
22
+
23
+func CopyMap[K comparable, V any](input map[K]V) (result map[K]V) {
24
+	result = make(map[K]V, len(input))
25
+	for key, value := range input {
26
+		result[key] = value
27
+	}
28
+	return
17
 }
29
 }

+ 3
- 3
irc/znc.go Dosyayı Görüntüle

74
 type zncPlaybackTimes struct {
74
 type zncPlaybackTimes struct {
75
 	start   time.Time
75
 	start   time.Time
76
 	end     time.Time
76
 	end     time.Time
77
-	targets utils.StringSet // nil for "*" (everything), otherwise the channel names
77
+	targets utils.HashSet[string] // nil for "*" (everything), otherwise the channel names
78
 	setAt   time.Time
78
 	setAt   time.Time
79
 }
79
 }
80
 
80
 
134
 		end = zncWireTimeToTime(params[3])
134
 		end = zncWireTimeToTime(params[3])
135
 	}
135
 	}
136
 
136
 
137
-	var targets utils.StringSet
137
+	var targets utils.HashSet[string]
138
 	var nickTargets []string
138
 	var nickTargets []string
139
 
139
 
140
 	// three cases:
140
 	// three cases:
157
 	if params[1] == "*" {
157
 	if params[1] == "*" {
158
 		playPrivmsgs = true // XXX nil `targets` means "every channel"
158
 		playPrivmsgs = true // XXX nil `targets` means "every channel"
159
 	} else {
159
 	} else {
160
-		targets = make(utils.StringSet)
160
+		targets = make(utils.HashSet[string])
161
 		for _, targetName := range strings.Split(targetString, ",") {
161
 		for _, targetName := range strings.Split(targetString, ",") {
162
 			if strings.HasPrefix(targetName, "#") {
162
 			if strings.HasPrefix(targetName, "#") {
163
 				if cfTarget, err := CasefoldChannel(targetName); err == nil {
163
 				if cfTarget, err := CasefoldChannel(targetName); err == nil {

Loading…
İptal
Kaydet