public PoolAllocItem(PoolBlockIndex startIndex, PoolBlockIndex endIndex, FIFOMemoryPool pool) { _startIndex = startIndex; _endIndex = endIndex; _writeOffset = 0; _readOffset = 0; _pool = pool; }
/// <summary> /// Common construct a growable and shrinkable fifo memory pool with block size /// </summary> /// <param name="initialPoolSize">Initial pool size</param> /// <param name="shrinkThresholdPercentage">When free size is over shrinkThresholdPercentage of total size, /// pool tries to shrink. But it will never shrink down to smaller than initial size /// </param> /// <param name="blockSize">Block size of pool, pool grows by block</param> private void CommonConstruct(int initialPoolSize, double shrinkThresholdPercentage, int blockSize) { if (shrinkThresholdPercentage <= 0.0 || shrinkThresholdPercentage > 1.0) { throw new System.NotSupportedException("shrinkThresholdPercentage must be bigger than 0.0f, smaller or equal to 1.0"); } _blockSize = blockSize; _blockCount = (initialPoolSize + _blockSize - 1) / _blockSize; if (0 == _blockCount) { _blockCount = 1; } _listOfBlocks = new List<PoolBlock>(); for (int i = 0; i < _blockCount; i++) { PoolBlock poolBlock = new PoolBlock(); poolBlock._bytes = new byte[_blockSize]; _listOfBlocks.Add(poolBlock); } _totalSize = _blockCount * _blockSize; _allocIndex = new PoolBlockIndex(0, 0); _reclaimIndex = new PoolBlockIndex(0, 0); _freeSize = _totalSize; _listOfAllocItems = new List<PoolAllocItem>(); _itemPool = new Queue<PoolAllocItem>(); _allocCount = 0; _freeCount = 0; _accumulatedAllocSize = 0; _shrinkThresholdPercentage = shrinkThresholdPercentage; _initialSize = _totalSize; }
public int Write(byte[] buffer, int srcOffset, PoolBlockIndex blockIndex, int poolItemOffset, int count) { bool lockAcquired = false; try { lockAcquired = Monitor.TryEnter(this); if (lockAcquired) { int absoluteWriteOffset = (blockIndex._blockIndex * _blockSize + blockIndex._blockOffset + poolItemOffset) % _totalSize; if (null == _writeIndex) { _writeIndex = new PoolBlockIndex(absoluteWriteOffset / _blockSize, absoluteWriteOffset % _blockSize); } else { _writeIndex._blockIndex = absoluteWriteOffset / _blockSize; _writeIndex._blockOffset = absoluteWriteOffset % _blockSize; } int bytesLeft = count; int srcIndex = srcOffset; while (bytesLeft > 0) { int bytesToCopy = _blockSize - _writeIndex._blockOffset; bytesToCopy = Math.Min(bytesToCopy, bytesLeft); Array.Copy(buffer, srcIndex, _listOfBlocks[_writeIndex._blockIndex]._bytes, _writeIndex._blockOffset, bytesToCopy); srcIndex += bytesToCopy; bytesLeft -= bytesToCopy; _writeIndex._blockIndex++; if (_writeIndex._blockIndex >= _blockCount) { _writeIndex._blockIndex = 0; } _writeIndex._blockOffset = 0; } return count; } else { return -1; } } finally { if (lockAcquired) { Monitor.Exit(this); } } }
public void IncreaseIndex(PoolBlockIndex curIndex, int offset) { int absoluteIndex = curIndex._blockIndex * _blockSize + curIndex._blockOffset + offset; absoluteIndex = absoluteIndex % _totalSize; curIndex._blockIndex = absoluteIndex / _blockSize; curIndex._blockOffset = absoluteIndex % _blockSize; }
public int CalculateSize(PoolBlockIndex startIndex, PoolBlockIndex endIndex) { int absoluteStartOffset = startIndex._blockIndex * _blockSize + startIndex._blockOffset; int absoluteEndOffset = endIndex._blockIndex * _blockSize + endIndex._blockOffset; if (absoluteEndOffset > absoluteStartOffset) { return absoluteEndOffset - absoluteStartOffset; } else { return absoluteEndOffset + _totalSize - absoluteStartOffset; } }
public PoolBlockIndex(PoolBlockIndex index) { _blockIndex = index._blockIndex; _blockOffset = index._blockOffset; }