private bool TryGetSmallestEntry(ulong stream, int startNumber, int endNumber, out IndexEntry entry) { Ensure.Nonnegative(startNumber, "startNumber"); Ensure.Nonnegative(endNumber, "endNumber"); entry = TableIndex.InvalidIndexEntry; var startKey = BuildKey(stream, startNumber); var endKey = BuildKey(stream, endNumber); if (startKey.GreaterThan(_maxEntry) || endKey.SmallerThan(_minEntry)) { return(false); } var workItem = GetWorkItem(); try { var recordRange = LocateRecordRange(startKey); long low = recordRange.Lower; long high = recordRange.Upper; while (low < high) { var mid = low + (high - low + 1) / 2; var midpoint = ReadEntry(_indexEntrySize, mid, workItem, _version); var midpointKey = new IndexEntryKey(midpoint.Stream, midpoint.Version); if (midpointKey.SmallerThan(startKey)) { high = mid - 1; } else { low = mid; } } var candEntry = ReadEntry(_indexEntrySize, high, workItem, _version); var candidateKey = new IndexEntryKey(candEntry.Stream, candEntry.Version); if (candidateKey.SmallerThan(startKey)) { throw new Exception(string.Format("candEntry ({0}@{1}) < startKey {2}, stream {3}, startNum {4}, endNum {5}, PTable: {6}.", candEntry.Stream, candEntry.Version, startKey, stream, startNumber, endNumber, Filename)); } if (candidateKey.GreaterThan(endKey)) { return(false); } entry = candEntry; return(true); } finally { ReturnWorkItem(workItem); } }
public IEnumerable <IndexEntry> GetRange(ulong stream, long startNumber, long endNumber, int?limit = null) { Ensure.Nonnegative(startNumber, "startNumber"); Ensure.Nonnegative(endNumber, "endNumber"); ulong hash = GetHash(stream); var result = new List <IndexEntry>(); var startKey = BuildKey(hash, startNumber); var endKey = BuildKey(hash, endNumber); if (startKey.GreaterThan(_maxEntry) || endKey.SmallerThan(_minEntry)) { return(result); } var workItem = GetWorkItem(); try { IndexEntryKey lowBoundsCheck, highBoundsCheck; var recordRange = LocateRecordRange(endKey, out lowBoundsCheck, out highBoundsCheck); long low = recordRange.Lower; long high = recordRange.Upper; while (low < high) { var mid = low + (high - low) / 2; IndexEntry midpoint = ReadEntry(_indexEntrySize, mid, workItem, _version); var midpointKey = new IndexEntryKey(midpoint.Stream, midpoint.Version); if (midpointKey.GreaterThan(lowBoundsCheck)) { throw new MaybeCorruptIndexException(String.Format( "Midpoint key (stream: {0}, version: {1}) > low bounds check key (stream: {2}, version: {3})", midpointKey.Stream, midpointKey.Version, lowBoundsCheck.Stream, lowBoundsCheck.Version)); } else if (!midpointKey.GreaterEqualsThan(highBoundsCheck)) { throw new MaybeCorruptIndexException(String.Format( "Midpoint key (stream: {0}, version: {1}) < high bounds check key (stream: {2}, version: {3})", midpointKey.Stream, midpointKey.Version, highBoundsCheck.Stream, highBoundsCheck.Version)); } if (midpointKey.SmallerEqualsThan(endKey)) { high = mid; highBoundsCheck = midpointKey; } else { low = mid + 1; lowBoundsCheck = midpointKey; } } PositionAtEntry(_indexEntrySize, high, workItem); for (long i = high, n = Count; i < n; ++i) { IndexEntry entry = ReadNextNoSeek(workItem, _version); var candidateKey = new IndexEntryKey(entry.Stream, entry.Version); if (candidateKey.GreaterThan(endKey)) { throw new MaybeCorruptIndexException(string.Format( "entry ({0}@{1}) > endKey {2}, stream {3}, startNum {4}, endNum {5}, PTable: {6}.", entry.Stream, entry.Version, startKey, stream, startNumber, endNumber, Filename)); } if (candidateKey.SmallerThan(startKey)) { return(result); } result.Add(entry); if (result.Count == limit) { break; } } return(result); } finally { ReturnWorkItem(workItem); } }
private bool TryGetLargestEntry(ulong stream, long startNumber, long endNumber, out IndexEntry entry) { Ensure.Nonnegative(startNumber, "startNumber"); Ensure.Nonnegative(endNumber, "endNumber"); entry = TableIndex.InvalidIndexEntry; var startKey = BuildKey(stream, startNumber); var endKey = BuildKey(stream, endNumber); if (startKey.GreaterThan(_maxEntry) || endKey.SmallerThan(_minEntry)) { return(false); } var workItem = GetWorkItem(); try { IndexEntryKey lowBoundsCheck, highBoundsCheck; var recordRange = LocateRecordRange(endKey, out lowBoundsCheck, out highBoundsCheck); long low = recordRange.Lower; long high = recordRange.Upper; while (low < high) { var mid = low + (high - low) / 2; IndexEntry midpoint = ReadEntry(_indexEntrySize, mid, workItem, _version); var midpointKey = new IndexEntryKey(midpoint.Stream, midpoint.Version); if (midpointKey.GreaterThan(lowBoundsCheck)) { throw new MaybeCorruptIndexException(String.Format( "Midpoint key (stream: {0}, version: {1}) > low bounds check key (stream: {2}, version: {3})", midpointKey.Stream, midpointKey.Version, lowBoundsCheck.Stream, lowBoundsCheck.Version)); } else if (!midpointKey.GreaterEqualsThan(highBoundsCheck)) { throw new MaybeCorruptIndexException(String.Format( "Midpoint key (stream: {0}, version: {1}) < high bounds check key (stream: {2}, version: {3})", midpointKey.Stream, midpointKey.Version, highBoundsCheck.Stream, highBoundsCheck.Version)); } if (midpointKey.GreaterThan(endKey)) { low = mid + 1; lowBoundsCheck = midpointKey; } else { high = mid; highBoundsCheck = midpointKey; } } var candEntry = ReadEntry(_indexEntrySize, high, workItem, _version); var candKey = new IndexEntryKey(candEntry.Stream, candEntry.Version); if (candKey.GreaterThan(endKey)) { throw new MaybeCorruptIndexException(string.Format( "candEntry ({0}@{1}) > startKey {2}, stream {3}, startNum {4}, endNum {5}, PTable: {6}.", candEntry.Stream, candEntry.Version, startKey, stream, startNumber, endNumber, Filename)); } if (candKey.SmallerThan(startKey)) { return(false); } entry = candEntry; return(true); } finally { ReturnWorkItem(workItem); } }
public IEnumerable<IndexEntry> GetRange(ulong stream, int startNumber, int endNumber, int? limit = null) { Ensure.Nonnegative(startNumber, "startNumber"); Ensure.Nonnegative(endNumber, "endNumber"); ulong hash = GetHash(stream); var result = new List<IndexEntry>(); var startKey = BuildKey(hash, startNumber); var endKey = BuildKey(hash, endNumber); if (startKey.GreaterThan(_maxEntry) || endKey.SmallerThan(_minEntry)) return result; var workItem = GetWorkItem(); try { var recordRange = LocateRecordRange(endKey); long low = recordRange.Lower; long high = recordRange.Upper; while (low < high) { var mid = low + (high - low) / 2; IndexEntry midpoint = ReadEntry(_indexEntrySize, mid, workItem, _version); var midpointKey = new IndexEntryKey(midpoint.Stream, midpoint.Version); if (midpointKey.SmallerEqualsThan(endKey)) high = mid; else low = mid + 1; } PositionAtEntry(_indexEntrySize, high, workItem); for (long i=high, n=Count; i<n; ++i) { IndexEntry entry = ReadNextNoSeek(workItem, _version); var candidateKey = new IndexEntryKey(entry.Stream, entry.Version); if (candidateKey.GreaterThan(endKey)) throw new Exception(string.Format("entry ({0}@{1}) > endKey {2}, stream {3}, startNum {4}, endNum {5}, PTable: {6}.", entry.Stream, entry.Version, startKey, stream, startNumber, endNumber, Filename)); if (candidateKey.SmallerThan(startKey)) return result; result.Add(entry); if (result.Count == limit) break; } return result; } finally { ReturnWorkItem(workItem); } }
private bool TryGetSmallestEntry(ulong stream, int startNumber, int endNumber, out IndexEntry entry) { Ensure.Nonnegative(startNumber, "startNumber"); Ensure.Nonnegative(endNumber, "endNumber"); entry = TableIndex.InvalidIndexEntry; var startKey = BuildKey(stream, startNumber); var endKey = BuildKey(stream, endNumber); if (startKey.GreaterThan(_maxEntry) || endKey.SmallerThan(_minEntry)) return false; var workItem = GetWorkItem(); try { var recordRange = LocateRecordRange(startKey); long low = recordRange.Lower; long high = recordRange.Upper; while (low < high) { var mid = low + (high - low + 1) / 2; var midpoint = ReadEntry(_indexEntrySize, mid, workItem, _version); var midpointKey = new IndexEntryKey(midpoint.Stream, midpoint.Version); if (midpointKey.SmallerThan(startKey)) high = mid - 1; else low = mid; } var candEntry = ReadEntry(_indexEntrySize, high, workItem, _version); var candidateKey = new IndexEntryKey(candEntry.Stream, candEntry.Version); if (candidateKey.SmallerThan(startKey)) throw new Exception(string.Format("candEntry ({0}@{1}) < startKey {2}, stream {3}, startNum {4}, endNum {5}, PTable: {6}.", candEntry.Stream, candEntry.Version, startKey, stream, startNumber, endNumber, Filename)); if (candidateKey.GreaterThan(endKey)) return false; entry = candEntry; return true; } finally { ReturnWorkItem(workItem); } }