Ejemplo n.º 1
0
        bool Process(BlockType blockType, ReadOnlySpan <byte> block, IEventStoreObserver observer)
        {
            if ((blockType & BlockType.Compressed) != 0)
            {
                CompressionStrategy.Decompress(ref block);
            }
            var reader = new SpanReader(block);

            if ((blockType & BlockType.HasTypeDeclaration) != 0)
            {
                Mapping.LoadTypeDescriptors(ref reader);
            }
            var  metadata = (blockType & BlockType.HasMetadata) != 0 ? Mapping.LoadObject(ref reader) : null;
            uint eventCount;

            if ((blockType & BlockType.HasOneEvent) != 0)
            {
                eventCount = 1;
            }
            else if ((blockType & BlockType.HasMoreEvents) != 0)
            {
                eventCount = reader.ReadVUInt32();
            }
            else
            {
                eventCount = 0;
            }
            var readEvents = observer.ObservedMetadata(metadata, eventCount);

            if (!readEvents)
            {
                return(observer.ShouldStopReadingNextEvents());
            }
            var events = new object[eventCount];
            var successfulEventCount = 0;

            for (var i = 0; i < eventCount; i++)
            {
                var ev = Mapping.LoadObject(ref reader);
                if (ev == null)
                {
                    continue;
                }
                events[successfulEventCount] = ev;
                successfulEventCount++;
            }

            if (eventCount != successfulEventCount)
            {
                Array.Resize(ref events, successfulEventCount);
            }

            observer.ObservedEvents(events);
            return(observer.ShouldStopReadingNextEvents());
        }
Ejemplo n.º 2
0
        bool Process(BlockType blockType, ByteBuffer block, IEventStoreObserver observer)
        {
            if ((blockType & BlockType.Compressed) != 0)
            {
                CompressionStrategy.Decompress(ref block);
            }
            var reader = new ByteBufferReader(block);

            if ((blockType & BlockType.HasTypeDeclaration) != 0)
            {
                Mapping.LoadTypeDescriptors(reader);
            }
            var  metadata = (blockType & BlockType.HasMetadata) != 0 ? Mapping.LoadObject(reader) : null;
            uint eventCount;

            if ((blockType & BlockType.HasOneEvent) != 0)
            {
                eventCount = 1;
            }
            else if ((blockType & BlockType.HasMoreEvents) != 0)
            {
                eventCount = reader.ReadVUInt32();
            }
            else
            {
                eventCount = 0;
            }
            var readEvents = observer.ObservedMetadata(metadata, eventCount);

            if (!readEvents)
            {
                return(observer.ShouldStopReadingNextEvents());
            }
            var events = new object[eventCount];

            for (var i = 0; i < eventCount; i++)
            {
                events[i] = Mapping.LoadObject(reader);
            }
            observer.ObservedEvents(events);
            return(observer.ShouldStopReadingNextEvents());
        }
