66.4. Реализация#
66.4. Реализация #
Содержание этого раздела охватывает детали реализации и другие хитрости, которые полезны для разработчиков классов операторов SP-GiST для их знания.
66.4.1. Ограничения SP-GiST #
Все отдельные листовые кортежи и внутренние кортежи должны помещаться на одной странице индекса (по умолчанию 8 КБ). Поэтому, при индексировании значений переменной длины, длинные значения могут быть поддержаны только с помощью методов, таких как радиксные деревья, в которых каждый уровень дерева включает префикс, достаточно короткий для помещения на страницу, а конечный листовой уровень включает суффикс, также достаточно короткий для помещения на страницу. Класс оператора должен установить longValuesOK
в true только если он готов организовать это. В противном случае, ядро SP-GiST будет отклонять любой запрос на индексирование значения, которое слишком велико для помещения на страницу индекса.
Точно так же, ответственность класса оператора заключается в том, чтобы внутренние кортежи не становились слишком большими, чтобы поместиться на странице индекса; это ограничивает количество дочерних узлов, которые могут быть использованы в одном внутреннем кортеже, а также максимальный размер префиксного значения.
Ограничение заключается в том, что когда узел внутренней кортежа указывает на набор
листовых кортежей, все эти кортежи должны находиться на одной странице индекса.
(Это решение проектирования, которое позволяет сократить поиск и сэкономить место в
связях, связывающих такие кортежи вместе). Если набор листовых кортежей
становится слишком большим для страницы, выполняется разделение и вставляется промежуточный
внутренний кортеж. Чтобы решить эту проблему, новый внутренний
кортеж должен разделить набор значений листовых кортежей на несколько
групп узлов. Если функция picksplit
класса оператора
не справляется с этим, ядро SP-GiST прибегает к
необычным мерам, описанным в Раздел 66.4.3.
Когда longValuesOK
равно true, ожидается, что последующие уровни дерева SP-GiST будут поглощать все больше информации в префиксы и метки узлов внутренних кортежей, делая требуемые листовые данные все меньше и меньше, так что в конечном итоге они поместятся на странице.
Чтобы предотвратить ошибки в классах операторов, вызывающие бесконечные циклы вставки, ядро SP-GiST выдаст ошибку, если листовые данные не станут меньше в течение десяти циклов вызовов метода choose
.
66.4.2. SP-GiST без меток узлов #
Некоторые алгоритмы деревьев используют фиксированный набор узлов для каждой внутренней кортежа; например, в квадродереве всегда ровно четыре узла, соответствующих четырем квадрантам вокруг центроида внутреннего кортежа. В таком случае код обычно работает с узлами по их номерам, и нет необходимости в явных метках узлов. Чтобы подавить метки узлов (и тем самым сэкономить некоторое пространство), функция picksplit
может возвращать NULL для массива nodeLabels
, а также функция choose
может возвращать NULL для массива prefixNodeLabels
во время действия spgSplitTuple
. В результате этого nodeLabels
также будет NULL при последующих вызовах функций choose
и inner_consistent
. В принципе, метки узлов могут использоваться для некоторых внутренних кортежей и опускаться для других в том же индексе.
Когда работа с внутренним кортежем, содержащим неименованные узлы, функция choose
не должна возвращать spgAddNode
, так как в таких случаях множество узлов должно быть фиксированным.
66.4.3. “Все-одинаковые” Внутренние кортежи #
Ядро SP-GiST может переопределить результаты функции picksplit
класса оператора, когда функция picksplit
не может разделить предоставленные значения листьев на по крайней мере две категории узлов. Когда это происходит, новый внутренний кортеж создается с несколькими узлами, каждый из которых имеет ту же метку (если есть), которую picksplit
дал одному из узлов, и значения листьев случайным образом разделены между этими эквивалентными узлами. Флаг allTheSame
устанавливается во внутреннем кортеже, чтобы предупредить функции choose
и inner_consistent
, что кортеж не имеет набора узлов, которые они могли бы ожидать.
При работе с кортежем allTheSame
интерпретация результата функции choose
spgMatchNode
означает, что новое значение может быть присвоено любому из эквивалентных узлов; основной код будет игнорировать предоставленное значение nodeN
и спускаться в один из узлов случайным образом (чтобы сохранить сбалансированность дерева). Ошибка будет, если функция choose
вернет spgAddNode
, так как это сделает узлы неэквивалентными; действие spgSplitTuple
должно быть использовано, если значение для вставки не соответствует существующим узлам.
При работе с кортежем allTheSame
функция inner_consistent
должна возвращать либо все, либо ни один из узлов в качестве целей для продолжения поиска по индексу, так как они все эквивалентны. Это может или не может потребовать специального кода, в зависимости от того, насколько функция inner_consistent
обычно предполагает о смысле узлов.