private RegionState GetBlock(int position, bool addIfMissing = true) { if (position <= 0) { throw new ArgumentException("Position must be greater than 0."); } if (_lastAccessedBlock != null && _lastAccessedBlock.ContainsPosition(position)) // performance improvement to remember last block { return(_lastAccessedBlock); } var blockKey = GetBlockKey(position); RegionState block; if (!_regionLookup.TryGetValue(blockKey, out block)) { if (!addIfMissing) { return(null); } block = CreateOrReuseBlock((blockKey - 1) * _regionSize + 1, blockKey * _regionSize); _regionLookup[blockKey] = block; } _lastAccessedBlock = block; return(block); }
/// <summary> /// Get block by either reusable one that is available for reuse, or creating a new one if non available for reuse. /// </summary> /// <param name="startPosition"></param> /// <param name="endPosition"></param> /// <returns></returns> private RegionState CreateOrReuseBlock(int startPosition, int endPosition) { RegionState block; if (_reusableBlocks.Any()) { block = _reusableBlocks.Pop(); block.Reset(startPosition, endPosition); } else { block = new RegionState(startPosition, endPosition); } return(block); }