WIP article for alt conf
This commit is contained in:
@@ -0,0 +1,90 @@
|
|||||||
|
# Исследование и улучшение механизма работы `set`-строк в ALT RPM
|
||||||
|
|
||||||
|
Ориентир на 700 слов, 9к символов
|
||||||
|
(!!!)/(???) - дополнить/уточнить
|
||||||
|
всё ещё куда-то надо включить "хэш клёвый, но медленный, вот тесты"
|
||||||
|
|
||||||
|
## 1. Зачем нужны set-строки
|
||||||
|
|
||||||
|
Обычная зависимость от версии библиотеки не гарантирует, что в ней остались все нужные программе символы: символ можно удалить, не сменив SONAME, а одинаковые SONAME могут скрывать разные наборы экспортов. Поэтому ALT RPM использует версии зависимостей вида `set:<encoded-set>`. Для `Provides` такая строка описывает символы, предоставляемые библиотекой, а для `Requires` - символы, которые конкретный потребитель требует от неё. В такой конфигурации сравниваются не номера версий, а включение множеств: все хэши символов из `Requires` должны присутствовать в `Provides`.
|
||||||
|
Гарантия вероятностная, поскольку вместо полноценных имён символов хранятся усечённые хэши, но ответ "символ отсутствует", когда он есть мы не получим
|
||||||
|
|
||||||
|
## 2. Структура set-строки
|
||||||
|
|
||||||
|
set-строка формируется следующим образом:
|
||||||
|
|
||||||
|
1. Список символов формируется автодепами `rpm-build`.
|
||||||
|
2. По количеству `Provides` символов вычисляется `bpp` (количество бит до которых обрезается хэш символа при формировании строки). (!!!)
|
||||||
|
3. Для каждого символа считается хэш-функция (используется Jenkins OAAT), хэш обрезается до `bpp` бит.
|
||||||
|
4. Массив хэшей сортируются, повторы удаляются.
|
||||||
|
5. Абсолютные значения заменяются дельтами между значениями
|
||||||
|
6. Для кодировки Golomb-Rice вычисляется параметр `Mshift`. (!!!) bpp - log2i(cnt) - 1
|
||||||
|
7. Массив дельт сжимаются кодировкой Golomb-Rice.
|
||||||
|
8. Битовый поток преобразуется в Base62-строку.
|
||||||
|
|
||||||
|
Примечание: при формировании set-строки для `req` символов, `bpp` вычисляется по количеству `prov` символов в актуальной (???) версии библиотеки для избежания сильного усечения хэшей при небольшом количестве требуемых символов.
|
||||||
|
|
||||||
|
Итоговая строка выглядит следующим образом:
|
||||||
|
|
||||||
|
```text
|
||||||
|
set:<bpp_char><Mshift_char><base62 строка>
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
bpp_char = bpp - 7 + 'a'
|
||||||
|
Mshift_char = Mshift - 7 + 'a'
|
||||||
|
```
|
||||||
|
|
||||||
|
Краткая схема:
|
||||||
|
|
||||||
|
```
|
||||||
|
массив строк
|
||||||
|
| (Jenkins OAAT)
|
||||||
|
v
|
||||||
|
массив усечённых хэшей
|
||||||
|
| (qsort)
|
||||||
|
v
|
||||||
|
отсортированный массив хэшей
|
||||||
|
| (вычисление разницы между элементами)
|
||||||
|
v
|
||||||
|
массив delta
|
||||||
|
| (Rice-Golomb преобразование)
|
||||||
|
v
|
||||||
|
битовый массив
|
||||||
|
| (base62 преобразование)
|
||||||
|
v
|
||||||
|
set-строка
|
||||||
|
```
|
||||||
|
|
||||||
|
### Механизм сравнения set-строк
|
||||||
|
|
||||||
|
Для проверки включения множества символов `req` в множество `prov` необходимо выполнить обратное декодирование следующим образом:
|
||||||
|
|
||||||
|
```
|
||||||
|
set-строка
|
||||||
|
| (обратное base62 преобразование)
|
||||||
|
v
|
||||||
|
битовый массив
|
||||||
|
| (обратное Rice-Golomb преобразование)
|
||||||
|
v
|
||||||
|
массив delta
|
||||||
|
| (вычисление изначальных значений)
|
||||||
|
v
|
||||||
|
массив усечённых хэшей (отсортированный)
|
||||||
|
```
|
||||||
|
|
||||||
|
Значения хэшей в массивах приводятся к минимальному `bpp` из двух set-строк (сохраняется отсортированность и дистинктивность(???)).
|
||||||
|
|
||||||
|
После получения отсортированных массивов хэшей из set-строк, включение символов (а точнее их усечённых хэш-значений) одного множества во второе проверить не составляет труда.
|
||||||
|
|
||||||
|
## 3. Практическая реализация
|
||||||
|
|
||||||
|
Несмотря на описанную структуру set-строки, на практике в текущем `lib/set.c` применяется множество оптимизаций и улучшений, направленных на ускорение работы `rpmsetcmp(const char *set1, const char *set2)` (функции, выдающей результат включения множеств). Рассмотрим основные из них.
|
||||||
|
|
||||||
|
### 3.1. Слитый декодер
|
||||||
|
|
||||||
|
### 3.2. Кэширование `Provides` set-строк
|
||||||
|
|
||||||
|
### 3.3. Быстрое сравнение включения множеств символов
|
||||||
|
|
||||||
|
## 4. Дальнейшие оптимизации
|
||||||
Reference in New Issue
Block a user