public LogBuffers(string logFileName) { var fileInfo = new FileInfo(logFileName); var logLength = fileInfo.Length; var termLength = LogBufferDescriptor.ComputeTermLength(logLength); LogBufferDescriptor.CheckTermLength(termLength); _termLength = termLength; // if log length exceeds MAX_INT we need multiple mapped buffers, (see FileChannel.map doc). if (logLength < int.MaxValue) { var mappedBuffer = IoUtil.MapExistingFile(logFileName); _mappedByteBuffers = new[] { mappedBuffer }; var metaDataSectionOffset = termLength * LogBufferDescriptor.PARTITION_COUNT; for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { var metaDataOffset = metaDataSectionOffset + (i * LogBufferDescriptor.TERM_META_DATA_LENGTH); _atomicBuffers[i] = new UnsafeBuffer(mappedBuffer.Pointer, i * termLength, termLength); _atomicBuffers[i + LogBufferDescriptor.PARTITION_COUNT] = new UnsafeBuffer(mappedBuffer.Pointer, metaDataOffset, LogBufferDescriptor.TERM_META_DATA_LENGTH); } _atomicBuffers[_atomicBuffers.Length - 1] = new UnsafeBuffer(mappedBuffer.Pointer, (int)(logLength - LogBufferDescriptor.LOG_META_DATA_LENGTH), LogBufferDescriptor.LOG_META_DATA_LENGTH); } else { _mappedByteBuffers = new MappedByteBuffer[LogBufferDescriptor.PARTITION_COUNT + 1]; var metaDataSectionOffset = termLength * (long)LogBufferDescriptor.PARTITION_COUNT; var metaDataSectionLength = (int)(logLength - metaDataSectionOffset); var memoryMappedFile = IoUtil.OpenMemoryMappedFile(logFileName); var metaDataMappedBuffer = new MappedByteBuffer(memoryMappedFile, metaDataSectionOffset, metaDataSectionLength); _mappedByteBuffers[_mappedByteBuffers.Length - 1] = metaDataMappedBuffer; for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { _mappedByteBuffers[i] = new MappedByteBuffer(memoryMappedFile, termLength * (long)i, termLength); _atomicBuffers[i] = new UnsafeBuffer(_mappedByteBuffers[i].Pointer, termLength); _atomicBuffers[i + LogBufferDescriptor.PARTITION_COUNT] = new UnsafeBuffer(metaDataMappedBuffer.Pointer, i * LogBufferDescriptor.TERM_META_DATA_LENGTH, LogBufferDescriptor.TERM_META_DATA_LENGTH); } _atomicBuffers[_atomicBuffers.Length - 1] = new UnsafeBuffer(metaDataMappedBuffer.Pointer, metaDataSectionLength - LogBufferDescriptor.LOG_META_DATA_LENGTH, LogBufferDescriptor.LOG_META_DATA_LENGTH); } // TODO try/catch foreach (var buffer in _atomicBuffers) { buffer.VerifyAlignment(); } }
/// <summary> /// Set the length of buffer used for each term of the log. Valid values are powers of 2 in the 64K - 1G range. /// </summary> /// <param name="termLength"> of the buffer used for each term of the log. </param> /// <returns> this for a fluent API. </returns> /// <seealso cref="Aeron.Context.TERM_LENGTH_PARAM_NAME"/> public ChannelUriStringBuilder TermLength(int?termLength) { if (null != termLength) { LogBufferDescriptor.CheckTermLength(termLength.Value); } _termLength = termLength; return(this); }
public LogBuffers(string logFileName, int termLength = LogBufferDescriptor.TERM_MIN_LENGTH) { try { long logLength = LogBufferDescriptor.PARTITION_COUNT * (LogBufferDescriptor.TERM_META_DATA_LENGTH + termLength) + LogBufferDescriptor.LOG_META_DATA_LENGTH; termLength = LogBufferDescriptor.ComputeTermLength(logLength); LogBufferDescriptor.CheckTermLength(termLength); _df = new DirectFile(logFileName, logLength); _termLength = termLength; // if log length exceeds MAX_INT we need multiple mapped buffers, (see FileChannel.map doc). if (logLength < int.MaxValue) { int metaDataSectionOffset = termLength * LogBufferDescriptor.PARTITION_COUNT; for (int i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { int metaDataOffset = metaDataSectionOffset + (i * LogBufferDescriptor.TERM_META_DATA_LENGTH); _buffers[i] = new DirectBuffer(termLength, _df.Buffer.Data + i * termLength); _buffers[i + LogBufferDescriptor.PARTITION_COUNT] = new DirectBuffer(LogBufferDescriptor.TERM_META_DATA_LENGTH, _df.Buffer.Data + metaDataOffset); _partitions[i] = new LogBufferPartition(_buffers[i], _buffers[i + LogBufferDescriptor.PARTITION_COUNT]); } _buffers[_buffers.Length - 1] = new DirectBuffer(LogBufferDescriptor.LOG_META_DATA_LENGTH, _df.Buffer.Data + (int)(logLength - LogBufferDescriptor.LOG_META_DATA_LENGTH)); } else { throw new NotImplementedException("TODO Check .NET mapping limit"); } } catch (IOException ex) { throw new AggregateException(ex); } foreach (var buffer in _buffers) { buffer.VerifyAlignment(8); } }
/// <summary> /// Construct the log buffers for a given log file. /// </summary> /// <param name="logFileName"></param> public LogBuffers(string logFileName) { try { var fileInfo = new FileInfo(logFileName); var logLength = fileInfo.Length; // if log length exceeds MAX_INT we need multiple mapped buffers, (see FileChannel.map doc). if (logLength < int.MaxValue) { var mappedBuffer = IoUtil.MapExistingFile(logFileName, MapMode.ReadWrite); // TODO Java has sparse hint & Little Endian _mappedByteBuffers = new[] { mappedBuffer }; _logMetaDataBuffer = new UnsafeBuffer(mappedBuffer.Pointer, (int)(logLength - LogBufferDescriptor.LOG_META_DATA_LENGTH), LogBufferDescriptor.LOG_META_DATA_LENGTH); int termLength = LogBufferDescriptor.TermLength(_logMetaDataBuffer); int pageSize = LogBufferDescriptor.PageSize(_logMetaDataBuffer); LogBufferDescriptor.CheckTermLength(termLength); LogBufferDescriptor.CheckPageSize(pageSize); _termLength = termLength; for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { _termBuffers[i] = new UnsafeBuffer(mappedBuffer.Pointer, i * termLength, termLength); } } else { _mappedByteBuffers = new MappedByteBuffer[LogBufferDescriptor.PARTITION_COUNT + 1]; int assumedTermLength = LogBufferDescriptor.TERM_MAX_LENGTH; long metaDataSectionOffset = assumedTermLength * (long)LogBufferDescriptor.PARTITION_COUNT; long metaDataMappingLength = logLength - metaDataSectionOffset; var memoryMappedFile = IoUtil.OpenMemoryMappedFile(logFileName); var metaDataMappedBuffer = new MappedByteBuffer(memoryMappedFile, metaDataSectionOffset, metaDataMappingLength); // Little Endian _mappedByteBuffers[LogBufferDescriptor.LOG_META_DATA_SECTION_INDEX] = metaDataMappedBuffer; _logMetaDataBuffer = new UnsafeBuffer( metaDataMappedBuffer.Pointer, (int)metaDataMappingLength - LogBufferDescriptor.LOG_META_DATA_LENGTH, LogBufferDescriptor.LOG_META_DATA_LENGTH); int metaDataTermLength = LogBufferDescriptor.TermLength(_logMetaDataBuffer); int pageSize = LogBufferDescriptor.PageSize(_logMetaDataBuffer); LogBufferDescriptor.CheckPageSize(pageSize); if (metaDataTermLength != assumedTermLength) { throw new InvalidOperationException( $"assumed term length {assumedTermLength} does not match metadta: termLength = {metaDataTermLength}"); } _termLength = assumedTermLength; for (var i = 0; i < LogBufferDescriptor.PARTITION_COUNT; i++) { long position = assumedTermLength * (long)i; _mappedByteBuffers[i] = new MappedByteBuffer(memoryMappedFile, position, assumedTermLength); // Little Endian _termBuffers[i] = new UnsafeBuffer(_mappedByteBuffers[i].Pointer, 0, assumedTermLength); } } } catch (InvalidOperationException ex) { Dispose(); throw ex; } }