Exemple #1
0
 private static int GetLogicalPosition(ReaderWorkItem workItem)
 {
     return workItem.IsMemory ? (int)workItem.Stream.Position : (int)workItem.Stream.Position - ChunkHeader.Size;
 }
Exemple #2
0
        private static bool TryReadBackwardInternal(ReaderWorkItem workItem, int actualPosition, out int length, out LogRecord record)
        {
            length = -1;
            record = null;

            if (actualPosition < 2 * sizeof(int)) // no space even for length prefix and suffix
                return false;

            var realPos = GetRealPosition(actualPosition, workItem.IsMemory);
            workItem.Stream.Position = realPos - sizeof(int);

            length = workItem.Reader.ReadInt32();

            if (length <= 0)
            {
                throw new ArgumentException(
                        string.Format("Log record that ends at actual pos {0} has non-positive length: {1}. "
                                      + "Something is seriously wrong.",
                                      actualPosition,
                                      length));
            }
            if (length > TFConsts.MaxLogRecordSize)
            {
                throw new ArgumentException(
                        string.Format("Log record that ends at actual pos {0} has too large length: {1} bytes, "
                                      + "while limit is {2} bytes.",
                                      actualPosition,
                                      length,
                                      TFConsts.MaxLogRecordSize));
            }

            if (actualPosition < length + 2 * sizeof(int)) // no space for record + length prefix and suffix
                throw new UnableToReadPastEndOfStreamException();

            workItem.Stream.Position = realPos - length - sizeof(int);
            record = LogRecord.ReadFrom(workItem.Reader);

            #if DEBUG
            workItem.Stream.Position = realPos - length - 2*sizeof(int);
            var prefixLength = workItem.Reader.ReadInt32();
            Debug.Assert(prefixLength == length);
            #endif
            return true;
        }
Exemple #3
0
        private bool TryReadForwardInternal(ReaderWorkItem workItem, int actualPosition, out int length, out LogRecord record)
        {
            length = -1;
            record = null;

            workItem.Stream.Position = GetRealPosition(actualPosition, workItem.IsMemory);

            if (!VerifyDataLengthForward(workItem, 2*sizeof(int)))
                return false;

            length = workItem.Reader.ReadInt32();

            if (length <= 0)
            {
                throw new ArgumentException(
                        string.Format("Log record at actual pos {0} has non-positive length: {1}. "
                                      + "Something is seriously wrong.",
                                      actualPosition,
                                      length));
            }
            if (length > TFConsts.MaxLogRecordSize)
            {
                throw new ArgumentException(
                        string.Format("Log record at actual pos {0} has too large length: {1} bytes, "
                                      + "while limit is {2} bytes.",
                                      actualPosition,
                                      length,
                                      TFConsts.MaxLogRecordSize));
            }

            if (!VerifyDataLengthForward(workItem, length + sizeof(int) /*suffix*/))
                throw new UnableToReadPastEndOfStreamException();

            record = LogRecord.ReadFrom(workItem.Reader);

            Debug.Assert(workItem.Reader.ReadInt32() == length); // verify suffix length == prefix length

            return true;
        }
Exemple #4
0
 private bool VerifyDataLengthForward(ReaderWorkItem workItem, int length)
 {
     var chunkSize = _isReadonly ? _chunkFooter.ActualDataSize : _chunkHeader.ChunkSize;
     return GetLogicalPosition(workItem) + length <= chunkSize;
 }
Exemple #5
0
        private int TranslateExactWithMidpoints(ReaderWorkItem workItem, Midpoint[] midpoints, int pos)
        {
            if (pos < midpoints[0].LogPos || pos > midpoints[midpoints.Length - 1].LogPos)
                return -1;

            var recordRange = LocatePosRange(midpoints, pos);
            return TranslateExactWithoutMidpoints(workItem, pos, recordRange.Item1, recordRange.Item2);
        }
Exemple #6
0
        private int TranslateExactWithoutMidpoints(ReaderWorkItem workItem, int pos, int startIndex, int endIndex)
        {
            int low = startIndex;
            int high = endIndex;
            while (low <= high)
            {
                var mid = low + (high - low) / 2;
                var v = ReadPosMap(workItem, mid);

                if (v.LogPos == pos)
                    return v.ActualPos;
                if (v.LogPos < pos)
                    low = mid + 1;
                else
                    high = mid - 1;
            }
            return -1;
        }
Exemple #7
0
        private Tuple<int, int> TranslateClosestForwardWithoutMidpoints(ReaderWorkItem workItem, int pos, int startIndex, int endIndex)
        {
            PosMap res = ReadPosMap(workItem, endIndex);

            if (pos > res.LogPos)
                return Tuple.Create(_actualDataSize, endIndex + 1); // to allow backward reading of the last record, forward read will decline anyway
            int low = startIndex;
            int high = endIndex;
            while (low < high)
            {
                var mid = low + (high - low) / 2;
                var v = ReadPosMap(workItem, mid);

                if (v.LogPos < pos)
                    low = mid + 1;
                else
                {
                    high = mid;
                    res = v;
                }
            }
            return Tuple.Create(res.ActualPos, high);
        }
Exemple #8
0
        private bool TryReadRecordInternal(ReaderWorkItem workItem, int actualPosition, out int length, out LogRecord record)
        {
            length = -1;
            record = null;

            workItem.Stream.Position = GetRealPosition(actualPosition, workItem.IsMemory);

            if (!VerifyStreamLength(workItem.Stream, 4))
                return false;
            
            length = workItem.Reader.ReadInt32();
            CheckLength(workItem, length, actualPosition);

            record = LogRecord.ReadFrom(workItem.Reader);
            return true;
        }
