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); }
public bool Write(LogRecord record, out long newPos) { _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 var written = 0; var leftToWrite = length + 8; while (leftToWrite > 0) { var leftInFile = (int)(_segmentSize - _writerLocalCheck); var amountToWrite = leftToWrite > leftInFile ? leftInFile : leftToWrite; _fileStream.Write(_buffer.GetBuffer(), written, amountToWrite); leftToWrite -= amountToWrite; written += amountToWrite; _writerCheck += amountToWrite; _writerLocalCheck += amountToWrite; if (_writerLocalCheck >= _segmentSize) { _writerLocalCheck -= _segmentSize; _currentSegment++; CreateSegment(_currentSegment); } } _writerCheckpoint.Write(_writerCheck); newPos = _writerCheck; return true; }
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; 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 (workItem.StreamPosition + 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); }
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); }