Skip to content

Commit bad593d

Browse files
authored
Greatly reduce time cost on loading custom map cache (CnCNet#937)
1 parent 7df7f27 commit bad593d

1 file changed

Lines changed: 40 additions & 24 deletions

File tree

DXMainClient/Domain/Multiplayer/MapLoader.cs

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -454,44 +454,60 @@ private void LoadCustomMaps()
454454

455455
Logger.Log("MapLoader: Finished loading custom map cache. Processing uncached custom maps...");
456456

457-
var localMapPaths = new ConcurrentBag<string>();
458-
459-
Task[] tasks = mapFiles.Select(mapFile => Task.Run(() =>
457+
List<string> localMapPaths;
460458
{
461-
string baseFilePath = mapFile.FullName.Substring(ProgramConstants.GamePath.Length);
462-
baseFilePath = baseFilePath.Substring(0, baseFilePath.Length - 4);
459+
ConcurrentBag<string> localMapPathsConcurrentBag = [];
460+
461+
int mapFileExtensionWithDotLength = $".{ClientConfiguration.Instance.MapFileExtension}".Length;
462+
463+
Task[] tasks = mapFiles.Select(mapFile => Task.Run(() =>
464+
{
465+
string baseFilePath = mapFile.FullName.Substring(ProgramConstants.GamePath.Length);
466+
baseFilePath = baseFilePath.Substring(0, baseFilePath.Length - mapFileExtensionWithDotLength);
463467

464-
string normalizedPath = baseFilePath
465-
.Replace(Path.DirectorySeparatorChar, '/')
466-
.Replace(Path.AltDirectorySeparatorChar, '/');
468+
string normalizedPath = baseFilePath
469+
.Replace(Path.DirectorySeparatorChar, '/')
470+
.Replace(Path.AltDirectorySeparatorChar, '/');
471+
472+
localMapPathsConcurrentBag.Add(normalizedPath);
473+
474+
if (customMapCache.Items.TryGetValue(normalizedPath, out var cachedItem) && !cachedItem.IsOutdated())
475+
{
476+
// Use cached map
477+
return;
478+
}
467479

468-
localMapPaths.Add(normalizedPath);
480+
// Not in cache or outdated
481+
var map = new Map(normalizedPath, true);
482+
if (map.InitializeFromCustomMap())
483+
customMapCache.Items[normalizedPath] = new CustomMapCache.Item(map);
484+
})).ToArray();
469485

470-
if (customMapCache.Items.TryGetValue(normalizedPath, out var cachedItem) && !cachedItem.IsOutdated())
486+
while (!Task.WaitAll(tasks, millisecondsTimeout: 1000))
471487
{
472-
// Use cached map
473-
return;
488+
string message = "MapLoader: Waiting for the custom map loading task to complete. Remaining files: " + tasks.Count(t => !t.IsCompleted) + ". Total: " + tasks.Length;
489+
Debug.WriteLine(message);
490+
Logger.Log(message);
474491
}
475492

476-
// Not in cache or outdated
477-
var map = new Map(normalizedPath, true);
478-
if (map.InitializeFromCustomMap())
479-
customMapCache.Items[normalizedPath] = new CustomMapCache.Item(map);
480-
})).ToArray();
481-
482-
while (!Task.WaitAll(tasks, millisecondsTimeout: 1000))
483-
{
484-
string message = "MapLoader: Waiting for the custom map loading task to complete. Remaining files: " + tasks.Count(t => !t.IsCompleted) + ". Total: " + tasks.Length;
485-
Debug.WriteLine(message);
486-
Logger.Log(message);
493+
localMapPaths = localMapPathsConcurrentBag.ToList();
487494
}
488495

489496
Logger.Log("MapLoader: Finished processing uncached custom maps.");
490497

491498
// remove cached maps that no longer exist locally
492499
Logger.Log("MapLoader: Removing outdated maps from cache...");
493-
foreach (var missingPath in customMapCache.Items.Keys.Where(cachedPath => !localMapPaths.Contains(cachedPath)))
500+
501+
HashSet<string> missingMapPaths;
502+
{
503+
HashSet<string> cachedMapPaths = customMapCache.Items.Keys.ToHashSet();
504+
cachedMapPaths.ExceptWith(localMapPaths);
505+
missingMapPaths = cachedMapPaths;
506+
}
507+
508+
foreach (string missingPath in missingMapPaths)
494509
customMapCache.Items.TryRemove(missingPath, out _);
510+
495511
Logger.Log("MapLoader: Finished removing outdated maps from cache.");
496512

497513
// save cache

0 commit comments

Comments
 (0)