Ejemplo n.º 3
0
        public void ReadToEnd(IEventStoreObserver observer)
        {
            var overflowWriter      = default(ByteBufferWriter);
            var bufferBlock         = new byte[FirstReadAhead + MaxBlockSize];
            var bufferStartPosition = NextReadPosition & SectorMask;
            var bufferFullLength    = 0;
            var bufferReadOffset    = (int)(NextReadPosition - bufferStartPosition);
            var currentReadAhead    = FirstReadAhead;
            var buf           = ByteBuffer.NewSync(bufferBlock, bufferFullLength, currentReadAhead);
            var bufReadLength = (int)File.Read(buf, bufferStartPosition);

            bufferFullLength += bufReadLength;
            while (true)
            {
                if (bufferStartPosition + (ulong)bufferReadOffset + HeaderSize > File.MaxFileSize)
                {
                    KnownAsFinished = true;
                    return;
                }
                if (bufferReadOffset == bufferFullLength)
                {
                    break;
                }
                if (bufferReadOffset + HeaderSize > bufferFullLength)
                {
                    for (var i = bufferReadOffset; i < bufferFullLength; i++)
                    {
                        if (bufferBlock[i] != 0)
                        {
                            SetCorrupted();
                            return;
                        }
                    }
                    break;
                }
                var blockCheckSum = PackUnpack.UnpackUInt32LE(bufferBlock, bufferReadOffset);
                bufferReadOffset += 4;
                var blockLen = PackUnpack.UnpackUInt32LE(bufferBlock, bufferReadOffset);
                if (blockCheckSum == 0 && blockLen == 0)
                {
                    bufferReadOffset -= 4;
                    break;
                }
                var blockType = (BlockType)(blockLen & 0xff);
                blockLen >>= 8;
                if (blockType == BlockType.LastBlock && blockLen == 0)
                {
                    if (Checksum.CalcFletcher32(bufferBlock, (uint)bufferReadOffset, 4) != blockCheckSum)
                    {
                        SetCorrupted();
                        return;
                    }
                    KnownAsFinished = true;
                    return;
                }
                if (blockLen == 0 && blockType != (BlockType.FirstBlock | BlockType.LastBlock))
                {
                    SetCorrupted();
                    return;
                }
                if (blockLen + HeaderSize > MaxBlockSize)
                {
                    SetCorrupted();
                    return;
                }
                bufferReadOffset += 4;
                var bufferLenToFill = (uint)(bufferReadOffset + (int)blockLen + FirstReadAhead) & SectorMaskUInt;
                if (bufferLenToFill > bufferBlock.Length)
                {
                    bufferLenToFill = (uint)bufferBlock.Length;
                }
                buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, (int)(bufferLenToFill - bufferFullLength));
                if (buf.Length > 0)
                {
                    bufferLenToFill = (uint)(bufferReadOffset + (int)blockLen + currentReadAhead) & SectorMaskUInt;
                    if (bufferLenToFill > bufferBlock.Length)
                    {
                        bufferLenToFill = (uint)bufferBlock.Length;
                    }
                    if (bufferStartPosition + bufferLenToFill > File.MaxFileSize)
                    {
                        bufferLenToFill = (uint)(File.MaxFileSize - bufferStartPosition);
                    }
                    buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, (int)(bufferLenToFill - bufferFullLength));
                    if (buf.Length > 0)
                    {
                        if (currentReadAhead * 4 < MaxBlockSize)
                        {
                            currentReadAhead = currentReadAhead * 2;
                        }
                        bufReadLength     = (int)File.Read(buf, bufferStartPosition + (ulong)bufferFullLength);
                        bufferFullLength += bufReadLength;
                    }
                }
                if (bufferReadOffset + (int)blockLen > bufferFullLength)
                {
                    SetCorrupted();
                    return;
                }
                if (Checksum.CalcFletcher32(bufferBlock, (uint)bufferReadOffset - 4, blockLen + 4) != blockCheckSum)
                {
                    SetCorrupted();
                    return;
                }
                var blockTypeBlock       = blockType & (BlockType.FirstBlock | BlockType.MiddleBlock | BlockType.LastBlock);
                var stopReadingRequested = false;
                if (blockTypeBlock == (BlockType.FirstBlock | BlockType.LastBlock))
                {
                    stopReadingRequested = Process(blockType, ByteBuffer.NewSync(bufferBlock, bufferReadOffset, (int)blockLen), observer);
                }
                else
                {
                    if (blockTypeBlock == BlockType.FirstBlock)
                    {
                        overflowWriter = new ByteBufferWriter();
                    }
                    else if (blockTypeBlock == BlockType.MiddleBlock || blockTypeBlock == BlockType.LastBlock)
                    {
                        if (overflowWriter == null)
                        {
                            SetCorrupted();
                            return;
                        }
                    }
                    else
                    {
                        SetCorrupted();
                        return;
                    }
                    overflowWriter.WriteBlock(ByteBuffer.NewSync(bufferBlock, bufferReadOffset, (int)blockLen));
                    if (blockTypeBlock == BlockType.LastBlock)
                    {
                        stopReadingRequested = Process(blockType, overflowWriter.Data, observer);
                        overflowWriter       = null;
                    }
                }
                bufferReadOffset += (int)blockLen;
                if (overflowWriter == null)
                {
                    NextReadPosition = bufferStartPosition + (ulong)bufferReadOffset;
                }
                if (stopReadingRequested)
                {
                    return;
                }
                var nextBufferStartPosition = (bufferStartPosition + (ulong)bufferReadOffset) & SectorMask;
                var bufferMoveDistance      = (int)(nextBufferStartPosition - bufferStartPosition);
                if (bufferMoveDistance <= 0)
                {
                    continue;
                }
                Array.Copy(bufferBlock, bufferMoveDistance, bufferBlock, 0, bufferFullLength - bufferMoveDistance);
                bufferStartPosition = nextBufferStartPosition;
                bufferFullLength   -= bufferMoveDistance;
                bufferReadOffset   -= bufferMoveDistance;
            }
            if (overflowWriter != null)
            {
                // It is not corrupted here just unfinished, but definitely not appendable
                EndBufferPosition = ulong.MaxValue;
                return;
            }
            EndBufferLen      = (uint)(bufferReadOffset - (bufferReadOffset & SectorMaskUInt));
            EndBufferPosition = bufferStartPosition + (ulong)bufferReadOffset - EndBufferLen;
            Array.Copy(bufferBlock, bufferReadOffset - EndBufferLen, EndBuffer, 0, EndBufferLen);
        }
