public IEnumerable <TapeRecord> ReadRecords(long afterVersion, int maxCount)
        {
            if (afterVersion < 0)
            {
                throw new ArgumentOutOfRangeException("afterVersion", "Must be zero or greater.");
            }

            if (maxCount <= 0)
            {
                throw new ArgumentOutOfRangeException("maxCount", "Must be more than zero.");
            }

            // afterVersion + maxCount > long.MaxValue, but transformed to avoid overflow
            if (afterVersion > long.MaxValue - maxCount)
            {
                throw new ArgumentOutOfRangeException("maxCount", "Version will exceed long.MaxValue.");
            }

            var blob = _container.GetBlockBlobReference(_blobName);

            var dataExists = blob.Exists();

            // we return empty result if writer didn't even start writing to the storage.
            if (!dataExists)
            {
                return(Enumerable.Empty <TapeRecord>());
            }

            var blockList = blob.DownloadBlockList();

            var range = GetReadRange(blockList, afterVersion, maxCount);

            if (range.Item4 == 0)
            {
                return(new TapeRecord[0]);
            }

            using (var s = blob.OpenRead())
            {
                s.ReadAheadSize = range.Item2;
                s.Seek(range.Item1, SeekOrigin.Begin);

                using (var reader = new BinaryReader(s))
                {
                    var bytes = reader.ReadBytes(range.Item2);

                    using (var ms = new MemoryStream(bytes))
                    {
                        TapeStreamSerializer.SkipRecords(range.Item3, ms);
                        var records = Enumerable.Range(0, range.Item4)
                                      .Select(i => TapeStreamSerializer.ReadRecord(ms))
                                      .ToArray();

                        return(records);
                    }
                }
            }
        }
예제 #2
0
        public IEnumerable <TapeRecord> ReadRecords(long afterVersion, int maxCount)
        {
            if (afterVersion < 0)
            {
                throw new ArgumentOutOfRangeException("afterVersion", "Must be zero or greater.");
            }

            if (maxCount <= 0)
            {
                throw new ArgumentOutOfRangeException("maxCount", "Must be more than zero.");
            }

            // afterVersion + maxCount > long.MaxValue, but transformed to avoid overflow
            if (afterVersion > long.MaxValue - maxCount)
            {
                throw new ArgumentOutOfRangeException("maxCount", "Version will exceed long.MaxValue.");
            }

            if (!_data.Exists)
            {
                // file could've been created since the last check
                _data.Refresh();
                if (!_data.Exists)
                {
                    yield break;
                }
            }

            using (var file = OpenForRead())
            {
                if (!TapeStreamSerializer.SkipRecords(afterVersion, file))
                {
                    yield break;
                }

                for (var i = 0; i < maxCount; i++)
                {
                    if (file.Position == file.Length)
                    {
                        yield break;
                    }

                    var record = TapeStreamSerializer.ReadRecord(file);

                    yield return(record);
                }
            }
        }