Esempio n. 1
0
        public void CommitCellPassToModel(int cellX, int cellY,
                                          double gridX, double gridY,
                                          CellPass processedCellPass, bool lowestPassOnly = false)
        {
            // Arrange the sub grid that will house this cell pass.
            // This needs to happen if, and only if, we will actually add a cell
            // pass to the sub grid. The reason for this restriction is that we may
            // otherwise end up creating a new sub grid that never has any cell passes
            // added to it.

            // The grid we are populating is a in-memory grid (ie: not the actual sub grid database
            // for this data model).

            var SubGrid = Grid.ConstructPathToCell(cellX, cellY, SubGridPathConstructionType.CreateLeaf) as IServerLeafSubGrid;

            SubGrid.AllocateLeafFullPassStacks();

            // If the node is brand new (ie: it does not have any cell passes committed to it yet)
            // then create and select the default segment

            if (SubGrid.Directory.SegmentDirectory.Count == 0)
            {
                SubGrid.Cells.SelectSegment(Consts.MIN_DATETIME_AS_UTC);
            }

            SubGrid.SetDirty();

            // Find the location of the cell within the sub grid.
            SubGrid.GetSubGridCellIndex(cellX, cellY, out byte SubGridCellX, out byte SubGridCellY);

            // Now add the pass to the cell information
            SubGrid.AddPass(SubGridCellX, SubGridCellY, processedCellPass, lowestPassOnly);

            // Include the new point into the extents being maintained for
            // any proofing run being processed.
            Processor.ProofingRunExtent.Include(gridX, gridY, processedCellPass.Height);

            // Include the new point into the extents being maintained for
            // any design being processed.
            Processor.DesignExtent.Include(gridX, gridY, processedCellPass.Height);

            SiteModel.SiteModelExtent.Include(gridX, gridY, processedCellPass.Height);

            Processor.ProcessedCellPassesCount++;
        }
Esempio n. 2
0
        private void IntegrateIntoIntermediaryGrid(IServerLeafSubGrid sourceSubGrid, ISubGridSegmentIterator segmentIterator)
        {
            var targetSubGrid = _target.ConstructPathToCell(sourceSubGrid.OriginX, sourceSubGrid.OriginY,
                                                            SubGridPathConstructionType.CreateLeaf) as IServerLeafSubGrid;

            targetSubGrid.AllocateLeafFullPassStacks();

            // If the node is brand new (ie: it does not have any cell passes committed to it yet)
            // then create and select the default segment
            if (targetSubGrid.Directory.SegmentDirectory.Count == 0)
            {
                targetSubGrid.Cells.SelectSegment(Consts.MIN_DATETIME_AS_UTC);
                targetSubGrid.Cells.PassesData[0].AllocateFullPassStacks();
            }

            if (targetSubGrid.Cells.PassesData[0].PassesData == null)
            {
                _log.LogCritical("No segment passes data in new segment");
                return;
            }

            targetSubGrid.Integrate(sourceSubGrid, segmentIterator, true);
        }
