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