/// <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); }
/// <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); }
/// <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); }