chgk_ledb/README.md
2022-10-08 15:39:54 +03:00

64 lines
3.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# chgk_ledb
Утилита загружающая базу данных ЧГК вопросов из ZIP файла в JSON формате в базу данных.
Исходный файл вопросов: `json.zip`, кодировка `UTF-8`.
При загрузке базы информация о пакете(файле/турнире) дублируется в каждом вопросе.
## Выходной формат данных
Для хранения данных используется [bincode](https://crates.io/crates/bincode) и [zstd](https://crates.io/crates/zstd).
Данные вопросов в виде структуры сериализуются через `bincode` в бинарные данные и сжимаются `zstd`. Каждый вопрос сериализуется и сжимается отдельно.
В файле сжатые данные храняться последовательно, после заголовка файла.
### Заголовок файла
В заголовке хранятся только смещения каждого сжатого блока данных, и дополнительно, смещение указывающее на конец файла.
Смещение указывается в виде 32-битного беззнакового целового числа `u32`, сохраненного в виде 4-х байтов от младшего к старшему ([Little Endian](https://ru.wikipedia.org/wiki/Порядок_байтов#Порядок_от_младшего_к_старшему)).
Пример заголовка:
~~~
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`.
## Ссылки
- Источник вопросов: http://db.chgk.info
- Копия файлов базы вопросов: https://gitlab.com/b4tman/db_chgk
- Конвертор в JSON: https://gitea.b4tman.ru/b4tman/chgk_txt2json