Esempio n. 1
0
        /// <summary>
        /// Decorates the base sub grid request logic with additional requirements for progressive requests
        /// </summary>
        public override ServerRequestResult RetrieveSubGrid(IClientLeafSubGrid clientGrid,
                                                            SubGridTreeBitmapSubGridBits cellOverrideMask,
                                                            out bool sieveFilterInUse,
                                                            Func <ServerRequestResult> computeSpatialFilterMaskAndClientProdDataMap)
        {
            // Establish the expected number of height layers in the client sub grid
            if (!(clientGrid is IClientProgressiveHeightsLeafSubGrid subGrid))
            {
                throw new ArgumentException($"Supplied client {clientGrid.Moniker()} is not a {nameof(IClientProgressiveHeightsLeafSubGrid)}");
            }

            _progressiveClientSubGrid = subGrid;

            var numHeightLayers = (int)((EndDate.Ticks - StartDate.Ticks) / Interval.Ticks);

            if ((EndDate.Ticks - StartDate.Ticks) % Interval.Ticks == 0)
            {
                numHeightLayers++;
            }

            _progressiveClientSubGrid.NumberOfHeightLayers = numHeightLayers;

            return(base.RetrieveSubGrid(clientGrid, cellOverrideMask, out sieveFilterInUse, computeSpatialFilterMaskAndClientProdDataMap));
        }
Esempio n. 2
0
        /// <summary>
        /// // Note: There is an assumption you have already checked on a existence map that there is a sub grid for this address
        /// </summary>
        private ServerRequestResult PerformDataExtraction()
        {
            // If there is a cache context for this sub grid, but the sub grid does not support assignation then complain
            var assignationSupported = ClientLeafSubGrid.SupportsAssignationFromCachedPreProcessedClientSubGrid[(int)_clientGrid.GridDataType];

            var subGridCacheContext = _subGridCacheContexts?.FirstOrDefault(x => x.GridDataType == _clientGrid.GridDataType);

            if (subGridCacheContext != null && !assignationSupported)
            {
                throw new TRexException($"Client sub grid of type {_clientGrid.GridDataType} does not support assignation from cached sub grids but has a cache context enabled for it.");
            }

            if (subGridCacheContext != null && assignationSupported)
            {
                if (subGridCacheContext != null && _clientGrid.GridDataType != subGridCacheContext.GridDataType)
                {
                    _log.LogWarning($"Client grid data type {_clientGrid.GridDataType} does not match type of sub grid cache context {subGridCacheContext.GridDataType}");
                }

                // Determine if there is a suitable pre-calculated result present in the general sub grid result cache.
                // If there is, then apply the filter mask to the cached data and copy it to the client grid
                var cachedSubGrid = (IClientLeafSubGrid)_subGridCache?.Get(subGridCacheContext, _clientGrid.CacheOriginX, _clientGrid.CacheOriginY);

                // If there was a cached sub grid located, assign its contents according the client grid mask into the client grid and return it
                if (cachedSubGrid != null)
                {
                    // Log.LogInformation($"Acquired sub grid {CachedSubGrid.Moniker()} for client sub grid {ClientGrid.Moniker()} in data model {SiteModel.ID} from result cache");

                    // Check the cache supplied a tpe of sub grid we can use. If not (due to an issue), ignore the returned item and request the result directly
                    if (_clientGrid.SupportsAssignationFrom(cachedSubGrid.GridDataType))
                    {
                        _clientGrid.ProdDataMap.Assign(cachedSubGrid.ProdDataMap);
                        var innerResult = ComputeSpatialFilterMaskAndClientProdDataMap();
                        if (innerResult != ServerRequestResult.NoError)
                        {
                            return(innerResult);
                        }

                        // Use the filter mask to copy the relevant cells from the cache to the client sub grid
                        _clientGrid.AssignFromCachedPreProcessedClientSubGrid(cachedSubGrid, _clientGrid.FilterMap);

                        return(ServerRequestResult.NoError);
                    }

                    _log.LogError($"Sub grid retrieved from cache is not valid for assigning into client grid. Ignoring. Client sub grid = {_clientGrid.Moniker()}/{_clientGrid.GridDataType}. Cache sub grid = {cachedSubGrid.Moniker()}/{cachedSubGrid.GridDataType}");
                }
            }

            var result = _retriever.RetrieveSubGrid(_clientGrid, CellOverrideMask, out var sieveFilterInUse, ComputeSpatialFilterMaskAndClientProdDataMap);

            // If a sub grid was retrieved and this is a supported data type in the cache then add it to the cache
            // If the sub grid does not support assignation from a precomputed sub grid then just return the result with
            // no reference to the cache.
            if (result == ServerRequestResult.NoError && assignationSupported)
            {
                // Determine if this sub grid is suitable for storage in the cache
                // Don't add sub grids computed using a non-trivial WMS sieve to the general sub grid cache
                var shouldBeCached = subGridCacheContext != null && !sieveFilterInUse && (_clientGrid.GridDataType == subGridCacheContext.GridDataType);

                var subGridInvalidationVersion = shouldBeCached ? subGridCacheContext.InvalidationVersion : 0;

                var clientGrid2 = ClientLeafSubGridFactory.GetSubGrid(_clientGrid.GridDataType);
                clientGrid2.Assign(_clientGrid);
                clientGrid2.AssignFromCachedPreProcessedClientSubGrid(_clientGrid, _clientGrid.FilterMap);

                if (shouldBeCached)
                {
                    //Log.LogInformation($"Adding sub grid {ClientGrid.Moniker()} in data model {SiteModel.ID} to result cache");

                    // Add the newly computed client sub grid to the cache by creating a clone of the client and adding it...
                    if (_subGridCache.Add(subGridCacheContext, _clientGrid, subGridInvalidationVersion) != CacheContextAdditionResult.Added)
                    {
                        _log.LogWarning($"Failed to add sub grid {clientGrid2.Moniker()}, data model {_siteModel.ID} to sub grid result cache context [FingerPrint:{subGridCacheContext.FingerPrint}], returning sub grid to factory as not added to cache");
                        ClientLeafSubGridFactory.ReturnClientSubGrid(ref _clientGrid);
                    }
                }

                _clientGrid = clientGrid2;
            }

            //if <config>.Debug_ExtremeLogSwitchB then  SIGLogMessage.PublishNoODS(Nil, 'Completed call to RetrieveSubGrid()');

            return(result);
        }