protected void AddValue(T value) { bool needNewBlock = true; if (blocksCount > 0) { FSBBlock <T> block = blocks[blocksCount - 1]; if (block.count < blockSize) { block.array[block.count++] = value; block.valid = 0; block.wwSizeX = 0; needNewBlock = false; } } if (needNewBlock) { TBlock block = NewBlock(); block.offset = valuesCount; block.count = 1; block.array[0] = value; AllocateBlocks(blocksCount + 1); blocks[blocksCount - 1] = block; } valuesCount++; }
protected T GetValue(int index) { if (index >= valuesCount || index < 0) { throw new IndexOutOfRangeException("index=" + index + " is out of [0, " + valuesCount + ")"); } FSBBlock <T> block = blocks[GetBlockIndex(index)]; return(block.array[index - block.offset]); }
protected void SetValue(int index, T value) { if (index >= valuesCount || index < 0) { throw new IndexOutOfRangeException("index=" + index + " is out of [0, " + valuesCount + ")"); } FSBBlock <T> block = blocks[GetBlockIndex(index)]; block.array[index - block.offset] = value; block.valid = 0; block.wwSizeX = 0; }
protected void RemoveValueAt(int index) { if (index >= valuesCount || index < 0) { throw new IndexOutOfRangeException("index=" + index + " is out of [0, " + valuesCount + ")"); } int i = GetBlockIndex(index); FSBBlock <T> block = blocks[i]; int j = index - block.offset; Array.Copy(block.array, j + 1, block.array, j, block.count - j - 1); block.array[block.count - 1] = default(T); block.count--; block.valid = 0; block.wwSizeX = 0; if (block.count == 0) { Array.Copy(blocks, i + 1, blocks, i, blocksCount - i - 1); blocks[blocksCount - 1] = null; blocksCount--; } else if (i > 0 && blockSize - blocks[i - 1].count >= block.count) { FSBBlock <T> left = blocks[i - 1]; Array.Copy(block.array, 0, left.array, left.count, block.count); left.count += block.count; left.valid = 0; left.wwSizeX = 0; Array.Copy(blocks, i + 1, blocks, i, blocksCount - i - 1); blocks[blocksCount - 1] = null; blocksCount--; } else if (i < blocksCount - 1) { FSBBlock <T> right = blocks[i + 1]; if (blockSize - block.count >= right.count) { Array.Copy(right.array, 0, block.array, block.count, right.count); block.count += right.count; Array.Copy(blocks, i + 2, blocks, i + 1, blocksCount - i - 2); blocks[blocksCount - 1] = null; blocksCount--; } } UpdateIndices(i); }
protected void InsertValue(int index, T value) { if (index > valuesCount || index < 0) { throw new IndexOutOfRangeException("index=" + index + " is out of [0, " + valuesCount + "]"); } int i = GetBlockIndex(index); if (i == -1) { AddValue(value); } else { FSBBlock <T> block = blocks[i]; int j = index - block.offset; if (j == 0 && i > 0 && blocks[i - 1].count < blockSize) { FSBBlock <T> left = blocks[i - 1]; left.array[left.count++] = value; left.valid = 0; left.wwSizeX = 0; } else if (i + 1 > blocksCount) { TBlock rightBlock = NewBlock(); rightBlock.offset = valuesCount; rightBlock.count = 1; rightBlock.array[0] = value; AllocateBlocks(i + 1); blocks[blocksCount - 1] = rightBlock; } else if (block.count < blockSize) { Array.Copy(block.array, j, block.array, j + 1, block.count - j); block.array[j] = value; block.count++; block.valid = 0; block.wwSizeX = 0; } else { T last = block.array[blockSize - 1]; Array.Copy(block.array, j, block.array, j + 1, block.count - j - 1); block.array[j] = value; block.valid = 0; block.wwSizeX = 0; if (i < blocksCount - 1 && blocks[i + 1].count < blockSize) { FSBBlock <T> right = blocks[i + 1]; Array.Copy(right.array, 0, right.array, 1, right.count); right.array[0] = last; right.count++; right.valid = 0; right.wwSizeX = 0; } else { AllocateBlocks(blocksCount + 1); Array.Copy(blocks, i + 1, blocks, i + 2, blocksCount - i - 2); TBlock right = NewBlock(); right.offset = block.offset + block.count; right.count = 1; right.array[0] = last; right.valid = 0; right.wwSizeX = 0; blocks[i + 1] = right; } } UpdateIndices(i); } }