protected void UnpinPointer(PoolPointer pointer) { lock (PoolPointers) { PinnedPointers.Remove(pointer); } }
public IMemoryOwner <byte> GetMemory(PoolPointer poolPointer) { lock (PoolPointers) { PinnedPointers.Add(poolPointer); return(new AllocatorMemoryOwner(this, poolPointer, UnderlyingMemory.Slice((int)poolPointer.Offset, (int)poolPointer.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; } } }