コード例 #1
0
        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");
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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");
        }
コード例 #6
0
        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);
        }
コード例 #7
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);
        }
コード例 #8
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");
        }
コード例 #9
0
        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)");
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
            }
        }
コード例 #12
0
        /// <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
            }
        }
コード例 #13
0
        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");
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        /// <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
        }