예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
            }
        }
예제 #3
0
        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);
            }
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
        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);
            }
        }