예제 #1
0
파일: TFChunk.cs 프로젝트: eleks/EventStore
        public RecordWriteResult TryAppend(LogRecord record)
        {
            if (_isReadonly)
            {
                throw new InvalidOperationException("Cannot write to a read-only block.");
            }

            var workItem     = _writerWorkItem;
            var buffer       = workItem.Buffer;
            var bufferWriter = workItem.BufferWriter;
            var stream       = workItem.Stream;

            buffer.SetLength(4);
            buffer.Position = 4;
            record.WriteTo(bufferWriter);
            var length = (int)buffer.Length - 4;

            bufferWriter.Write(length); // length suffix
            buffer.Position = 0;
            bufferWriter.Write(length); // length prefix

            if (stream.Position + length + 8 > ChunkHeader.Size + _chunkHeader.ChunkSize)
            {
                return(RecordWriteResult.Failed(GetLogicalPosition(workItem)));
            }

            var oldPosition = WriteRawData(buffer);

            _actualDataSize = GetLogicalPosition(workItem);
            return(RecordWriteResult.Successful(oldPosition, _actualDataSize));
        }
예제 #2
0
        public RecordWriteResult TryAppend(LogRecord record)
        {
            if (_isReadonly)
            {
                throw new InvalidOperationException("Cannot write to a read-only block.");
            }

            var workItem     = _writerWorkItem;
            var buffer       = workItem.Buffer;
            var bufferWriter = workItem.BufferWriter;
            var stream       = workItem.Stream;

            buffer.SetLength(4);
            buffer.Position = 4;
            record.WriteTo(bufferWriter);
            buffer.Position = 0;
            var toWriteLength = (int)buffer.Length;

            bufferWriter.Write(toWriteLength - 4);

            if (!VerifyStreamLength(stream, toWriteLength))
            {
                return(RecordWriteResult.Failed(GetLogicalPosition(workItem)));
            }

            var oldPosition = WriteRawData(buffer);

            _actualDataSize = GetLogicalPosition(workItem);
            return(RecordWriteResult.Successful(oldPosition, _actualDataSize));
        }
예제 #3
0
        public RecordWriteResult TryAppend(LogRecord record)
        {
            if (_isReadOnly)
            {
                throw new InvalidOperationException("Cannot write to a read-only block.");
            }

            var workItem     = _writerWorkItem;
            var buffer       = workItem.Buffer;
            var bufferWriter = workItem.BufferWriter;
            var stream       = workItem.Stream;

            buffer.SetLength(4);
            buffer.Position = 4;
            record.WriteTo(bufferWriter);
            var length = (int)buffer.Length - 4;

            bufferWriter.Write(length); // length suffix
            buffer.Position = 0;
            bufferWriter.Write(length); // length prefix

            if (stream.Position + length + 2 * sizeof(int) > ChunkHeader.Size + _chunkHeader.ChunkSize)
            {
                return(RecordWriteResult.Failed(GetDataPosition(workItem)));
            }

            var oldPosition = WriteRawData(workItem, buffer);

            _physicalDataSize = (int)GetDataPosition(workItem); // should fit 32 bits
            _logicalDataSize  = ChunkHeader.GetLocalLogPosition(record.LogPosition + length + 2 * sizeof(int));

            // for non-scavenged chunk _physicalDataSize should be the same as _logicalDataSize
            // for scavenged chunk _logicalDataSize should be at least the same as _physicalDataSize
            if ((!ChunkHeader.IsScavenged && _logicalDataSize != _physicalDataSize) ||
                (ChunkHeader.IsScavenged && _logicalDataSize < _physicalDataSize))
            {
                throw new Exception(string.Format("Data sizes violation. Chunk: {0}, IsScavenged: {1}, LogicalDataSize: {2}, PhysicalDataSize: {3}.",
                                                  FileName, ChunkHeader.IsScavenged, _logicalDataSize, _physicalDataSize));
            }

            return(RecordWriteResult.Successful(oldPosition, _physicalDataSize));
        }