add Docs sec

This commit is contained in:
2026-07-01 19:19:09 +03:00
parent 23f381b068
commit c7ba3e4629
3 changed files with 157 additions and 0 deletions
+19
View File
@@ -0,0 +1,19 @@
# TODO
just to-do for krosh.
- [ ] Описать работу кода set.c
- [ ] Общий "скелет"
- [ ] часть вводов-выводов
- [ ] hash часть
- [ ] delta часть
- [ ] golomb часть
- [ ] base62(64) часть
- [ ] Протестировать, понять процент прироста от optimized кода
- [ ] research
- [ ] хэши, оптимальный ли этот, подходят ли другие
- точно были вопросы к коллизиям + кодировкам изначального ascii (условно много повторов на одинаковых наборах)
- [ ] кодировки, существование и применимость других
- [ ] реализация base62
- [ ] Написать "аналог" на другом ЯП (Python?)
- решить, какие использовать хэш функции, функции кодирования и т.д.
+92
View File
@@ -0,0 +1,92 @@
# set:version
what is happening inside [set:version](https://git.altlinux.org/gears/r/rpm.git?a=blob;f=lib/set.c)
## Зачем
set:version в alt-rpm позволяет сопоставлять Provides и Requires пакетов не обычным сравнением версий, а сравнением специальных set-строк зависимостей вида
```text
libfoo.so.X = set:<encoded-set>
```
`encoded-set` формируется на основе символов, необходимых/предоставляемых пакетом. Данный механизм позволяет гарантировать (с точностью до коллизий хэша, об этом будет далее) наличие всех требуемых символов в библиотеке. Это исключает ситуации, при которых ">= версий" ломается при удалении символа из библиотеки, а также ситуаций совпадения SONAME библиотек с разным набором символов.
set-строки (являющиеся перекодированным списком символов) генерируются способом, который позволяет их сравнивать между собой на предмет включения одного множества символов в другой.
## Реализация `set.c`
`set.c` предоставляет 5 "публичных" API для работы set:version
```c
int rpmsetcmp(const char *set1, const char *set2);
struct set *set_new(void);
void set_add(struct set *set, const char *sym);
const char *set_fini(struct set *set, int bpp);
struct set *set_free(struct set *set);
```
### `rpmsetcmp()`
Основная функция, сравнивающая строки и выдающая результат в зависимости от включения:
* 1: set1 > set2
* 0: set1 == set2
* -1: set1 < set2 (aka set1 \subset set2)
* -2: set1 != set2
* -3: set1 decoder error
* -4: set2 decoder error
на основе [данной](https://github.com/svpv/rpmss/blob/4256d86cc9ba1aa4ceb8c0f03f7d48675d9d27bb/set.h#L12) заметки, `set1` лучше делать как `Provides` для лучшей производительности.
### `set_new()`
Создаёт пустой объект `struct set`.
Внутри `struct set` — это временный контейнер для строк символов и их будущих hash-значений.
Из релизации:
> internally struct set is just a bag of strings and their hash values.
### `set_add()`
Добавляет строковый символ в set.
Использование:
```c
set_add(s, "printf@@GLIBC_2.2.5");
set_add(s, "malloc@@GLIBC_2.2.5");
```
### `set_fini()`
Финализирует множество и возвращает готовую set-version строку.
Внутри происходит основная работа:
1. Jenkins hash
2. обрезка до bpp бит
3. сортировка
4. delta кодирование
5. golomb кодирование
6. base62(64) кодирование
### `set_free()`
Освобождает struct set и его внутренние строки.
## `set.c` под капотом
### hash
### delta
### golomb
### base62
## Комментарии
## additional
[коды](https://altlinux.space/arseny/atsv-research) от Арсения для наглядности происходящего
some funny [msg's](https://lists.pld-linux.org/mailman/pipermail/pld-devel-en/2013-November/012467.html)
+46
View File
@@ -0,0 +1,46 @@
# raw_data
## messages from tg
[6/23/26 9:57PM] Arseny: Кстати. У меня есть серьёзная математическая, она же очень серьёзная алгоритмическая задача на исследование. ALT set:version (https://git.altlinux.org/gears/r/rpm.git?a=blob;f=lib/set.c) нужен майнтейнер.
[6/23/26 9:57PM] Arseny: Вы хотели алгоритмов? Вот, расскажите мне про этот.
[6/23/26 9:57PM] Arseny: весь алгоритм можно разбить на 4 последовательных стадии.
0) Задача в том, чтобы проверять, выполняется ли R ⊂ P.
множества, стоящие в позиции P, даются командой навроде nm --dynamic -j -U /usr/lib64/libyourfavourite.so.N.
множества, стоящие в позиции R, даются командой навроде nm --dynamic -j -u /usr/bin/yourfavouriteprog, или там может быть иной .so.
Тут, наверное, ещё и введение в предметную область должно быть.
1) hash: N элементов сбрасываются в этот самый хеш; его эффективность бы стоило оценить хорошенько. (гипотеза от меня: он вообще-то плохой и даёт много коллизий на интересных нам инпутах), в результате K <= N отсортированных хешей, чисел из [0; 2**10) (по умолчанию 10 бит на хеш);
2) delta: K <= N чисел из прошлого шага заменяются на разности с предыдущими, и получаются по-другому распределённые числа, чаще маленькие и очень, очень мало сверхбольших; есть мнение, что они для равномерно распределённых хешей распределены геометрически;
3) golomb: эти K разностей кодируются по Rice-Golomb (https://en.wikipedia.org/wiki/Golomb_coding), делитель по умолчанию 2**7; получается префиксный код из K битострок, которые можно слева направо прочесть без lookahead и восстановить массив разностей;
4) (якобы) base62: их конкатенация кодируется в буквы.
(2) и (3) близки к очевидно-понятным; я поизучал, реализовал на питоне (https://altlinux.space/arseny/atsv-research) и снова поизучал.
А вот (1) и (4) я не занимался совсем.
От (4) у меня тоже башка взрывается, а (1) можно очень хорошо так поизучать, и существует, наверное, обширная литература.
[6/23/26 9:57PM] Arseny: grep -A16 Jenkins lib/set.c
вот в этом дереве исходников (https://git.altlinux.org/gears/r/rpm.git?p=rpm.git;a=blob;f=lib/set.c;h=9474a2ee6d7c;hb=a01a87db6e8a)
[6/23/26 9:57PM] Arseny: Пусть параметр-делитель равен M, и энкодеру на вход поступает число A. Тогда ищутся такие q и r < q, что A = qM + r. Частное кодируется унарной кодировкой из единиц, за ним следует нулик, а далее ровно log₂M бит на остаток. Подобрать M нужно с умом.
```sh
python3 stringset.py 10 7 <<EOF
foo
bar
quux
EOF
hashes=[298, 487, 588]
deltas=[298, 189, 101]
codes=[b'1100101010', b'100111101', b'01100101']
golomb divisor: 128 (minimum word bit length: 8)
total bit length: 27
per-elem bit length: 9.000
```
Но здесь не хеш из файла выше, а питонический hash() обычный. Чтобы смотреть на актуальные результаты, нужно подсунуть актуальный.
[6/23/26 9:58PM] Arseny: А вот страничка set:version на ALT Wiki (https://www.altlinux.org/Set-version)
[6/23/26 9:58PM] Arseny: Putze, F.; Sanders, P.; Singler, J. (2007),
253 * "Cache-, Hash- and Space-Efficient Bloom Filters",
254 * http://algo2.iti.uni-karlsruhe.de/singler/publications/cacheefficientbloomfilters-wea2007.pdf
[6/23/26 9:58PM] Arseny: Сайта нет, но статью поискать https://t.me/c/1622441719/1359/9771
[6/23/26 9:59PM] Arseny: И ещё наследие Алексея Турбина:
https://ftp.altlinux.org/pub/people/at/
https://github.com/svpv