Files
ARSV/articles/for-asvk/article/article_hbd.tex
T
2026-08-21 04:44:49 +03:00

120 lines
9.7 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
\Title{Гудов Д.О.}{Исследование алгоритма разрешения зависимостей в ALT RPM}
\section*{Введение}
Одной из задач пакетного менеджера является проверка совместимости устанавливаемого программного обеспечения с уже имеющимися или одновременно устанавливаемыми библиотеками. Традиционная зависимость от имени библиотеки и номера её версии не всегда достаточна: отдельный экспортируемый символ может быть удалён без изменения SONAME, а библиотеки с одинаковым SONAME могут предоставлять различные программные интерфейсы. В результате формально удовлетворённая зависимость от версии ещё не гарантирует, что динамический загрузчик найдёт все символы, необходимые программе.
В ALT RPM эта задача решается при помощи специальных версий зависимостей вида \texttt{set:<encoded-set>} [\Ref{SETC}]. Для отношения \texttt{Provides} такая строка описывает множество символов, экспортируемых библиотекой, а для отношения \texttt{Requires} --- символы, требуемые программой от конкретной библиотеки. При проверке зависимости обычное сравнение версий заменяется проверкой включения множеств. Полные имена символов при этом не сохраняются: они заменяются усечёнными хеш-значениями, сортируются и кодируются в компактную строку, допустимую как версия RPM.
Цель настоящей работы --- исследовать алгоритм построения и сравнения \texttt{set:}-строк, оценить вероятностные свойства хэша и вычислительную сложность алгоритма, а также определить направления оптимизации реализации.
%% В первых разделах формализуется решаемая задача, рассматриваются реальные данные репозитория Sisyphus, формат строки и путь её построения в исходной реализации \texttt{lib/set.c}.
\section{Постановка задачи и данные ALT Linux}
\label{PROBLEM}
Пусть $P$ --- множество символов, предоставляемых библиотекой, а $R$ --- множество символов, требуемых от неё программой. Обозначим $p=|P|$ и $r=|R|$. Зависимость выполнима тогда и только тогда, когда
\[
R\subseteq P.
\]
Списки символов формируются механизмом автоматического определения зависимостей \texttt{rpm-build}. Для \texttt{Provides} из динамической таблицы библиотеки выбираются доступные извне определённые символы. Для \texttt{Requires} утилита \texttt{ldd --bindings} устанавливает соответствие между требуемым символом и конкретной библиотекой-поставщиком; слабые неопределённые символы исключаются. Таким образом, одна строка \texttt{Requires} содержит только множество, связанное с данным поставщиком.
Явное хранение имён увеличивало бы RPM-метаданные пропорционально их суммарной длине. Поэтому используется усечённая хеш-функция c целым $b$, называемого в реализации \texttt{bpp},
\[
h_b(x)=h_{32}(x)\bmod 2^b,
\qquad
H_b(S)=\{h_b(x)\mid x\in S\},
\]
где $h_{32}$ --- 32-битная функция Jenkins one-at-a-time. Фактически \texttt{lib/set.c} проверяет условие
\[
H_b(R)\subseteq H_b(P).
\]
Такое представление сохраняет включение: из $R\subseteq P$ следует $H_b(R)\subseteq H_b(P)$. Следовательно, коллизия хешей не создаёт ложного отказа для корректной зависимости. Обратное утверждение неверно: отсутствующий символ из $R\setminus P$ может получить то же усечённое значение, что и один из символов $P$, и привести к ложному принятию зависимости. Тем самым предоставляемая гарантия имеет вероятностный характер.
Для оценки реальной нагрузки был исследован срез репозитория Sisyphus для архитектур \texttt{x86\_64} и \texttt{noarch}. Объём рассмотренных метаданных на момент 2026-08-20 приведён в табл.~\Ref{CORPUS}.
\begin{table}[H]
\begin{center}
\caption{\label{CORPUS}Объём исследованного среза Sisyphus}
\small
\begin{tabular}{|l|r|}
\hline
Объект & Количество \\
\hline
Пакеты & 47\,654 \\
\hline
Отношения \texttt{Provides} с \texttt{set:}-версией & 14\,859 \\
\hline
Отношения \texttt{Requires} с \texttt{set:}-версией & 69\,153 \\
\hline
Сопоставленные пары $P,R$ & 68\,492 \\
\hline
\end{tabular}
\end{center}
\end{table}
661 отношений удовлетворены обычным неверсионированным \texttt{Provides}.
Для каждой сопоставленной пары декодировались мощности множеств $p$ и $r$, а также вычислялось индивидуальное отношение $p/r$. Квантили этих величин показаны в табл.~\Ref{CARDINALITIES}. Квантили отношения вычислялись непосредственно по парам.
\begin{table}[H]
\begin{center}
\caption{\label{CARDINALITIES}Мощности множеств в парах \texttt{Provides}/\texttt{Requires}}
\small
\begin{tabular}{|c|r|r|r|}
\hline
Квантиль & $p$ & $r$ & $p/r$ \\
\hline
0,50 & 480 & 13 & 28,1 \\
\hline
0,75 & 1\,886 & 37 & 80 \\
\hline
0,90 & 6\,219 & 104 & 257 \\
\hline
\end{tabular}
\end{center}
\end{table}
В 92,4\% сопоставленных пар выполняется $p/r\geq 4$. Следовательно, типичный проверяемый набор требований существенно разрежен относительно множества предоставляемых символов. Это наблюдение важно для алгоритма сравнения: последовательный симметричный просмотр двух массивов не всегда использует характерное различие их мощностей.
\section{Устройство существующей \texttt{set:}-строки}
\label{FORMAT}
Построение \texttt{set:}-строки выполняется как последовательность преобразований
\[
\begin{aligned}
\text{имена символов}
&\longrightarrow \text{усечённые хеши}
\longrightarrow \text{сортировка},\\
&\longrightarrow \text{удаление повторов и вычисление дельт},\\
&\longrightarrow \text{код Голомба--Райса}
\longrightarrow \text{Base62-представление}.
\end{aligned}
\]
Итоговая версия имеет вид
\[
\texttt{set:}\langle b\rangle\langle m\rangle\langle payload\rangle.
\]
Префикс \texttt{set:} распознаётся RPM как признак специальной версии. Следующие два символа кодируют параметры $b=\texttt{bpp}$ и $m=\texttt{Mshift}$ по правилу $c=v-7+\texttt{'a'}$. Допустимы $10\leq b\leq32$, $7\leq m\leq31$ и $m<b$. Оставшаяся часть строки содержит закодированный в \texttt{Base62} битовый поток.
\subsection{Хеширование и вероятность коллизий}
Для каждого имени вычисляется 32-битный Jenkins one-at-a-time [\Ref{JENKINS}], после чего сохраняются только $b$ младших бит. Пусть $n$ различных имён независимо и равномерно отображаются в пространство из $N=2^b$ значений. Тогда математическое ожидание числа столкнувшихся пар равно
\References
\begin{enumerate}
\item
\Label{SETC}
Tourbin A.
\emph{set.c --- base62, Golomb and set-string routines}.
ALT RPM source code, 2010--2012.
[Электронный ресурс] URL: \url{https://git.altlinux.org/gears/r/rpm.git?a=blob;f=lib/set.c}.
\item
\Label{JENKINS}
\end{enumerate}