public void SetElement_Empty_Fail() { var span = new TRexSpan <CellPass>(new CellPass[3], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 3, false); Action act = () => span.SetElement(new CellPass(), 0); act.Should().Throw <ArgumentException>("Index out of range"); }
public void Add_SimpleSpanTwo() { var baseTime = DateTime.UtcNow; var span = new TRexSpan <CellPass>(new CellPass[2], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 2, false); var cp1 = new CellPass { Time = baseTime }; var cp2 = new CellPass { Time = baseTime.AddMinutes(1) }; span.Add(cp1); span.Add(cp2); span.Count.Should().Be(2); span.First().Should().BeEquivalentTo(cp1); span.Last().Should().BeEquivalentTo(cp2); span.GetElement(0).Should().BeEquivalentTo(cp1); span.GetElement(1).Should().BeEquivalentTo(cp2); span.OffsetPlusCount.Should().Be(2); }
public void Insert_InMiddle() { var baseTime = DateTime.UtcNow; var span = new TRexSpan <CellPass>(new CellPass[3], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 3, false); var cp1 = new CellPass { Time = baseTime }; var cp2 = new CellPass { Time = baseTime.AddMinutes(1) }; span.Add(cp1); span.Add(cp1); span.Insert(cp2, 1); span.Count.Should().Be(3); span.First().Should().BeEquivalentTo(cp1); span.Last().Should().BeEquivalentTo(cp1); span.GetElement(0).Should().BeEquivalentTo(cp1); span.GetElement(1).Should().BeEquivalentTo(cp2); span.OffsetPlusCount.Should().Be(3); }
public void Add_CentralSpanTwo(int poolSize, ushort spanOffset, int spanCapacity) { var baseTime = DateTime.UtcNow; var span = new TRexSpan <CellPass>(new CellPass[poolSize], TRexSpan <CellPass> .NO_SLAB_INDEX, spanOffset, spanCapacity, false); var cp1 = new CellPass { Time = baseTime }; var cp2 = new CellPass { Time = baseTime.AddMinutes(1) }; span.Add(cp1); span.Add(cp2); span.Count.Should().Be(2); span.First().Should().BeEquivalentTo(cp1); span.Last().Should().BeEquivalentTo(cp2); span.GetElement(0).Should().BeEquivalentTo(cp1); span.GetElement(1).Should().BeEquivalentTo(cp2); span.OffsetPlusCount.Should().Be(spanOffset + span.Count); }
public void Insert_FailOutOfRange_High() { var span = new TRexSpan <CellPass>(new CellPass[10], TRexSpan <CellPass> .NO_SLAB_INDEX, 5, 6, false); var cp = new CellPass(); Action act = () => span.Insert(cp, 7); act.Should().Throw <ArgumentException>().WithMessage("Index out of range"); }
public void Creation_Specific_PoolAllocated() { var span = new TRexSpan <CellPass>(new CellPass[2], 0, 0, 2, false); span.Count.Should().Be(0); span.Capacity.Should().Be(2); span.Offset.Should().Be(0); span.Elements.Should().NotBeNull(); span.OffsetPlusCount.Should().Be(0); }
public void Creation_Default() { var span = new TRexSpan <CellPass>(); span.Count.Should().Be(0); span.Capacity.Should().Be(0); span.Offset.Should().Be(0); span.Elements.Should().BeNull(); span.OffsetPlusCount.Should().Be(0); }
public void Add_Fail_ExceedsCapacity() { var span = new TRexSpan <CellPass>(new CellPass[1], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 1, false); var cp = new CellPass(); span.Add(cp); Action act = () => span.Add(cp); act.Should().Throw <ArgumentException>() .WithMessage($"No spare capacity to add new element, capacity = 1, element count = 1"); }
public void Copy_Fail_ArrayT_SourceCountOutOfBounds() { var span = new TRexSpan <CellPass>(new CellPass[10], TRexSpan <CellPass> .NO_SLAB_INDEX, 5, 2, false); Action act = () => span.Copy(new CellPass[1], 3); act.Should().Throw <ArgumentException>().WithMessage("Source count may not be negative or greater than the count of elements in the source"); var span3 = new TRexSpan <CellPass>(new CellPass[10], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 1, false); act = () => span3.Copy(new CellPass[2], 2); act.Should().Throw <ArgumentException>().WithMessage("Target has insufficient capacity (1) to contain required items from source (2)"); }
public void GetElement_SingleElement_Success() { var baseTime = DateTime.UtcNow; var span = new TRexSpan <CellPass>(new CellPass[3], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 3, false); var cp = new CellPass { Time = baseTime }; span.Add(cp); span.GetElement(0).Should().BeEquivalentTo(cp); }
public SlabAllocatedPoolPage(int poolSize, int arraySize) { // Create a single allocation to contain a slab of elements of size pool size SlabPage = new T[poolSize]; int spanCount = poolSize / arraySize; // Create an array of sub array spans that fit within the overall slab Arrays = new TRexSpan <T> [spanCount]; for (int i = 0; i < spanCount; i++) { Arrays[i] = new TRexSpan <T>(SlabPage, 0, i * arraySize, arraySize, true); } }
/// <summary> /// Allocate or resize an array of passes to a new size, with additional space provided for expansion /// </summary> public void AllocatePasses(int capacity) { if (!Passes.IsRented) { Passes = GenericSlabAllocatedArrayPoolHelper <CellPass> .Caches().Rent(capacity); #if CELLDEBUG if (!Passes.IsRented) { throw new Exception("Is not rented!"); } #endif return; } if (Passes.Count >= capacity) { #if CELLDEBUG if (!Passes.IsRented) { throw new Exception("Is not rented!"); } #endif // Current allocated capacity is sufficient. Passes.Count = capacity; return; } if (capacity > Passes.Capacity) { // Get a new buffer and copy the content into it var newPasses = GenericSlabAllocatedArrayPoolHelper <CellPass> .Caches().Rent(capacity); newPasses.Copy(Passes, Passes.Count); GenericSlabAllocatedArrayPoolHelper <CellPass> .Caches().Return(ref Passes); Passes = newPasses; #if CELLDEBUG if (!Passes.IsRented) { throw new Exception("Is not rented!"); } #endif } }
public void SetElement_SingleElement_RangeFailure() { var baseTime = DateTime.UtcNow; var span = new TRexSpan <CellPass>(new CellPass[3], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 3, false); var cp = new CellPass { Time = baseTime }; span.Add(cp); Action act = () => span.SetElement(cp, -1); act.Should().Throw <ArgumentException>("Index out of range"); act = () => span.SetElement(cp, 1); act.Should().Throw <ArgumentException>("Index out of range"); }
public void Copy_Central() { var baseTime = DateTime.UtcNow; var span = new TRexSpan <CellPass>(new CellPass[12], TRexSpan <CellPass> .NO_SLAB_INDEX, 5, 2, false); var cp1 = new CellPass { Time = baseTime }; var cp2 = new CellPass { Time = baseTime.AddMinutes(1) }; span.Add(cp1); span.Add(cp2); var span2 = new TRexSpan <CellPass>(new CellPass[8], TRexSpan <CellPass> .NO_SLAB_INDEX, 0, 8, false); span2.Copy(span, 2); span2.Count.Should().Be(2); span2.GetElement(0).Should().BeEquivalentTo(cp1); span2.GetElement(1).Should().BeEquivalentTo(cp2); }
/// <summary> /// Takes a cell pass stack and integrates its contents into this cell pass stack ensuring all duplicates are resolved /// and that cell pass ordering on time is preserved /// </summary> public void Integrate(Cell_NonStatic sourcePasses, int startIndex, int endIndex, out int addedCount, out int modifiedCount) { #if CELLDEBUG // Check 'this' cell pass times are in order CheckPassesAreInCorrectTimeOrder("Cell passes are not in time order before integration"); sourcePasses.CheckPassesAreInCorrectTimeOrder("Source cell passes are not in time order before integration"); #endif addedCount = 0; modifiedCount = 0; if (sourcePasses.Passes.Count == 0) { return; } var thisIndex = 0; var sourceIndex = startIndex; var integratedIndex = 0; var originalPassCount = PassCount; var integratedPassCount = originalPassCount + (endIndex - startIndex + 1); // Set the length to be the combined. While this may be more than needed if // there are passes in source that have identical times to the passes in // this cell pass stack, it does give an upper bound, and the minority of cases // where the actual number of passes are less than the total that are initially set here // will be cleaned up when the sub grid next exits the cache, or is integrated with // another aggregated sub grid from TAG file processing var integratedPasses = GenericSlabAllocatedArrayPoolHelper <CellPass> .Caches().Rent(integratedPassCount); // Combine the two (sorted) lists of cell passes together to arrive at a single // integrated list of passes. do { if (thisIndex >= PassCount) { integratedPasses.Add(sourcePasses.Passes.GetElement(sourceIndex)); sourceIndex++; } else if (sourceIndex > endIndex) { integratedPasses.Add(Passes.GetElement(thisIndex)); thisIndex++; } else { var thisElement = Passes.GetElement(thisIndex); var sourceElement = sourcePasses.Passes.GetElement(sourceIndex); switch (thisElement.Time.CompareTo(sourceElement.Time)) { case -1: { integratedPasses.Add(thisElement); thisIndex++; break; } case 0: { if (!thisElement.Equals(sourceElement)) { modifiedCount++; } integratedPasses.Add(sourceElement); sourceIndex++; thisIndex++; integratedPassCount--; break; } case 1: { integratedPasses.Add(sourceElement); sourceIndex++; break; } } } integratedIndex++; } while (integratedIndex <= integratedPassCount - 1); integratedPasses.Count = integratedPassCount; // Assign the integrated list of passes to this cell, replacing the previous list of passes. // Return the original cell pass span and replace it with the integrated one GenericSlabAllocatedArrayPoolHelper <CellPass> .Caches().Return(ref Passes); // No need to mark Passes as being returned as it is immediately replace by IntegratedPasses below // Passes.MarkReturned(); Passes = integratedPasses; addedCount = integratedPassCount - originalPassCount; #if CELLDEBUG CheckPassesAreInCorrectTimeOrder("Cell passes are not in time order after integration"); #endif }