Exemplo n.º 1
0
        /// <summary>
        /// Grow the current heap
        /// </summary>
        /// <param name="nVertex">Min element needs</param>
        public void Grow(int Count)
        {
            // Grow default size
            int GrowSize = (int)((HeapData.Length / 100D) * GrowPercentile);

            // Check if this size is sufficient
            if (GrowSize < Count)
            {
                GrowSize += Count;
            }

            int oldSize = HeapData.Length;

            Array.Resize(ref HeapData, HeapData.Length + GrowSize);

            ArrayHandler <Type> current = new ArrayHandler <Type>(this, oldSize, GrowSize);

            // Check if there's continuous free segments
            for (int i = 0; i < FreeSpaces.Count; ++i)
            {
                ArrayHandler <Type> Segment = FreeSpaces[i];
                if (Segment.Offset + Segment.Size == current.Offset)
                {
                    current = new ArrayHandler <Type>(this, Segment.Offset, Segment.Size + current.Size);
                    FreeSpaces.Remove(Segment);
                }
            }

            FreeSpaces.Add(current);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Free a portion of heap.
        /// </summary>
        /// <param name="V">Handle to this portion.</param>
        public void Free(ArrayHandler <Type> V)
        {
            // !! The vertex segment MUST be used !!

            if (V == null)
            {
                return;
            }

            if (!UsedSpaces.Contains(V))
            {
                throw new Exception("This handler doesn't belongs to this heap.");
            }

            bool Found = false;

            var freeSpace = new ArrayHandler <Type>(this, V.Offset, V.Size);

            // Check if there's continuous free segments
            for (int i = FreeSpaces.Count - 1; i >= 0; --i)
            {
                ArrayHandler <Type> Segment = FreeSpaces[i];
                if (Segment.Offset + Segment.Size == V.Offset)
                {
                    freeSpace = new ArrayHandler <Type>(this, Segment.Offset, Segment.Size + freeSpace.Size);
                    FreeSpaces.RemoveAt(i--);
                    Found = true;
                }
                else if (V.Offset + V.Size == Segment.Offset)
                {
                    freeSpace = new ArrayHandler <Type>(this, freeSpace.Offset, freeSpace.Size + Segment.Size);
                    FreeSpaces.RemoveAt(i--);
                    Found = true;
                }

                if (Found)
                {
                    break;
                }
            }

            if (FreeSpaces.FindIndex((X) => (X.Offset <= freeSpace.Offset && X.Size + X.Size >= freeSpace.Offset)) < 0)
            {
                FreeSpaces.Add(freeSpace);
            }

            UsedSpaces.Remove(V);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Return an handler to this heap for access
        /// in a region with this size.
        /// </summary>
        /// <param name="Count">Region's size.</param>
        /// <returns>Handler.</returns>
        public ArrayHandler <Type> Alloc(int Count)
        {
            bool spaceFound = false;

            ArrayHandler <Type> ToReturn = null;

            if (Count == 0)
            {
                return(null);
            }

            // Searching a free segment of heap
            for (int i = FreeSpaces.Count - 1; i >= 0; --i)
            {
                ArrayHandler <Type> Segment = FreeSpaces[i];
                if (Segment.Size >= Count)
                {
                    long remains = Segment.Size - Count;

                    // Add space surplus
                    if (remains > 0)
                    {
                        FreeSpaces.Add(new ArrayHandler <Type>(this, Segment.Offset + Count, remains));
                    }

                    // Prepare return segment
                    ToReturn = new ArrayHandler <Type>(this, Segment.Offset, Count);

                    // Remove old segment
                    FreeSpaces.Remove(Segment);

                    spaceFound = true;

                    break;
                }
            }

            if (!spaceFound)
            {
                Grow(Count);
                return(Alloc(Count));
            }

            UsedSpaces.Add(ToReturn);

            return(ToReturn);
        }