Beispiel #1
0
        /// <summary>
        /// Прочитать метаданные страницы.
        /// </summary>
        /// <param name="stream">Поток.</param>
        private void ReadDataPageMetadata(Stream stream)
        {
            ReadHeader();

            // если LowerOffset больше чем размер заголовка, то значит есть данные на странице.
            if (_header.LowerOffset > DataPageHeader.Size)
            {
                // читаем локальные индексы.
                ReadDataPageLocalIndexes(stream);
            }

            void ReadHeader()
            {
                var buffer = new byte[DataPageHeader.Size];

                stream.Seek(0, SeekOrigin.Begin);
                stream.Read(buffer, 0, DataPageHeader.Size);
                var spanBuffer = buffer.AsSpan();

                _header = new DataPageHeader
                {
                    LowerOffset = spanBuffer.DecodeInt(0, out var nextStartOffset),
                    UpperOffset = spanBuffer.DecodeInt(nextStartOffset, out _)
                };
            }
        }
Beispiel #2
0
        /// <summary>
        /// Единый метод для инициализации страницы.
        /// </summary>
        /// <param name="isCompleted">Является ли страница завершенной?</param>
        private void Initialize(bool isCompleted)
        {
            var fileInfo = new FileInfo(_fileName);

            if (!Directory.Exists(_fileName))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(_fileName));
            }

            var fileStream = new FileStream(
                _fileName,
                FileMode.OpenOrCreate,
                FileAccess.ReadWrite,
                FileShare.ReadWrite,
                _config.BufferSize,
                FileOptions.SequentialScan
                );

            // Если файл не найден, или файл есть, но он не завершенный
            if (!fileInfo.Exists || !isCompleted)
            {
                // если длина оказалась больше 0, значит файл уже существует и инициализирован.
                if (fileStream.Length > 0)
                {
                    ReadDataPageMetadata(fileStream);
                }
                else
                {
                    // файл новый, поэтому заполняем нулями.
                    fileStream.SetLength(_config.PageSize);

                    _header = new DataPageHeader
                    {
                        // для нового файла нижняя граница - после заголовка
                        LowerOffset = DataPageHeader.Size,
                        // а верхняя - конец файла.
                        UpperOffset = (int)fileStream.Length
                    };
                }

                _bufferedFileWriter = new BufferedFileWriter(
                    fileStream,
                    _config.BufferSize,
                    _config.AutoFlushInterval
                    );

                // записать заголовок в файл.
                UpdateHeader();
            }
            else
            {
                // если файл существует и завершен, то читаем только метаданные.
                ReadDataPageMetadata(fileStream);
            }

            // Выключаем индексацию файла операционной системой, так как в файле массив байт, искать по контенту не получится :)
            fileInfo.Attributes = FileAttributes.NotContentIndexed;
        }