public int SearchFirst(object key, IIndexComparer <T> comparer) { int blockNum = FindFirstBlock(key, comparer); int sr; if (blockNum < 0) { // Guarenteed not found in any blocks so return start of insert block blockNum = (-(blockNum + 1)); // - 1; sr = -1; } else { // We got a block, so find out if it's in the block or not. var block = Blocks[blockNum]; // Try and find it in the block, sr = block.SearchFirst(key, comparer); } int offset = 0; for (int i = 0; i < blockNum; ++i) { var block = Blocks[i]; offset += block.Count; } return(sr >= 0 ? offset + sr : -offset + sr); }
/// <summary> /// Uses a binary search algorithm to quickly determine the index of the /// <see cref="IIndexBlock{T}"/> within 'blocks' of the block /// that contains the given key value using the <see cref="IIndexComparer{T}"/> /// as a lookup comparator. /// </summary> /// <param name="key"></param> /// <param name="comparer"></param> /// <returns></returns> private int FindBlockContaining(object key, IIndexComparer <T> comparer) { if (Count == 0) { return(-1); } int low = 0; int high = Blocks.Count - 1; while (low <= high) { int mid = (low + high) / 2; var block = Blocks[mid]; // Is what we are searching for lower than the bottom value? if (comparer.CompareValue(block.Bottom, (Field)key) > 0) { high = mid - 1; } // No, then is it greater than the highest value? else if (comparer.CompareValue(block.Top, (Field)key) < 0) { low = mid + 1; } // Must be inside this block then! else { return(mid); } } return(-(low + 1)); // key not found. }
public T RemoveSort(object key, T value, IIndexComparer <T> comparer) { CheckImmutable(); // Find the range of blocks that the value is in. int origBlockIndex = FindFirstBlock(key, comparer); int blockIndex = origBlockIndex; int lastBlockIndex = Blocks.Count - 1; if (blockIndex < 0) { // Not found in a block, throw new InvalidOperationException("Value (" + key + ") was not found in the list."); } var block = Blocks[blockIndex]; int i = block.IndexOf(value); while (i == -1) { // If not found, go to next block ++blockIndex; if (blockIndex > lastBlockIndex) { throw new InvalidOperationException("Value (" + key + ") was not found in the list."); } block = Blocks[blockIndex]; // Try and find the value within this block i = block.IndexOf(value); } // Remove value from the block, return(RemoveFromBlock(blockIndex, block, i)); }
/// <inheritdoc/> public int BinarySearch(object key, IIndexComparer <T> comparer) { var arr = GetArray(true); int low = 0; int high = count - 1; while (low <= high) { int mid = (low + high) / 2; int cmp = comparer.CompareValue(arr[mid], (DataObject)key); if (cmp < 0) { low = mid + 1; } else if (cmp > 0) { high = mid - 1; } else { return(mid); // key found } } return(-(low + 1)); // key not found. }
/// <summary> /// Uses a binary search algorithm to quickly determine the index of /// the <see cref="IIndexBlock{T}"/> within 'blocks' of the block /// that contains the given key value using the <see cref="IIndexComparer{T}"/> /// as a lookup comparator. /// </summary> /// <param name="key"></param> /// <param name="comparer"></param> /// <returns></returns> private int FindLastBlock(object key, IIndexComparer <T> comparer) { if (Count == 0) { return(-1); } int low = 0; int high = Blocks.Count - 1; while (low <= high) { if (high - low <= 2) { for (int i = high; i >= low; --i) { var block1 = Blocks[i]; if (comparer.CompareValue(block1.Bottom, (Field)key) <= 0) { if (comparer.CompareValue(block1.Top, (Field)key) >= 0) { return(i); } return(-(i + 1) - 1); } } return(-(low + 1)); } int mid = (low + high) / 2; var block = Blocks[mid]; // Is what we are searching for lower than the bottom value? if (comparer.CompareValue(block.Bottom, (Field)key) > 0) { high = mid - 1; } // No, then is it greater than the highest value? else if (comparer.CompareValue(block.Top, (Field)key) < 0) { low = mid + 1; } // Equal, so highest must be someplace between mid and high. else { low = mid; if (low == high) { return(low); } } } return(-(low + 1)); // key not found. }
public bool Contains(object key, IIndexComparer <T> comparer) { int blockIndex = FindBlockContaining(key, comparer); if (blockIndex < 0) { // We didn't find in the list, so return false. return(false); } // We got a block, so find out if it's in the block or not. var block = Blocks[blockIndex]; // Find, if not there then return false. return(block.BinarySearch(key, comparer) >= 0); }
/// <inheritdoc/> public int SearchFirst(object key, IIndexComparer <T> comparer) { var arr = GetArray(true); int low = 0; int high = count - 1; while (low <= high) { if (high - low <= 2) { for (int i = low; i <= high; ++i) { int cmp1 = comparer.CompareValue(arr[i], (DataObject)key); if (cmp1 == 0) { return(i); } if (cmp1 > 0) { return(-(i + 1)); } } return(-(high + 2)); } int mid = (low + high) / 2; int cmp = comparer.CompareValue(arr[mid], (DataObject)key); if (cmp < 0) { low = mid + 1; } else if (cmp > 0) { high = mid - 1; } else { high = mid; } } return(-(low + 1)); // key not found. }
public void InsertSort(object key, T value, IIndexComparer <T> comparer) { CheckImmutable(); int blockIndex = FindLastBlock(key, comparer); if (blockIndex < 0) { // Not found a block, // The block to insert the value, blockIndex = (-(blockIndex + 1)) - 1; if (blockIndex < 0) { blockIndex = 0; } } // We got a block, so find out if it's in the block or not. var block = Blocks[blockIndex]; // The point to insert in the block, int i = block.SearchLast(key, comparer); if (i < 0) { i = -(i + 1); } else { i = i + 1; // NOTE: A block can never become totally full so it's always okay to // skip one ahead. } // Insert value into the block, InsertIntoBlock(value, blockIndex, block, i); }
public InsertSearchIndex(ITable table, int columnOffset) : base(table, columnOffset) { comparer = new IndexComparerImpl(this); list = new BlockIndex <int>(); }
protected override void Dispose(bool disposing) { list = null; comparer = null; }
/// <summary> /// Disposes this scheme. /// </summary> public override void Dispose() { // Close and invalidate. list = null; comparer = null; }
/// <summary> /// Sets the internal comparator that enables us to sort and lookup on the /// data in this column. /// </summary> private void SetupComparer() { comparer = new IndexComparerImpl(this); }