/// <summary> /// Final time-consuming call to look at all team entries and merge where appropriate. /// </summary> /// <returns> /// A dictionary of merged team ids keyed by the newest id to become the value of the pre-known id. /// Empty dictionary = no work done. /// </returns> public static IDictionary <Guid, Guid> FinaliseTeams(IReadOnlyCollection <Player> allPlayers, List <Team> teamsToMutate) { var mergeResult = new Dictionary <Guid, Guid>(); var indexesToRemove = new List <int>(); logger.ConditionalDebug($"Beginning {nameof(FinaliseTeams)} on {teamsToMutate.Count} entries."); int lastProgressBars = -1; for (int i = teamsToMutate.Count - 1; i >= 0; --i) { var newerTeamRecord = teamsToMutate[i]; // Try match teams. Team?foundOlderTeamRecord = null; for (int j = 0; j < i; ++j) { var olderTeamRecord = teamsToMutate[j]; if (Matcher.TeamsMatch(allPlayers, olderTeamRecord, newerTeamRecord)) { // Quick check that the team is definitely older if (olderTeamRecord.CompareToBySourceAscending(newerTeamRecord) == 1) { // Swap the instances round logger.ConditionalDebug($"Newer team is not newer, swapping {newerTeamRecord} with {olderTeamRecord}."); (newerTeamRecord, olderTeamRecord) = (teamsToMutate[i], teamsToMutate[j]) = (olderTeamRecord, newerTeamRecord); } foundOlderTeamRecord = olderTeamRecord; break; } } // If an older team was found, merge it. if (foundOlderTeamRecord != null) { logger.ConditionalDebug($"Merging newer team {newerTeamRecord} into {foundOlderTeamRecord} and deleting index [{i}]."); MergeExistingTeam(mergeResult, newerTeamRecord, foundOlderTeamRecord); // Remove the newer record (the older record persists) indexesToRemove.Add(i); logger.ConditionalDebug($"Resultant team: {foundOlderTeamRecord}."); } int progressBars = ProgressBar.CalculateProgressBars(teamsToMutate.Count - i, teamsToMutate.Count, 100); if (progressBars != lastProgressBars) { string progressBar = ProgressBar.GetProgressBar(progressBars, 100, false) + " " + i + "/" + teamsToMutate.Count; logger.Info(progressBar); lastProgressBars = progressBars; } } logger.ConditionalDebug($"{nameof(FinaliseTeams)}: Remaking teams list {teamsToMutate.Count} --> {teamsToMutate.Count - indexesToRemove.Count} entries."); teamsToMutate.RemoveAtRange(indexesToRemove); logger.ConditionalDebug($"Finished {nameof(FinaliseTeams)} with {teamsToMutate.Count} entries."); return(mergeResult); }
/// <summary> /// Final time-consuming call to look at all player entries and merge where appropriate. /// </summary> /// <param name="playersToMutate">List of players to change</param> /// <returns>Any work done (true, should loop) or No work done (false, can stop)</returns> public static bool FinalisePlayers(List <Player> playersToMutate) { bool workDone = false; if (playersToMutate == null) { return(workDone); } var indexesToRemove = new List <int>(); string logMessage = $"Beginning {nameof(FinalisePlayers)} on {playersToMutate.Count} entries."; logger.ConditionalDebug(logMessage); int lastProgressBars = -1; int length = playersToMutate.Count - 1; for (int i = length; i >= 0; --i) { // This is the player record that we are modifying var newerPlayerRecord = playersToMutate[i]; // First, try match through persistent information only. Player?foundOlderPlayerRecord = null; for (int j = 0; j < i; ++j) { // This is the player record that we are checking against. var olderPlayerRecord = playersToMutate[j]; if (Matcher.PlayersMatch(olderPlayerRecord, newerPlayerRecord, FilterOptions.Persistent)) { // Quick check that the player is definitely older // This happens when a merge has already happened, but the dates then go out of order. if (olderPlayerRecord.CompareToBySourceAscending(newerPlayerRecord) == 1) { // Swap the instances round logger.ConditionalDebug($"Newer player is not newer, swapping {newerPlayerRecord} with {olderPlayerRecord} (Persistent)."); (newerPlayerRecord, olderPlayerRecord) = (playersToMutate[i], playersToMutate[j]) = (olderPlayerRecord, newerPlayerRecord); } foundOlderPlayerRecord = olderPlayerRecord; break; } // else // If that doesn't work, try and match a name and same team. if (foundOlderPlayerRecord == null && Matcher.PlayersMatch(olderPlayerRecord, newerPlayerRecord, FilterOptions.PlayerName)) { if (olderPlayerRecord.CompareToBySourceAscending(newerPlayerRecord) == 1) { logger.ConditionalDebug($"Newer player is not newer, swapping {newerPlayerRecord} with {olderPlayerRecord} (PlayerName)."); (newerPlayerRecord, olderPlayerRecord) = (playersToMutate[i], playersToMutate[j]) = (olderPlayerRecord, newerPlayerRecord); } foundOlderPlayerRecord = olderPlayerRecord; // no break -- we want to continue searching all Persistent records first // however by assigning foundPlayer, we've earmarked this entry so we don't have to iterate again } } // If a player has now been found, merge it. if (foundOlderPlayerRecord != null) { logger.ConditionalDebug($"Merging player {newerPlayerRecord} from sources [{string.Join(", ", newerPlayerRecord.Sources)}] into {foundOlderPlayerRecord} from sources [{string.Join(", ", foundOlderPlayerRecord.Sources)}]."); foundOlderPlayerRecord.Merge(newerPlayerRecord); indexesToRemove.Add(i); workDone = true; } // -i because we're counting backwards int progressBars = ProgressBar.CalculateProgressBars(playersToMutate.Count - i, playersToMutate.Count, 100); if (progressBars != lastProgressBars) { string progressBar = ProgressBar.GetProgressBar(progressBars, 100, false) + " " + i + "/" + playersToMutate.Count; logger.Info(progressBar); lastProgressBars = progressBars; } } logger.ConditionalDebug($"{nameof(FinalisePlayers)}: Remaking players list {playersToMutate.Count} --> {playersToMutate.Count - indexesToRemove.Count} entries."); playersToMutate.RemoveAtRange(indexesToRemove); return(workDone); }