Go to file
Dmitry bef08e6166
Some checks failed
continuous-integration/drone/push Build is failing
add .drone.yml
2022-10-12 18:01:38 +03:00
src use collection.load(rx) for writer task 2022-10-10 16:15:16 +03:00
.drone.yml add .drone.yml 2022-10-12 18:01:38 +03:00
.gitignore test fmt 1 2022-10-06 21:22:19 +03:00
bench.txt upd bench 2022-10-10 00:09:17 +03:00
Cargo.lock use forked ledb 2022-10-10 16:14:47 +03:00
Cargo.toml use forked ledb 2022-10-10 16:14:47 +03:00
LICENSE add LICENSE 2022-10-02 17:40:27 +03:00
README.md data format in README 2022-10-08 15:39:54 +03:00

chgk_ledb

Утилита загружающая базу данных ЧГК вопросов из ZIP файла в JSON формате в базу данных.

Исходный файл вопросов: json.zip, кодировка UTF-8.

При загрузке базы информация о пакете(файле/турнире) дублируется в каждом вопросе.

Выходной формат данных

Для хранения данных используется bincode и zstd. Данные вопросов в виде структуры сериализуются через bincode в бинарные данные и сжимаются zstd. Каждый вопрос сериализуется и сжимается отдельно. В файле сжатые данные храняться последовательно, после заголовка файла.

Заголовок файла

В заголовке хранятся только смещения каждого сжатого блока данных, и дополнительно, смещение указывающее на конец файла. Смещение указывается в виде 32-битного беззнакового целового числа u32, сохраненного в виде 4-х байтов от младшего к старшему (Little Endian).

Пример заголовка:

00:  10 00 00 00
04:  1A 00 00 00
08:  2E 00 00 00
0А:  3A 00 00 00

данные:

10:  00 00 00 00 00 00 00 00 00 00
1A:  00 00 00 00 00 00 00 00 00 00
     00 00 00 00 00 00 00 00 00 00
2E:  00 00 00 00 00 00 00 00 00 00
     00 00
3A:  (EOF)

В этом примере сохранены 3 записи:

  1. смещение 0x10, длина 10 байт
  2. смещение 0x1A, длина 20 байт
  3. смещение 0x2E, длина 12 байт

Размер файла - 58 байт (0x3A), размер заголовка 16 байт (0x10).

Чтение данных

Пусть размер записи заголовка в байтах = M, количество записей в файле = N.

Тогда для того чтобы:

  • Найти N, нужно прочитать первую запись (M байт) в начале файла и разделить её значение на M;
  • Найти элемент данных с индексом i, нужно последовательно прочитать 2 записи (M * 2 байт), начиная c индекса i (по смещению в файле: i * M). Смещением будет значение по индексу i, длинной - разница между значениями по индексам i + 1 и i.

Далее для каждого вопроса отдельно предполагается распаковка данных через zstd и десериализация через bincode.

Ссылки