Exemplo n.º 1
0
        /// <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;
            }
        }