Esempio n. 3
0
        /// <summary>
        /// Locates the sub grid in the sub grid tree that contains the cell identified by CellX and CellY in the global
        /// sub grid tree cell address space. The tree level for the sub grid returned is specified in Level.
        /// </summary>
        public static ISubGrid LocateSubGridContaining(IStorageProxy storageProxyForSubGrids,
                                                       IServerSubGridTree forSubGridTree,
                                                       //const GridDataCache : TICDataStoreCache;
                                                       int cellX,
                                                       int cellY,
                                                       byte level,
                                                       bool lookInCacheOnly,
                                                       bool acceptSpeculativeReadFailure)
        {
            IServerLeafSubGrid leafSubGrid = null;
            var createdANewSubGrid         = false;

            ISubGrid result = null;

            if (forSubGridTree == null)
            {
                throw new TRexSubGridProcessingException($"Sub grid tree null in {nameof(LocateSubGridContaining)}");
            }

            // Note: Sub grid tree specific interlocks are no longer used. The tree now internally
            // manages fine grained locks across structurally mutating activities such as node/leaf
            // sub grid addition and reading content from the persistent store.

            // First check to see if the requested cell is present in a leaf sub grid
            var subGrid = forSubGridTree.LocateClosestSubGridContaining(cellX, cellY, level);

            if (subGrid == null) // Something bad happened
            {
                _log.LogWarning($"Failed to locate sub grid at {cellX}:{cellY}, level {level}, data model ID:{forSubGridTree.ID}");
                return(null);
            }

            if (!subGrid.IsLeafSubGrid() && !lookInCacheOnly && level == forSubGridTree.NumLevels)
            {
                if (forSubGridTree.CachingStrategy == ServerSubGridTreeCachingStrategy.CacheSubGridsInTree)
                {
                    // Create the leaf sub grid that will be used to read in the sub grid from the disk.
                    // In the case where the sub grid isn't present on the disk this reference will be destroyed
                    subGrid = forSubGridTree.ConstructPathToCell(cellX, cellY, Types.SubGridPathConstructionType.CreateLeaf);
                }
                else if (forSubGridTree.CachingStrategy == ServerSubGridTreeCachingStrategy.CacheSubGridsInIgniteGridCache)
                {
                    // Create the leaf sub grid without constructing elements in the grid to represent it other than the
                    // path in the tree to the parent of the sub grid.
                    // Note: Setting owner and parent relationship from the sub grid to the tree in this fashion permits
                    // business logic in th sub grid that require knowledge of it parent and owner relationships to function
                    // correctly while not including a reference to the sub grid from the tree.
                    subGrid = forSubGridTree.CreateNewSubGrid(forSubGridTree.NumLevels);
                    subGrid.SetAbsoluteOriginPosition(cellX & ~SubGridTreeConsts.SubGridLocalKeyMask, cellY & ~SubGridTreeConsts.SubGridLocalKeyMask);
                    subGrid.Owner  = forSubGridTree;
                    subGrid.Parent = forSubGridTree.ConstructPathToCell(cellX, cellY, Types.SubGridPathConstructionType.CreatePathToLeaf);
                }

                if (subGrid != null)
                {
                    createdANewSubGrid = true;
                }
                else
                {
                    _log.LogError($"Failed to create leaf sub grid in LocateSubGridContaining for sub grid at {cellX}x{cellY}");
                    return(null);
                }
            }

            if (subGrid.IsLeafSubGrid())
            {
                leafSubGrid = subGrid as IServerLeafSubGrid;
            }

            if (leafSubGrid == null) // Something bad happened
            {
                _log.LogError($"Sub grid request result for {cellX}:{cellY} is not a leaf sub grid, it is a {subGrid.GetType().Name}.");
                return(null);
            }

            if (!createdANewSubGrid)
            {
                if (lookInCacheOnly)
                {
                    if (subGrid.Level == level)
                    {
                        return(subGrid);
                    }

                    // If the returned sub grid is a leaf sub grid then it was already present in the
                    // cache. If the level of the returned sub grid matches the request level parameter
                    // then there is nothing more to do here.
                    if (subGrid.IsLeafSubGrid() &&
                        ((leafSubGrid.HasSubGridDirectoryDetails || leafSubGrid.Dirty) &&
                         leafSubGrid.HasAllCellPasses() && leafSubGrid.HasLatestData()) ||
                        (!subGrid.IsLeafSubGrid() && subGrid.Level == level))
                    {
                        return(subGrid);
                    }
                }
            }

            if ((!leafSubGrid.HasSubGridDirectoryDetails && !leafSubGrid.Dirty) ||
                !(leafSubGrid.HasAllCellPasses() && leafSubGrid.HasLatestData()))
            {
                // The requested cell is either not present in the sub grid tree (cache),
                // or it is residing on disk, and a newly created sub grid has been constructed
                // to contain the data read from disk.

                // The underlying assumption is that this method is only called if the caller knows
                // that the sub grid exists in the sub grid tree (this is known via the sub grid existence
                // map available to the caller). In cases where eventual consistency
                // may mean that a sub grid was removed from the sub grid tree since the caller retrieved
                // its copy of the sub grid existence map this function will fail gracefully with a null sub grid.
                // The exception to this rule is the tag file processor service which may speculatively
                // attempt to read a sub grid that doesn't exist.
                // This is a different approach to desktop systems where the individual node sub grids
                // contain mini existence maps for the sub grids below them.

                if (forSubGridTree.LoadLeafSubGrid(storageProxyForSubGrids,
                                                   new SubGridCellAddress(cellX, cellY),
                                                   true, true,
                                                   leafSubGrid))
                {
                    // We've loaded it - get the reference to the new sub grid and return it
                    result = leafSubGrid;
                }
                else
                {
                    // The sub grid could not be loaded. This is likely due to it not ever existing
                    // in the model, or it may have been deleted. Failure here does not necessarily
                    // constitute evidence of corruption in the data model. Examination of the
                    // spatial existence map in conjunction with the requested sub grid index is
                    // required to determine that. Advise the caller nothing was read by sending back
                    // a null sub grid reference.
                    // The failed sub grid is not proactively deleted and will remain so the normal cache
                    // expiry mechanism can remove it in its normal operations

                    if (acceptSpeculativeReadFailure)
                    {
                        // Return the otherwise empty sub grid back to the caller and integrate it into the cache
                        if (_log.IsTraceEnabled())
                        {
                            _log.LogTrace($"Speculative read failure accepted for sub grid {leafSubGrid.Moniker()}. Blank sub grid returned to caller.");
                        }

                        result = leafSubGrid;
                    }
                    else
                    {
                        _log.LogWarning($"Failed to read leaf sub grid {leafSubGrid.Moniker()} in model {forSubGridTree.ID}. Failed sub grid is NOT removed from the tree");

                        // Empty the sub grid leaf based data to encourage it to be read on a secondary attempt
                        leafSubGrid.DeAllocateLeafFullPassStacks();
                        leafSubGrid.DeAllocateLeafLatestPassGrid();
                    }
                }
            }

            // Ignite special case - allow Dirty leaf sub grids to be returned
            if (result == null)
            {
                if (leafSubGrid.HasSubGridDirectoryDetails && leafSubGrid.Dirty && leafSubGrid.HasAllCellPasses() && leafSubGrid.HasLatestData())
                {
                    result = leafSubGrid;
                }
            }

            // IGNITE: Last gasp - if the sub grid is in memory and has directory details then just return it
            if (result == null && leafSubGrid.HasSubGridDirectoryDetails)
            {
                result = leafSubGrid;
            }

            return(result);
        }