Ejemplo n.º 4
0
 public void ReadFromStartToEnd(IEventStoreObserver observer)
 {
     NextReadPosition = 0;
     ReadToEnd(observer);
 }
Ejemplo n.º 5
0
 public void ReadToEnd(IEventStoreObserver observer)
 {
     var overflowWriter = default(ByteBufferWriter);
     var bufferBlock = new byte[FirstReadAhead + MaxBlockSize];
     var bufferStartPosition = NextReadPosition & SectorMask;
     var bufferFullLength = 0;
     var bufferReadOffset = (int)(NextReadPosition - bufferStartPosition);
     var currentReadAhead = FirstReadAhead;
     var buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, currentReadAhead);
     var bufReadLength = (int)File.Read(buf, bufferStartPosition);
     bufferFullLength += bufReadLength;
     while (true)
     {
         if (bufferStartPosition + (ulong)bufferReadOffset + HeaderSize > File.MaxFileSize)
         {
             KnownAsFinished = true;
             return;
         }
         if (bufferReadOffset == bufferFullLength)
         {
             break;
         }
         if (bufferReadOffset + HeaderSize > bufferFullLength)
         {
             for (var i = bufferReadOffset; i < bufferFullLength; i++)
             {
                 if (bufferBlock[i] != 0)
                 {
                     SetCorrupted();
                     return;
                 }
             }
             break;
         }
         var blockCheckSum = PackUnpack.UnpackUInt32LE(bufferBlock, bufferReadOffset);
         bufferReadOffset += 4;
         var blockLen = PackUnpack.UnpackUInt32LE(bufferBlock, bufferReadOffset);
         if (blockCheckSum == 0 && blockLen == 0)
         {
             bufferReadOffset -= 4;
             break;
         }
         var blockType = (BlockType)(blockLen & 0xff);
         blockLen >>= 8;
         if (blockType == BlockType.LastBlock && blockLen == 0)
         {
             if (Checksum.CalcFletcher32(bufferBlock, (uint)bufferReadOffset, 4) != blockCheckSum)
             {
                 SetCorrupted();
                 return;
             }
             KnownAsFinished = true;
             return;
         }
         if (blockLen == 0 && blockType != (BlockType.FirstBlock | BlockType.LastBlock))
         {
             SetCorrupted();
             return;
         }
         if (blockLen + HeaderSize > MaxBlockSize)
         {
             SetCorrupted();
             return;
         }
         bufferReadOffset += 4;
         var bufferLenToFill = (uint)(bufferReadOffset + (int)blockLen + FirstReadAhead) & SectorMaskUInt;
         if (bufferLenToFill > bufferBlock.Length) bufferLenToFill = (uint)bufferBlock.Length;
         buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, (int)(bufferLenToFill - bufferFullLength));
         if (buf.Length > 0)
         {
             bufferLenToFill = (uint)(bufferReadOffset + (int)blockLen + currentReadAhead) & SectorMaskUInt;
             if (bufferLenToFill > bufferBlock.Length) bufferLenToFill = (uint)bufferBlock.Length;
             if (bufferStartPosition + bufferLenToFill > File.MaxFileSize)
             {
                 bufferLenToFill = (uint)(File.MaxFileSize - bufferStartPosition);
             }
             buf = ByteBuffer.NewSync(bufferBlock, bufferFullLength, (int)(bufferLenToFill - bufferFullLength));
             if (buf.Length > 0) {
                 if (currentReadAhead * 4 < MaxBlockSize)
                 {
                     currentReadAhead = currentReadAhead * 2;
                 }
                 bufReadLength = (int)File.Read(buf, bufferStartPosition + (ulong)bufferFullLength);
                 bufferFullLength += bufReadLength;
             }
         }
         if (bufferReadOffset + (int)blockLen > bufferFullLength)
         {
             SetCorrupted();
             return;
         }
         if (Checksum.CalcFletcher32(bufferBlock, (uint)bufferReadOffset - 4, blockLen + 4) != blockCheckSum)
         {
             SetCorrupted();
             return;
         }
         var blockTypeBlock = blockType & (BlockType.FirstBlock | BlockType.MiddleBlock | BlockType.LastBlock);
         var stopReadingRequested = false;
         if (blockTypeBlock == (BlockType.FirstBlock | BlockType.LastBlock))
         {
             stopReadingRequested = Process(blockType, ByteBuffer.NewSync(bufferBlock, bufferReadOffset, (int)blockLen), observer);
         }
         else
         {
             if (blockTypeBlock == BlockType.FirstBlock)
             {
                 overflowWriter = new ByteBufferWriter();
             }
             else if (blockTypeBlock == BlockType.MiddleBlock || blockTypeBlock == BlockType.LastBlock)
             {
                 if (overflowWriter == null)
                 {
                     SetCorrupted();
                     return;
                 }
             }
             else
             {
                 SetCorrupted();
                 return;
             }
             overflowWriter.WriteBlock(ByteBuffer.NewSync(bufferBlock, bufferReadOffset, (int)blockLen));
             if (blockTypeBlock == BlockType.LastBlock)
             {
                 stopReadingRequested = Process(blockType, overflowWriter.Data, observer);
                 overflowWriter = null;
             }
         }
         bufferReadOffset += (int)blockLen;
         if (overflowWriter == null)
             NextReadPosition = bufferStartPosition + (ulong)bufferReadOffset;
         if (stopReadingRequested)
         {
             return;
         }
         var nextBufferStartPosition = (bufferStartPosition + (ulong)bufferReadOffset) & SectorMask;
         var bufferMoveDistance = (int)(nextBufferStartPosition - bufferStartPosition);
         if (bufferMoveDistance <= 0) continue;
         Array.Copy(bufferBlock, bufferMoveDistance, bufferBlock, 0, bufferFullLength - bufferMoveDistance);
         bufferStartPosition = nextBufferStartPosition;
         bufferFullLength -= bufferMoveDistance;
         bufferReadOffset -= bufferMoveDistance;
     }
     if (overflowWriter != null)
     {
         // It is not corrupted here just unfinished, but definitely not appendable
         EndBufferPosition = ulong.MaxValue;
         return;
     }
     EndBufferLen = (uint)(bufferReadOffset - (bufferReadOffset & SectorMaskUInt));
     EndBufferPosition = bufferStartPosition + (ulong)bufferReadOffset - EndBufferLen;
     Array.Copy(bufferBlock, bufferReadOffset - EndBufferLen, EndBuffer, 0, EndBufferLen);
 }
