Ejemplo n.º 1
0
        private void assureFreeMemoryByStartAccumulation(long bytes)
        {
            MemoryBlockByAddress freeBlock = new MemoryBlockByAddress(-1L, 0L);
            int removedBlocks = 0;

            foreach (MemoryBlockByAddress block in this.structureByAddress)
            {
                if (freeBlock.Address < 0L)
                {
                    freeBlock = block;
                    removedBlocks++;
                    continue;
                }
                long occupiedBytes = block.Address - freeBlock.End;
                if (occupiedBytes < 0)
                {
                    throw new InvalidOperationException("Allocated memory is overlapping.");
                }
                if (occupiedBytes == 0)
                {
                    freeBlock.Size += block.Size;
                }
                else
                {
                    this.memoryMove(freeBlock.End, freeBlock.Address, occupiedBytes);
                    MemoryBlockByAddress foundNode;
                    int  startIndex        = this.allocationsByAddress.GetLeftmostGreaterOrEqualIndex(new MemoryBlockByAddress(freeBlock.End, 0L), out foundNode);
                    int  endIndexExclusive = this.allocationsByAddress.GetLeftmostGreaterOrEqualIndex(new MemoryBlockByAddress(block.Address, 0L), out foundNode);
                    long delta             = freeBlock.Size;
                    for (int i = endIndexExclusive; --i >= startIndex;)
                    {
                        this.allocationsByAddress[i].Address -= delta;
                    }
                    freeBlock = new MemoryBlockByAddress(block.Address - freeBlock.Size, block.Size + freeBlock.Size);
                }
                removedBlocks++;
                if (freeBlock.Size >= bytes)
                {
                    break;
                }
            }
            for (int i = removedBlocks; --i >= 0;)
            {
                MemoryBlockBySize blockBySize = this.structureByAddress[i].ToSize;
                this.structureBySize.Remove(blockBySize);
                this.structureByAddress.RemoveAt(i);
            }
            this.structureByAddress.Add(freeBlock);
            this.structureBySize.Add(freeBlock.ToSize);
        }
Ejemplo n.º 2
0
        private void assureFreeMemoryByMinimumMemoryCopy(long bytes)
        {
            int n = this.structureByAddress.Count;

            MemoryRange[] memory = new MemoryRange[n];

            int  storeIndex = 0;
            long lastPointer = 0L, totalFreeSoFar = 0L, totalCostSoFar = 0L;

            foreach (MemoryBlockByAddress block in this.structureByAddress)
            {
                long occupiedBytes = block.Address - lastPointer;
                totalFreeSoFar      += block.Size;
                totalCostSoFar      += occupiedBytes;
                memory[storeIndex++] = new MemoryRange(totalFreeSoFar, totalCostSoFar);
                lastPointer          = block.End;
            }

            if (totalFreeSoFar != this.free)
            {
                throw new InvalidOperationException("Free memory mismatch.");
            }

            int  startIndex = -1, endIndex = -1;
            long maxFreeBlockCost = long.MaxValue;
            int  j = memory.BinarySearchLeftmostGreaterOrEqual(bytes, mr => mr.TotalFreeBytes);

            for (int i = 0; i < n && j < n; i++)
            {
                long cost      = memory[j].TotalCost - memory[i].TotalCost;
                long freeBytes = memory[j].TotalFreeBytes - (i == 0 ? 0L : memory[i - 1].TotalFreeBytes);
                if (freeBytes >= bytes && cost < maxFreeBlockCost)
                {
                    startIndex       = i;
                    endIndex         = j;
                    maxFreeBlockCost = cost;
                }
                while (j < n && memory[j].TotalFreeBytes - memory[i].TotalFreeBytes < bytes)
                {
                    j++;
                }
            }

            long actualCost = 0L;
            MemoryBlockByAddress resultBlock = this.structureByAddress[startIndex];

            for (int i = startIndex + 1; i <= endIndex; i++)
            {
                MemoryBlockByAddress foundNode, block = this.structureByAddress[i];
                long count = block.Address - resultBlock.End;

                this.memoryMove(resultBlock.End, resultBlock.Address, count);
                int sti = this.allocationsByAddress.GetLeftmostGreaterOrEqualIndex(new MemoryBlockByAddress(resultBlock.End, 0L), out foundNode);
                int eni = this.allocationsByAddress.GetLeftmostGreaterOrEqualIndex(new MemoryBlockByAddress(block.Address, 0L), out foundNode);
                actualCost += count;
                long delta = resultBlock.Size;
                for (int k = eni; --k >= sti;)
                {
                    this.allocationsByAddress[k].Address -= delta;
                }
                resultBlock = new MemoryBlockByAddress(block.Address - resultBlock.Size, resultBlock.Size + block.Size);
            }

            if (actualCost != maxFreeBlockCost)
            {
                Debugger.Break();
            }

            for (int i = endIndex + 1; --i >= startIndex;)
            {
                MemoryBlockBySize memoryBlockSize = this.structureByAddress[i].ToSize;
                this.structureBySize.Remove(memoryBlockSize);
                this.structureByAddress.RemoveAt(i);
            }
            this.structureByAddress.Add(resultBlock);
            this.structureBySize.Add(resultBlock.ToSize);
        }