public bool LoadLeafSubGrid(IStorageProxy storageProxy, SubGridCellAddress cellAddress, bool loadAllPasses, bool loadLatestPasses, IServerLeafSubGrid subGrid) { var fullFileName = string.Empty; var result = false; try { // Loading contents into a dirty sub grid (which should happen only on the mutable nodes), or // when there is already content in the segment directory are strictly forbidden and break immutability // rules for sub grids if (subGrid.Dirty) { throw new TRexSubGridIOException("Leaf sub grid directory loads may not be performed while the sub grid is dirty. The information should be taken from the cache instead."); } // Load the cells into it from its file // Briefly lock this sub grid just for the period required to read its contents lock (subGrid) { // If more than thread wants this sub grid then they may concurrently attempt to load it. // Make a check to see if this has happened and another thread has already loaded this sub grid directory. // If so, just return success. Previously the commented out assert was enforced causing exceptions // Debug.Assert(SubGrid.Directory?.SegmentDirectory?.Count == 0, "Loading a leaf sub grid directory when there are already segments present within it."); // Check this thread is the winner of the lock to be able to load the contents if (subGrid.Directory?.SegmentDirectory?.Count == 0) { // Ensure the appropriate storage is allocated if (loadAllPasses) { subGrid.AllocateLeafFullPassStacks(); } if (loadLatestPasses) { subGrid.AllocateLeafLatestPassGrid(); } fullFileName = GetLeafSubGridFullFileName(cellAddress); // Briefly lock this sub grid just for the period required to read its contents result = subGrid.LoadDirectoryFromFile(storageProxy, fullFileName); } else { // A previous thread has already read the directory so there is nothing more to do, return a true result. return(true); } } } finally { if (result && RecordSubGridFileReadingToLog) { _log.LogDebug($"Sub grid file {fullFileName} read from persistent store containing {subGrid.Directory.SegmentDirectory.Count} segments (Moniker: {subGrid.Moniker()}"); } } return(result); }
public static void AddMultipleCellsWithPasses(ISiteModel siteModel, int cellX, int cellY, List <CellPass[]> passesList, int expectedCellCount = -1, int expectedPassCount = -1) { // Construct the sub grid to hold the cell being tested IServerLeafSubGrid leaf = siteModel.Grid.ConstructPathToCell(cellX, cellY, SubGridPathConstructionType.CreateLeaf) as IServerLeafSubGrid; leaf.Should().NotBeNull(); leaf.AllocateLeafFullPassStacks(); leaf.CreateDefaultSegment(); leaf.AllocateFullPassStacks(leaf.Directory.SegmentDirectory.First()); leaf.AllocateLeafLatestPassGrid(); // Add the leaf to the site model existence map siteModel.ExistenceMap[leaf.OriginX >> SubGridTreeConsts.SubGridIndexBitsPerLevel, leaf.OriginY >> SubGridTreeConsts.SubGridIndexBitsPerLevel] = true; long totalCells = 0; for (var i = 0; i < passesList.Count; i++) { //CellPass[] _passes = passes.ToArray(); byte subGridX = (byte)(cellX & SubGridTreeConsts.SubGridLocalKeyMask); byte subGridY = (byte)(cellY & SubGridTreeConsts.SubGridLocalKeyMask); foreach (var pass in passesList[i]) { leaf.AddPass(subGridX, subGridY, pass); } var cellPasses = leaf.Cells.PassesData[i].PassesData.ExtractCellPasses(subGridX, subGridY); if (expectedPassCount > -1) { ((int)cellPasses.PassCount).Should().Be(expectedPassCount); } // Assign global latest cell pass to the appropriate pass leaf.Directory.GlobalLatestCells[subGridX, subGridY] = cellPasses.Passes.Last(); // Ensure the pass data existence map records the existence of a non null value in the cell leaf.Directory.GlobalLatestCells.PassDataExistenceMap[subGridX, subGridY] = true; if (expectedCellCount > -1) { // Count the number of non-null elevation cells to verify a correct setup siteModel.Grid.Root.ScanSubGrids(siteModel.Grid.FullCellExtent(), x => { totalCells += leaf.Directory.GlobalLatestCells.PassDataExistenceMap.CountBits(); return(true); }); } siteModel.SiteModelExtent.Include(siteModel.Grid.GetCellExtents(cellX, cellY)); } totalCells.Should().Be(expectedCellCount); // Save the leaf information just created siteModel.Grid.SaveLeafSubGrid(leaf, siteModel.PrimaryStorageProxy, siteModel.PrimaryStorageProxy, new List <ISubGridSpatialAffinityKey>()); siteModel.SaveToPersistentStoreForTAGFileIngest(siteModel.PrimaryStorageProxy); }
/// <summary> /// Set up a model with a single sub grid with a single cell containing 3 cell passes /// </summary> /// <returns></returns> private ISiteModel CreateSiteModelWithSingleCellForTesting() { var siteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(DITagFileFixture.NewSiteModelGuid, true); // Switch to mutable storage representation to allow creation of content in the site model siteModel.StorageRepresentationToSupply.Should().Be(StorageMutability.Immutable); siteModel.SetStorageRepresentationToSupply(StorageMutability.Mutable); siteModel.Machines.CreateNew("Test Machine", "", MachineType.Dozer, DeviceTypeEnum.SNM940, false, Guid.NewGuid()); // vibrationState is needed to get cmv values siteModel.MachinesTargetValues[0].VibrationStateEvents.PutValueAtDate(BASE_TIME, VibrationState.On); siteModel.MachinesTargetValues[0].AutoVibrationStateEvents.PutValueAtDate(BASE_TIME, AutoVibrationState.Manual); // Construct the sub grid to hold the cell being tested IServerLeafSubGrid leaf = siteModel.Grid.ConstructPathToCell(SubGridTreeConsts.DefaultIndexOriginOffset, SubGridTreeConsts.DefaultIndexOriginOffset, SubGridPathConstructionType.CreateLeaf) as IServerLeafSubGrid; leaf.Should().NotBeNull(); leaf.AllocateLeafFullPassStacks(); leaf.CreateDefaultSegment(); leaf.AllocateFullPassStacks(leaf.Directory.SegmentDirectory.First()); leaf.AllocateLeafLatestPassGrid(); // Add the leaf to the site model existence map siteModel.ExistenceMap[leaf.OriginX >> SubGridTreeConsts.SubGridIndexBitsPerLevel, leaf.OriginY >> SubGridTreeConsts.SubGridIndexBitsPerLevel] = true; siteModel.Grid.CountLeafSubGridsInMemory().Should().Be(1); // Add three passes, each separated by 10 seconds and descending by 100mm each pass for (int i = 0; i < PASSES_IN_DECREMENTING_ELEVATION_LIST; i++) { leaf.AddPass(0, 0, new CellPass { InternalSiteModelMachineIndex = 0, Time = BASE_TIME.AddSeconds(i * TIME_INCREMENT_SECONDS), Height = BASE_HEIGHT + i * HEIGHT_DECREMENT, PassType = PassType.Front, CCV = CCV_Test, MDP = MDP_Test, MaterialTemperature = Temperature_Test }); } var cellPasses = leaf.Cells.PassesData[0].PassesData.ExtractCellPasses(0, 0); cellPasses.Passes.Count.Should().Be(PASSES_IN_DECREMENTING_ELEVATION_LIST); // Assign global latest cell pass to the appropriate pass leaf.Directory.GlobalLatestCells[0, 0] = cellPasses.Passes.Last(); // Ensure the pass data existence map records the existence of a non null value in the cell leaf.Directory.GlobalLatestCells.PassDataExistenceMap[0, 0] = true; // Count the number of non-null elevation cells to verify a correct setup long totalCells = 0; siteModel.Grid.Root.ScanSubGrids(siteModel.Grid.FullCellExtent(), x => { totalCells += leaf.Directory.GlobalLatestCells.PassDataExistenceMap.CountBits(); return(true); }); totalCells.Should().Be(1); return(siteModel); }