Exemplo n.º 1
0
 internal LogsIteratorHelper(String logFile)
 {
     _stream = new FileStream(logFile, FileMode.Open, FileAccess.Read,
         FileShare.ReadWrite);
     Reader = new LineReader(_stream);
     Index = new Index(logFile);
 }
Exemplo n.º 2
0
        /// <summary>
        /// Переиндексация
        /// </summary>
        /// <param name="validationResult">Результат валидации индекса</param>
        /// <param name="logFile">Имя лог-файла</param>
        /// <param name="indexName">Имя индекса</param>
        private void ReIndex(IndexValidationResult validationResult, String logFile, 
            String indexName)
        {
            if (validationResult.State == IndexState.Corrupted && File.Exists(indexName))
                // удаляем существующий индекс
                File.Delete(indexName);

            using (var source = OpenForReading(logFile))
            using (var index = OpenForWriting(indexName))
            {
                var recordId = String.Empty;
                var recordOffset = 0L;
                var recordLines = 0;

                var reader = new LineReader(source);

                using (var writer = new BinaryWriter(index, Encoding.Default))
                {
                    // записываем размер исходного лога
                    writer.Seek(0, SeekOrigin.Begin);
                    writer.Write(source.Length);

                    switch (validationResult.State)
                    {
                        case IndexState.Corrupted:
                            // оставляем место для количества записей в исходном логе
                            writer.Write(validationResult.RecordsCount);
                            break;
                        case IndexState.Obsolete:
                            // подсчет числа записей начнем с последней известной 
                            // записи в логе
                            validationResult.RecordsCount--;
                            // перемещаемся к началу последней записи в логе
                            source.Seek(validationResult.LastRecordOffset, SeekOrigin.Begin);
                            // перемещаемся к концу индексного файла минус один элемент индекса
                            // (начинаем переиндексацию с последней известной записи!)
                            writer.Seek(-(Int32)IndexElementSize, SeekOrigin.End);
                            break;
                    }

                    // читаем исходный лог до конца
                    while (!reader.Eof)
                    {
                        // запоминаем текущую позицию в логе
                        var currentOffset = source.Position;

                        // читаем очередную строку лога
                        var rawEntry = EventRecordHelper.GetRawEntry(reader.ReadLine());
                        // проверяем ее на валидность по числу полей
                        if (!EventRecordHelper.IsValidEntry(rawEntry))
                            // вероятнее всего, это - недозаписанное событие
                            // в текущем логе, прерываем чтение
                            break;

                        // если сохраненный идентификатор записи не совпадает с 
                        // идентификатором считанной строки, эта строка является
                        // первой в записи
                        if (String.Compare(recordId, rawEntry[0]) != 0)
                        {
                            if (!String.IsNullOrEmpty(recordId))
                            {
                                // сведения о предыдущей записи нужно сохранить
                                // в индексном файле
                                writer.Write(recordOffset);
                                writer.Write(recordLines);

                                // обнуляем счетчик строк в записи
                                recordLines = 0;
                            }

                            // увеличиваем счетчик записей в логе
                            validationResult.RecordsCount++;
                            recordId = rawEntry[0];
                            recordOffset = currentOffset;
                        }

                        // увеличиваем число строк в записи
                        recordLines++;

                        // последняя запись
                        if (reader.Eof)
                        {
                            // сохраняем сведения о последней записи
                            writer.Write(recordOffset);
                            writer.Write(recordLines);
                        }
                    }

                    // сохраняем итоговое количество записей в индексе
                    writer.Seek(sizeof(Int64), SeekOrigin.Begin);
                    writer.Write(validationResult.RecordsCount);
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Переиндексация
        /// </summary>
        /// <param name="validationResult">Результат валидации индекса</param>
        /// <param name="logFile">Имя лог-файла</param>
        /// <param name="indexName">Имя индекса</param>
        private void ReIndex(IndexValidationResult validationResult, string logFile,
                             string indexName)
        {
            if (validationResult.State == IndexState.Corrupted && File.Exists(indexName))
            {
                // удаляем существующий индекс
                File.Delete(indexName);
            }

            using (var source = OpenForReading(logFile))
                using (var index = OpenForWriting(indexName))
                {
                    var recordId     = string.Empty;
                    var recordOffset = 0L;
                    var recordLines  = 0;

                    var reader = new LineReader(source);

                    using (var writer = new BinaryWriter(index, Encoding.Default))
                    {
                        // записываем размер исходного лога
                        writer.Seek(0, SeekOrigin.Begin);
                        writer.Write(source.Length);

                        switch (validationResult.State)
                        {
                        case IndexState.Corrupted:
                            // оставляем место для количества записей в исходном логе
                            writer.Write(validationResult.RecordsCount);
                            break;

                        case IndexState.Obsolete:
                            // подсчет числа записей начнем с последней известной
                            // записи в логе
                            validationResult.RecordsCount--;
                            // перемещаемся к началу последней записи в логе
                            source.Seek(validationResult.LastRecordOffset, SeekOrigin.Begin);
                            // перемещаемся к концу индексного файла минус один элемент индекса
                            // (начинаем переиндексацию с последней известной записи!)
                            writer.Seek(-(int)IndexElementSize, SeekOrigin.End);
                            break;
                        }

                        // читаем исходный лог до конца
                        while (!reader.Eof)
                        {
                            // запоминаем текущую позицию в логе
                            var currentOffset = source.Position;

                            // читаем очередную строку лога
                            var rawEntry = EventRecordHelper.GetRawEntry(reader.ReadLine());
                            // проверяем ее на валидность по числу полей
                            if (!EventRecordHelper.IsValidEntry(rawEntry))
                            {
                                // вероятнее всего, это - недозаписанное событие
                                // в текущем логе, прерываем чтение
                                break;
                            }

                            // если сохраненный идентификатор записи не совпадает с
                            // идентификатором считанной строки, эта строка является
                            // первой в записи
                            if (string.Compare(recordId, rawEntry[0]) != 0)
                            {
                                if (!string.IsNullOrEmpty(recordId))
                                {
                                    // сведения о предыдущей записи нужно сохранить
                                    // в индексном файле
                                    writer.Write(recordOffset);
                                    writer.Write(recordLines);

                                    // обнуляем счетчик строк в записи
                                    recordLines = 0;
                                }

                                // увеличиваем счетчик записей в логе
                                validationResult.RecordsCount++;
                                recordId     = rawEntry[0];
                                recordOffset = currentOffset;
                            }

                            // увеличиваем число строк в записи
                            recordLines++;

                            // последняя запись
                            if (reader.Eof)
                            {
                                // сохраняем сведения о последней записи
                                writer.Write(recordOffset);
                                writer.Write(recordLines);
                            }
                        }

                        // сохраняем итоговое количество записей в индексе
                        writer.Seek(sizeof(Int64), SeekOrigin.Begin);
                        writer.Write(validationResult.RecordsCount);
                    }
                }
        }