Go to file
Dmitry Belyaev 1b88db07be
continuous-integration/drone/push Build is passing Details
add questions benches
2023-08-26 13:42:50 +03:00
app add questions benches 2023-08-26 13:42:50 +03:00
app_async add questions benches 2023-08-26 13:42:50 +03:00
lib async_zip, async-compression from crates.io 2023-08-18 10:05:22 +03:00
.drone.yml ci: publish lib with all features 2023-08-18 09:33:42 +03:00
.gitignore deps: add `insta` for tests 2023-08-12 21:42:14 +03:00
Cargo.lock add async bench 2023-08-23 13:30:51 +03:00
Cargo.toml add app_async 2023-08-07 22:06:21 +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
bench.txt db::read -- io::Cursor instead of take 2022-11-09 21:31:38 +03:00

README.md

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.

Ссылки