data format in README
This commit is contained in:
parent
8ad88490e7
commit
76f794f167
54
README.md
54
README.md
@ -4,12 +4,58 @@
|
||||
|
||||
Исходный файл вопросов: `json.zip`, кодировка `UTF-8`.
|
||||
|
||||
Выходная база: файл `./db/data.mdb`, формат базы [LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database).
|
||||
|
||||
Работа с базой выполняется с помощью [ledb](https://crates.io/crates/ledb).
|
||||
|
||||
При загрузке базы информация о пакете(файле/турнире) дублируется в каждом вопросе.
|
||||
|
||||
## Выходной формат данных
|
||||
|
||||
Для хранения данных используется [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
|
||||
|
Loading…
Reference in New Issue
Block a user