diff --git a/MergerLogic/DataTypes/Data.cs b/MergerLogic/DataTypes/Data.cs index b6f485df..22e4b1e2 100644 --- a/MergerLogic/DataTypes/Data.cs +++ b/MergerLogic/DataTypes/Data.cs @@ -3,6 +3,7 @@ using MergerLogic.Utils; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using System.Collections.Concurrent; using System.Diagnostics; using System.Reflection; using System.Runtime.Serialization; @@ -199,24 +200,48 @@ protected virtual Extent GetExtent() protected virtual Tile? InternalGetLastExistingTile(Coord coords) { this._logger.LogDebug($"[{MethodBase.GetCurrentMethod().Name}] started for coord: z:{coords.Z}, x:{coords.X}, y:{coords.Y}"); + // get tiles coordinates int z = coords.Z; int baseTileX = coords.X; int baseTileY = this.ConvertOriginCoord(coords); //dont forget to use the correct origin when overriding this - Tile? lastTile = null; - - // Go over zoom levels until a tile is found (may not find tile) + // Define all tiles coordinates that needs to be requested for upscale + List coordsList = new List(coords.Z); for (int i = z - 1; i >= 0; i--) { baseTileX >>= 1; // Divide by 2 baseTileY >>= 1; // Divide by 2 - lastTile = this.Utils.GetTile(i, baseTileX, baseTileY); - if (lastTile != null) + coordsList.Add(new Coord(i, baseTileX, baseTileY)); + } + + // Async method to request all tiles that can be used for "upscale" concurrently + var getUpscaleTiles = async delegate (Coord[] coordsArray) + { + ConcurrentDictionary zOrderToTileDictionary = new ConcurrentDictionary(); + // get all tiles concurrently + await Parallel.ForEachAsync(coordsArray, async (coord, cancellationToken) => { - break; - } + await Task.Run(() => + { + Tile? tile = this.Utils.GetTile(coord.Z, coord.X, coord.Y); + if (tile != null) + { + zOrderToTileDictionary.TryAdd(coord.Z, tile); + } + }, cancellationToken); + }); + return zOrderToTileDictionary.ToArray(); + }; + var response = getUpscaleTiles(coordsList.ToArray()); + var tilesResponseArray = response.Result; + if (tilesResponseArray.Length == 0) + { + return null; } + // Get first valid tile that can be upscaled + var orderedTilesArray = tilesResponseArray.OrderBy(kvp => kvp.Key); + Tile? lastTile = orderedTilesArray.Last().Value; string message = lastTile == null ? "null" : $"z:{lastTile.Z}, x:{lastTile.X}, y:{lastTile.Y}"; this._logger.LogDebug($"[{MethodBase.GetCurrentMethod().Name}] ended, lastTile: {message}"); return lastTile; diff --git a/MergerLogicUnitTests/DataTypes/FSTest.cs b/MergerLogicUnitTests/DataTypes/FSTest.cs index 7931b089..be989ca5 100644 --- a/MergerLogicUnitTests/DataTypes/FSTest.cs +++ b/MergerLogicUnitTests/DataTypes/FSTest.cs @@ -348,7 +348,8 @@ public void GetCorrespondingTileWithUpscale(bool isBase, bool isOneXOne, GridOri .Returns(nullTile); } - this._oneXOneConvertorMock.InSequence(sequence) + this._oneXOneConvertorMock + .InSequence(sequence) .Setup(converter => converter.TryFromTwoXOne(It.Is(c => c.Z == 5 && c.X == 2 && c.Y == 3))) .Returns(isValidConversion ? cords => cords : null); }