fix spelling

This commit is contained in:
2026-07-05 21:04:54 +03:00
parent 02eb7d5034
commit f7671826d4
+31 -31
View File
@@ -45,7 +45,7 @@ struct set *set_free(struct set *set);
### `set_new()` ### `set_new()`
Создаёт пустой объект `struct set` — контейнер для строк символов и их будущих hash-значений. Создаёт пустой объект `struct set` — контейнер для строк символов и их будущих hash-значений.
Из релизации: Из реализации:
> internally struct set is just a bag of strings and their hash values. > internally struct set is just a bag of strings and their hash values.
@@ -81,7 +81,7 @@ set_add(s, "malloc@@GLIBC_2.2.5");
``` ```
массив строк массив строк
| (Jenkins OATT) | (Jenkins OAAT)
v v
массив хэшей массив хэшей
| (qsort) | (qsort)
@@ -100,7 +100,7 @@ set-строка
### hash ### hash
Для каждого элемента (строки) высчитывается 32-битный хэш и обрезается до `bpp` младщих бит Для каждого элемента (строки) высчитывается 32-битный хэш и обрезается до `bpp` младших бит
```c ```c
unsigned mask = (1u << bpp) - 1; unsigned mask = (1u << bpp) - 1;
@@ -109,7 +109,7 @@ set->sv[i].v = hash(set->sv[i].s) & mask;
В качестве хэш-функции используется `Jenkins OAAT`. В качестве хэш-функции используется `Jenkins OAAT`.
Получившийся массив сортируется по хэш значениям по возрастанию. При коллизии, печатается `warning: hash collision` в `stderr` Получившийся массив сортируется по хэш-значениям по возрастанию. При коллизии печатается `warning: hash collision` в `stderr`
С помощью функции `uniqv()` в массиве остаются только уникальные значения, возвращаемое значение - размер массива после удаления повторов. С помощью функции `uniqv()` в массиве остаются только уникальные значения, возвращаемое значение - размер массива после удаления повторов.
@@ -136,7 +136,7 @@ unsigned *v = {1, 3, 12, 8};
> `encode_golomb()` - main golomb encoding routine: package integers into bits. > `encode_golomb()` - main golomb encoding routine: package integers into bits.
Для сокращения длины итоговой строки применяется Rice-Golomb кодирование, которое позволяет с параметром `Mshift` записать число `n` как `n >> Mshift`, записанный последовательностью нулей и `n & 2^Mshift` записанный стандартным двоичным кодированием. Целая часть и остаток разделяется единичном битом. Для сокращения длины итоговой строки применяется Rice-Golomb кодирование, которое позволяет с параметром `Mshift` записать число `n` как `n >> Mshift`, записанный последовательностью нулей, и `n & 2^Mshift`, записанный стандартным двоичным кодированием. Целая часть и остаток разделяются единичным битом.
`Mshift` выбирается как `bpp - log2(c) - 1`, т.к. при равномерном распределении `c` хэшей по диапазону `2^bpp`, средняя `delta` будет равна `2^bpp / c` `Mshift` выбирается как `bpp - log2(c) - 1`, т.к. при равномерном распределении `c` хэшей по диапазону `2^bpp`, средняя `delta` будет равна `2^bpp / c`
@@ -161,13 +161,13 @@ bits = 00 1 00101010
Алфавитом для кодирования является `0-9,a-z,A-Z`, но символ `Z` кодирует сразу 61, 62 и 63 следующим образом: Алфавитом для кодирования является `0-9,a-z,A-Z`, но символ `Z` кодирует сразу 61, 62 и 63 следующим образом:
1. в битовую последовательность после кодированием `Z` добавляется 2 бита: 1. в битовую последовательность после кодирования `Z` добавляется 2 бита:
- `00` для 61 - `00` для 61
- `01` для 62 - `01` для 62
- `10` для 63 - `10` для 63
2. битовая последовательность продолжает кодироваться стандартным образом 2. битовая последовательность продолжает кодироваться стандартным образом
Заметим, что данным образом невозможно получить поседовательность `ZZ`, т.к. символ `Z` требует двух старших бит выставленных в `11` Заметим, что данным образом невозможно получить последовательность `ZZ`, т.к. символ `Z` требует двух старших бит, выставленных в `11`
Пример преобразования: Пример преобразования:
@@ -188,7 +188,7 @@ bits = 101111 001000 10
101111 = 1*1 + 0*2 + 1*4 + 1*8 + 1*16 + 1*32 = 61 = Z 101111 = 1*1 + 0*2 + 1*4 + 1*8 + 1*16 + 1*32 = 61 = Z
``` ```
Тогда в последовательность добавляется два бита `00` сразу после бит, кодирующих Z. Тогда в последовательность добавляется два бита `00` сразу после битов, кодирующих Z.
``` ```
bits = 101111 000010 0010 bits = 101111 000010 0010
@@ -204,7 +204,7 @@ bits = 101111 000010 0010
## Сравнение set-строк ## Сравнение set-строк
При сравнении set-строк происходит обратный процесс преобразования до получений хэш-значений При сравнении set-строк происходит обратный процесс преобразования до получения хэш-значений
``` ```
set-строка set-строка
@@ -229,7 +229,7 @@ set-строка
4. для каждого массива хэшей (`v1` и `v2`) создаётся два буферных массива `v(1|2)buf(A|B)` для функции `downsample_set()` 4. для каждого массива хэшей (`v1` и `v2`) создаётся два буферных массива `v(1|2)buf(A|B)` для функции `downsample_set()`
5. С помощью функции `downsample_set()` `bpp` обоих хэшей выравнивается до минимального из `bpp1` и `bpp2`. 5. С помощью функции `downsample_set()` `bpp` обоих хэшей выравнивается до минимального из `bpp1` и `bpp2`.
6. Создаётся два флага `ge` и `le`, для определения вложенности множеств 6. Создаётся два флага `ge` и `le`, для определения вложенности множеств
7. Вложенность множеств проверяется с помощью 3х макросов: `IFGE` `IFLT4` `IFLT8` 7. Вложенность множеств проверяется с помощью трёх макросов: `IFGE` `IFLT4` `IFLT8`
8. Возвращается значение в зависимости от вложенности: 8. Возвращается значение в зависимости от вложенности:
- 1: set1 > set2 - 1: set1 > set2
- 0: set1 == set2 - 0: set1 == set2
@@ -244,7 +244,7 @@ set-строка
### `decode_base62_golomb()` ### `decode_base62_golomb()`
`decode_base62_golomb()` - оптимизированная версия стадий `decode_base62` и `decode_golomb`. Функция считывает сразу по два байта, пользуясь таблицей `word_to_num` преобразовывает их в битовую последовательность, после, набирая до 24х байт, декодирует по Rice-Golomb. `decode_base62_golomb()` - оптимизированная версия стадий `decode_base62` и `decode_golomb`. Функция считывает сразу по два байта, с помощью таблицы `word_to_num` преобразует их в битовую последовательность, затем, набирая до 24 бит, декодирует по Rice-Golomb.
#### `enum` #### `enum`
@@ -273,37 +273,37 @@ enum {
static const unsigned short word_to_num[65536]; static const unsigned short word_to_num[65536];
``` ```
pre-compiled таблица соответствия любой комбинации из двух байт, битовому представлению из 12 символов + возможный флаг Предварительно скомпилированная таблица соответствия любой комбинации из двух байт с битовым представлением из 12 бит + возможный флаг
Таблица строится следующим образом: Таблица строится следующим образом:
1. все значения заполняются `W_EE` как ошибоные 1. все значения заполняются `W_EE` как ошибочные
2. с помощью макроса `AA1` строятся макросы `AA1x2`, `AA1x25` и т.д. вплоть до `AA10x10` и ему аналогичных. 2. с помощью макроса `AA1` строятся макросы `AA1x2`, `AA1x25` и т.д. вплоть до `AA10x10` и ему аналогичных.
- итоговые макросы позволяют быстро заполнить таблицу значениями `[CCI(c1, c2)] = (c1 - b1) | ((c2 - b2) << 6)` - итоговые макросы позволяют быстро заполнить таблицу значениями `[CCI(c1, c2)] = (c1 - b1) | ((c2 - b2) << 6)`
3. аналогичный процесс заполнения для `AZ`, но с добавлением флага `W_AZ` к значениям в таблице. 3. аналогичный процесс заполнения для `AZ`, но с добавлением флага `W_AZ` к значениям в таблице.
4. заполняется таблица для `ZA` значений с флагом `W_ZA`. Невозможности старших бит `11` во втором символе (т.е. символы с 48 номера) проверяется лишь внутри функций, `W_EE` для таких значений не возвращается 4. заполняется таблица для `ZA` значений с флагом `W_ZA`. Недопустимость старших бит `11` во втором символе (т.е. символы со значения 48) проверяется лишь внутри функций, `W_EE` для таких значений не возвращается
5. заполняется таблица для `A0` и `0X` значений с флагами `W_A0` и `W_0X` соответственно. 5. заполняется таблица для `A0` и `0X` значений с флагами `W_A0` и `W_0X` соответственно.
#### Считывание #### Считывание
Функция считывает с помощью макросов `GetXX` несколько бит (стандартно блоками до 24х бит) и передаёт их на декодирование Функция считывает с помощью макросов `GetXX` несколько бит (стандартно блоками до 24 бит) и передаёт их на декодирование
при 24 битах: при 24 битах:
- берутся именно 4 base62-символа (по два пары) - берутся именно 4 base62-символа (две пары)
- значение помещается в 32-битный `unsigned` - значение помещается в 32-битный `unsigned`
- при ограничении `Mshift >= 7` в одну последовательность может поместиться максимум 3 закодированных golomb числа. - при ограничении `Mshift >= 7` в одну последовательность может поместиться максимум 3 закодированных Golomb-числа.
"12 бит" считыватель используется в ситуациях, когда первая пара обычная, а вторая содержит специальный случай "12 бит" считыватель используется в ситуациях, когда первая пара обычная, а вторая содержит специальный случай
"10 бит" считыватель используется в ситуциях с Z-escape "10 бит" считыватель используется в ситуациях с Z-escape
"6 бит" считыватель используется для одного символа. "6 бит" считыватель используется для одного символа.
#### Rice-Golomb декодер #### Rice-Golomb декодер
Декодер постоянно находится в двух состояних: Декодер постоянно находится в двух состояниях:
- `q-state`: ищет unary-префикс и разделительную `1` - `q-state`: ищет unary-префикс и разделительную `1`
- `r-state`: добирает Mshift бит остатка `r` - `r-state`: добирает Mshift бит остатка `r`
@@ -318,9 +318,9 @@ value = (q << Mshift) | r;
Для обработки Z-escape используются макросы `Esc1` и `Esc2`. Для обработки Z-escape используются макросы `Esc1` и `Esc2`.
`Esc1` вызывается при обнаружении `Z` символа и считывает старшие 2 бита у следующего символа. В результате `Esc1` получит 10 бит для golumb-декодера `Esc1` вызывается при обнаружении символа `Z` и считывает старшие 2 бита у следующего символа. В результате `Esc1` получает 10 бит для Golomb-декодера
`Esc2` вызывается после завершения escape-пары и решает что делать дальше: `Esc2` вызывается после завершения escape-пары и решает, что делать дальше:
- обычный символ — обработать 6 бит - обычный символ — обработать 6 бит
- конец строки — завершить декодирование - конец строки — завершить декодирование
@@ -329,9 +329,9 @@ value = (q << Mshift) | r;
#### `QMake` и `RMake` макросы #### `QMake` и `RMake` макросы
`QMake` ищет разделительную единицу в текущем блоке бит. Если блок содержит только нули, все они добавляются к q, после чего функция читает следующий блок. `QMake` ищет разделительную единицу в текущем блоке бит. Если блок содержит только нули, все они добавляются к `q`, после чего функция читает следующий блок.
Если в блоке есть единица, используется `__builtin_ffs(bits)` для определеия позиции первого бита, разделительной для golomb-кода. Оставшиеся биты заполняют r. Если в блоке есть единица, используется `__builtin_ffs(bits)` для определения позиции первого бита, разделительной для Golomb-кода. Оставшиеся биты заполняют `r`.
`RMake` проверяет, набралось ли `Mshift` бит остатка, записывает готовое значение `RMake` проверяет, набралось ли `Mshift` бит остатка, записывает готовое значение
@@ -360,7 +360,7 @@ value = (q << Mshift) | r;
unsigned hash = str[0] | (str[2] << 8) | (str[3] << 16); unsigned hash = str[0] | (str[2] << 8) | (str[3] << 16);
``` ```
массивы `hv` и `ev` представляют из себя аналог LRU кэша размером `CACHE_SIZE=256`. массивы `hv` и `ev` представляют собой аналог LRU-кэша размером `CACHE_SIZE=256`.
Если fingerprint set-строки на декодирование совпал с имеющимся в `hv` массиве, проверяется полное соответствие строки с `ev[i]->str`. В случае hit - элемент помещается на нулевую позицию, остальные элементы сдвигаются. Если fingerprint set-строки на декодирование совпал с имеющимся в `hv` массиве, проверяется полное соответствие строки с `ev[i]->str`. В случае hit - элемент помещается на нулевую позицию, остальные элементы сдвигаются.
При неудачной проверке полной set-строки, поиск по кэшу продолжается. При неудачной проверке полной set-строки, поиск по кэшу продолжается.
@@ -370,9 +370,9 @@ unsigned hash = str[0] | (str[2] << 8) | (str[3] << 16);
- Если кэш не заполнен, декодируемая строка записывается на первую свободную позицию - Если кэш не заполнен, декодируемая строка записывается на первую свободную позицию
- Если кэш заполнен, элемент ставится на `PIVOT_SIZE=243` позицию, элементы с этой позиции сдвигаются. - Если кэш заполнен, элемент ставится на `PIVOT_SIZE=243` позицию, элементы с этой позиции сдвигаются.
#### `SENTINELS` биты #### `SENTINELS` значения
Данные `~0u` биты необходимы при дальнейшем проходе по массиву внутри функции `rpmsetcmp()`, т.к. там происходят прыжки по 4 и 8 элементов. Данные `~0u` значения необходимы при дальнейшем проходе по массиву внутри функции `rpmsetcmp()`, т.к. там происходят прыжки по 4 и 8 элементов.
### `downsample_set()` ### `downsample_set()`
@@ -382,7 +382,7 @@ unsigned hash = str[0] | (str[2] << 8) | (str[3] << 16);
Итоговый массив будет доступен по указателю `w`. Итоговый массив будет доступен по указателю `w`.
Возвращаемое значение - количество элементов в новом массиве `w`. Возвращаемое значение - количество элементов в новом массиве `w`.
Т.к. первоначальный входной массив отсортирован, после обрезания до `bpp` бит, массив будет поделён на две части, обе из которых будут отсортированны. Деление массива будет происходить в месте, где старший бит на позции `bpp+1` становится равным `1`. Т.к. первоначальный входной массив отсортирован, после обрезания до `bpp` бит массив будет поделён на две части, обе из которых будут отсортированы. Деление массива будет происходить в месте, где старший бит на позиции `bpp+1` становится равным `1`.
Далее обе половины массива объединяются в буфере `w`, дубликаты значений удаляются. Далее обе половины массива объединяются в буфере `w`, дубликаты значений удаляются.
@@ -401,7 +401,7 @@ return value = 5
#### Макросы `IFLT*` #### Макросы `IFLT*`
`IFLT8` быстро продвигают `v1`, пока `*v1 < v2val`. Сперва макрос "грубо" прыгает по 8 элементов, далее уточняет с шагом 4, 2, 1. `IFLT8` быстро продвигает `v1`, пока `*v1 < v2val`. Сперва макрос "грубо" прыгает по 8 элементов, далее уточняет с шагом 4, 2, 1.
```text ```text
+8 +8 +8 ... // грубый поиск +8 +8 +8 ... // грубый поиск
@@ -434,11 +434,11 @@ ge = 0;
v2++; v2++;
``` ```
## `SEFT_TEST` флаг ## `SELF_TEST` флаг
При выставленном `SEFT_TEST` флаге происходит следующее: При выставленном `SELF_TEST` флаге происходит следующее:
1. Явно отклчючается `NDEBUG` для работы `assert()` 1. Явно отключается `NDEBUG` для работы `assert()`
2. Компилируются `test_*` функции 2. Компилируются `test_*` функции
3. Компилируется `main()`, запускающая все `test_*` функции 3. Компилируется `main()`, запускающая все `test_*` функции