Example #1
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
            }
        }
Example #2
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
        }