Exemple #9
0
        private Tuple<int, int> TranslateClosestForwardPosition(ReaderWorkItem workItem, int logicalPosition)
        {
            if (!_isReadonly || _chunkFooter.MapSize == 0)
            {
                // this is mostly for ability to read closest backward from the very end
                var logicalPos = Math.Min(_actualDataSize, logicalPosition);
                return Tuple.Create(logicalPos, -1);
            }

            var midpoints = _midpoints;
            if (workItem.IsMemory || midpoints == null)
            {
                var mapCount = _chunkFooter.MapSize / sizeof(ulong);
                return TranslateClosestForwardWithoutMidpoints(workItem, logicalPosition, 0, mapCount - 1);
            }
            return TranslateClosestForwardWithMidpoints(workItem, midpoints, logicalPosition);
        }
Exemple #10
0
        private Tuple<int, int> TranslateClosestForwardWithMidpoints(ReaderWorkItem workItem, Midpoint[] midpoints, int pos)
        {
            if (pos > midpoints[midpoints.Length - 1].LogPos)
                return Tuple.Create(_actualDataSize, midpoints.Length); // to allow backward reading of the last record, forward read will decline anyway

            var recordRange = LocatePosRange(midpoints, pos);
            return TranslateClosestForwardWithoutMidpoints(workItem, pos, recordRange.Item1, recordRange.Item2);
        }
Exemple #11
0
 private int GetLogicalPosition(ReaderWorkItem workItem)
 {
     return(workItem.IsMemory ? (int)workItem.Stream.Position : (int)workItem.Stream.Position - ChunkHeader.Size);
 }
Exemple #12
0
//        private int TranslateClosestWithMidpoints(ReaderWorkItem workItem, Midpoint[] midpoints, int prevPos)
//        {
//            if (prevPos < midpoints[0].LogPos || prevPos >= midpoints[midpoints.Length - 1].LogPos)
//                return -1;
//
//            var recordRange = LocateClosestPosRange(midpoints, prevPos);
//            return TranslateClosestWithoutMidpoints(workItem, prevPos, recordRange.Item1, recordRange.Item2);
//        }

        private Tuple<PosMap, int> TranslateSameOrClosestWithoutMidpoints(ReaderWorkItem workItem, int pos, int startIndex, int endIndex)
        {
            PosMap res = ReadPosMap(workItem, endIndex);
            if (pos > res.LogPos)
                return Tuple.Create(new PosMap(-1, -1), -1);
            int low = startIndex;
            int high = endIndex;
            while (low < high)
            {
                var mid = low + (high - low) / 2;
                var v = ReadPosMap(workItem, mid);

                if (v.LogPos < pos)
                    low = mid + 1;
                else
                {
                    high = mid;
                    res = v;
                }
            }
            return Tuple.Create(res, high);
        }
Exemple #13
0
 private void CheckLength(ReaderWorkItem workItem, int length, int actualPosition)
 {
     if (length <= 0)
     {
         throw new ArgumentException(
                 string.Format("Log record at actual pos {0} has non-positive length: {1}. "
                               + "Something is seriously wrong.",
                               actualPosition,
                               length));
     }
     if (length > TFConsts.MaxLogRecordSize)
     {
         throw new ArgumentException(
                 string.Format("Log record at actual pos {0} has too large length: {1} bytes, "
                               + "while limit is {2} bytes.",
                               actualPosition,
                               length,
                               TFConsts.MaxLogRecordSize));
     }
     if (!VerifyStreamLength(workItem.Stream, length))
         throw new UnableToReadPastEndOfStreamException();
 }
Exemple #14
0
 private PosMap ReadPosMap(ReaderWorkItem workItem, int index)
 {
     var pos = (workItem.IsMemory ? 0 : ChunkHeader.Size) + _chunkFooter.ActualChunkSize + (index << 3);
     workItem.Stream.Seek(pos, SeekOrigin.Begin);
     return new PosMap(workItem.Reader.ReadUInt64());
 }
Exemple #15
0
        private int TranslateExactPosition(ReaderWorkItem workItem, int pos)
        {
            if (!_isReadonly || _chunkFooter.MapSize == 0)
                return pos;

            var midpoints = _midpoints;
            if (workItem.IsMemory || midpoints == null)
            {
                var mapCount = _chunkFooter.MapSize / sizeof(ulong);
                return TranslateExactWithoutMidpoints(workItem, pos, 0, mapCount - 1);
            }
            return TranslateExactWithMidpoints(workItem, midpoints, pos);
        }
Exemple #16
0
 private void ReturnReaderWorkItem(ReaderWorkItem item)
 {
     if (item.IsMemory)
     {
         _memoryStreams.Enqueue(item);
         if (!_cached || _selfdestructin54321)
             TryDestructUnmanagedMemory();
     }
     else
     {
         _streams.Enqueue(item);
         if (_selfdestructin54321)
             TryDestruct();
     }
 }
Exemple #17
0
 private Tuple<PosMap, int> TranslateToSameOrClosestPosition(ReaderWorkItem workItem, int logicalPosition)
 {
     if (!_isReadonly || _chunkFooter.MapSize == 0)
     {
         return Tuple.Create(new PosMap(logicalPosition, logicalPosition), -1);
     }
     else
     {
         return TranslateSameOrClosestWithoutMidpoints(workItem,
                                                       logicalPosition,
                                                       0,
                                                       _chunkFooter.MapSize/sizeof(ulong) - 1);
     }
 }