Exemple #1
0
        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);
        }
Exemple #2
0
 public long GetTotalAllocatedSize()
 {
     lock (PoolPointers)
     {
         return(PoolPointers.Sum(x => x.Length));
     }
 }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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;
                }
            }
        }