Ejemplo n.º 6
0
 public void ReadFromStartToEnd(IEventStoreObserver observer)
 {
     NextReadPosition = 0;
     ReadToEnd(observer);
 }
Ejemplo n.º 7
0
 bool Process(BlockType blockType, ByteBuffer block, IEventStoreObserver observer)
 {
     if ((blockType & BlockType.Compressed) != 0)
     {
         CompressionStrategy.Decompress(ref block);
     }
     var reader = new ByteBufferReader(block);
     if ((blockType & BlockType.HasTypeDeclaration) != 0)
     {
         Mapping.LoadTypeDescriptors(reader);
     }
     var metadata = (blockType & BlockType.HasMetadata) != 0 ? Mapping.LoadObject(reader) : null;
     uint eventCount;
     if ((blockType & BlockType.HasOneEvent) != 0)
     {
         eventCount = 1;
     }
     else if ((blockType & BlockType.HasMoreEvents) != 0)
     {
         eventCount = reader.ReadVUInt32();
     }
     else
     {
         eventCount = 0;
     }
     var readEvents = observer.ObservedMetadata(metadata, eventCount);
     if (!readEvents) return observer.ShouldStopReadingNextEvents();
     var events = new object[eventCount];
     for (var i = 0; i < eventCount; i++)
     {
         events[i] = Mapping.LoadObject(reader);
     }
     observer.ObservedEvents(events);
     return observer.ShouldStopReadingNextEvents();
 }