diff --git a/articles/for-asvk/article/article_hbd.tex b/articles/for-asvk/article/article_hbd.tex index c16bc66..c42b6aa 100644 --- a/articles/for-asvk/article/article_hbd.tex +++ b/articles/for-asvk/article/article_hbd.tex @@ -184,7 +184,42 @@ B=\sum_{i=1}^{n}\ell_i \end{center} \end{table} -После сортировки получается массив $(255,280,460,711,758)$, а после вычисления разностей --- $(255,25,180,251,47)$. Для $n=5$ формула даёт $m=7$; полученный 43-битный поток преобразуется в payload \texttt{ZvpACXZy}. Параметрам $b=10$ и $m=7$ соответствуют заголовочные символы \texttt{d} и \texttt{a}, поэтому итоговая строка равна \texttt{set:daZvpACXZy}. Пример показывает, что строка содержит достаточно данных для восстановления упорядоченного множества усечённых хешей, но не исходных имён символов. +После сортировки получается массив $(255,280,460,711,758)$, а после вычисления разностей --- $(255,25,180,251,47)$. Для $n=5$ формула даёт $m=7$; полученный 43-битный поток преобразуется в payload \texttt{ZvpACXZy}. Параметрам $b=10$ и $m=7$ соответствуют заголовочные символы \texttt{d} и \texttt{a}, поэтому итоговая строка равна \texttt{set:daZvpACXZy}. + +\section{Построение \texttt{set:}-строк в \texttt{set.c}} +\label{CONSTRUCTION} + +Благодаря сценариям автозависимостей \texttt{rpm-build} утилита \texttt{mkset} получает символы из ELF-файлов и далее импользует \texttt{lib/set.c}, вызывая интерфейс построения множества: +\[ +\texttt{set\_new()}\ \longrightarrow\ +\texttt{set\_add()}\ \longrightarrow\ +\texttt{set\_fini()}. +\] + +Функция \texttt{set\_new()} создаёт пустую структуру \texttt{struct set}. В исходной реализации она представляет собой растущий массив пар «указатель на строку --- хеш». Функция \texttt{set\_add()} увеличивает ёмкость массива блоками по 1024 элемента и копирует каждое имя отдельным вызовом \texttt{xstrdup()}. На этом этапе хеши ещё не вычисляются, поэтому один объект можно финализировать с заданным значением \texttt{bpp}. + +Основную работу выполняет \texttt{set\_fini()}. Её действия следуют в фиксированном порядке: +\begin{enumerate} +\item проверяется непустота множества и условие $10\leq b\leq32$; +\item для каждого имени вычисляется Jenkins OAAT и применяется маска из $b$ младших бит; +\item массив пар сортируется стандартной функцией \texttt{qsort()} по хеш-значению; +\item для равных хешей различных имён выводится предупреждение о коллизии; +\item хеши копируются в числовой массив, а повторяющиеся значения удаляются; +\item массив кодируется последовательно как дельты, код Голомба--Райса и Base62; +\item сформированная строка копируется в динамическую память и возвращается вызывающей стороне. +\end{enumerate} + +Удаление повторов необходимо в двух случаях. Во-первых, одно имя может несколько раз попасть во входной поток. Во-вторых, различные имена могут совпасть после усечения хеша. Для семантики $H_b(S)$ оба случая означают один элемент множества. При этом предупреждение о коллизии формируется до удаления повторов, пока реализации ещё доступны исходные строки и можно различить совпадение имён от совпадения их хешей. + +Оценим вычислительную сложность. Пусть $L$ --- суммарная длина всех входных имён, $n$ --- их количество, а $B$ --- длина потока Голомба--Райса в битах. Хеширование требует $O(L)$ операций, сортировка --- $O(n\log n)$ сравнений, линейные проходы сортированного массива --- $O(n)$, кодирование --- $O(B)$. Поэтому для исходного варианта +\[ +T_{\mathrm{build}}=O(L)+O(n\log n)+O(B). +\] +Хранимые копии строк, массив пар, массив уникальных хешей, битовый буфер и результирующая строка дают дополнительную память порядка +\[ +M_{\mathrm{build}}=O(L+n+B). +\] +Главным асимптотическим слагаемым для больших наборов остаётся \texttt{qsort()}, тогда как большое число отдельных копирований строк и наличие промежуточного битового массива влияют на постоянные затраты. Это определяет два независимых направления дальнейшего улучшения: замена сортировки для крупных множеств и потоковое кодирование без промежуточных представлений. При этом любые изменения должны сохранять байтовую совместимость формата. \References \begin{enumerate}