public PoolPointer Allocate(long size) { if (size > PoolSize) { return(null); } long currentScanOffset = 0; lock (PoolPointers) { foreach (var pointer in PoolPointers.OrderBy(x => x.Offset).ToArray()) { if (pointer.Offset - currentScanOffset >= size) { var newPointer = new PoolPointer(this, currentScanOffset, size, DefaultFixed); PoolPointers.Add(newPointer); return(newPointer); } currentScanOffset = pointer.Offset + pointer.Length; } if (PoolSize - currentScanOffset >= size) { var newPointer = new PoolPointer(this, currentScanOffset, size, DefaultFixed); PoolPointers.Add(newPointer); return(newPointer); } } return(null); }
public long GetTotalAllocatedSize() { lock (PoolPointers) { return(PoolPointers.Sum(x => x.Length)); } }
public void Release(PoolPointer poolPointer) { lock (PoolPointers) { if (PinnedPointers.Contains(poolPointer)) { throw new InvalidOperationException("Cannot release a pool pointer that is currently pinned"); } PoolPointers.Remove(poolPointer); } }
public void Compact() { lock (PoolPointers) { long currentScanOffset = 0; int currentPinnedPointerIndex = 0; var pinnedPointers = PinnedPointers .Concat(PoolPointers.Where(x => x.Fixed)) .OrderBy(x => x.Offset) .ToArray(); var movablePointers = PoolPointers .Except(pinnedPointers) .OrderBy(x => x.Offset); foreach (var pointer in movablePointers) { if (currentScanOffset == pointer.Offset) { // Block is already in optimal position currentScanOffset += pointer.Length; continue; } while (pinnedPointers[currentPinnedPointerIndex].Offset - currentScanOffset < pointer.Length) { // There is a pinned pointer in the way. Skip over it currentScanOffset = pinnedPointers[currentPinnedPointerIndex].Offset + pinnedPointers[currentPinnedPointerIndex].Length; currentPinnedPointerIndex++; } var originalPosition = UnderlyingMemory.Slice((int)pointer.Offset, (int)pointer.Length); var newPosition = UnderlyingMemory.Slice((int)currentScanOffset, (int)pointer.Length); originalPosition.CopyTo(newPosition); pointer.Offset = currentScanOffset; currentScanOffset += pointer.Length; } } }