diff --git a/server/matchmaker.go b/server/matchmaker.go index 6362491893fdeca2a3da256112d288248d8307f2..208f7ac38fd890b2c778717045ee074cbc7596e1 100644 --- a/server/matchmaker.go +++ b/server/matchmaker.go @@ -201,13 +201,19 @@ type LocalMatchmaker struct { matchedEntriesFn func([][]*MatchmakerEntry) batch *index.Batch indexWriter *bluge.Writer - sessionTickets map[string]map[string]struct{} - partyTickets map[string]map[string]struct{} - entries map[string][]*MatchmakerEntry - indexes map[string]*MatchmakerIndex - activeIndexes map[string]*MatchmakerIndex - revCache map[string]map[string]bool - revThresholdFn func() *time.Timer + // All tickets for a session ID. + sessionTickets map[string]map[string]struct{} + // All tickets for a party ID. + partyTickets map[string]map[string]struct{} + // All entries for a given ticket. + entries map[string][]*MatchmakerEntry + // Index for each ticket. + indexes map[string]*MatchmakerIndex + // Indexes that have not yet reached their max interval count. + activeIndexes map[string]*MatchmakerIndex + // Reverse lookup cache for mutual matching. + revCache map[string]map[string]bool + revThresholdFn func() *time.Timer } func NewLocalMatchmaker(logger, startupLogger *zap.Logger, config Config, router MessageRouter, metrics Metrics, runtime *Runtime) Matchmaker { @@ -486,6 +492,7 @@ func (m *LocalMatchmaker) Process() { break } } + // Either processing first hit, or current hit entries combined with previous hits may tip over index.MaxCount. if foundCombo == nil { entryCombo := make([]*MatchmakerEntry, len(entries)) copy(entryCombo, entries) @@ -505,15 +512,20 @@ func (m *LocalMatchmaker) Process() { // The size of the combination being considered does not satisfy the count multiple. // Attempt to adjust the combo by removing the smallest possible number of entries. // Prefer keeping entries that have been in the matchmaker the longest, if possible. - eligibleIndexes := make([]*MatchmakerIndex, 0, len(foundCombo)) + eligibleIndexesUniq := make(map[*MatchmakerIndex]struct{}, len(foundCombo)) for _, e := range foundCombo { // Only tickets individually less <= the removable size are considered. // For example removing a party of 3 when we're only looking to remove 2 is not allowed. if foundIndex, ok := m.indexes[e.Ticket]; ok && foundIndex.Count <= rem { - eligibleIndexes = append(eligibleIndexes, foundIndex) + eligibleIndexesUniq[foundIndex] = struct{}{} } } + eligibleIndexes := make([]*MatchmakerIndex, 0, len(eligibleIndexesUniq)) + for _, egi := range eligibleIndexes { + eligibleIndexes = append(eligibleIndexes, egi) + } + eligibleGroups := groupIndexes(eligibleIndexes, rem) if len(eligibleGroups) <= 0 { // No possible combination to remove, unlikely but guard. @@ -530,7 +542,7 @@ func (m *LocalMatchmaker) Process() { foundCombo[i] = foundCombo[len(foundCombo)-1] foundCombo[len(foundCombo)-1] = nil foundCombo = foundCombo[:len(foundCombo)-1] - break + i-- } } }