This section covers implementation details and other tricks that are useful for implementers of <acronym>SP-GiST</acronym> operator classes to know. この節では、SP-GiSTの演算子クラスを実装する人にとって知っていると役に立つ、実装についての詳細とその他の秘訣について説明します。
Individual leaf tuples and inner tuples must fit on a single index page
(8kB by default). Therefore, when indexing values of variable-length
data types, long values can only be supported by methods such as radix
trees, in which each level of the tree includes a prefix that is short
enough to fit on a page, and the final leaf level includes a suffix also
short enough to fit on a page. The operator class should set
<structfield>longValuesOK</structfield> to true only if it is prepared to arrange for
this to happen. Otherwise, the <acronym>SP-GiST</acronym> core will
reject any request to index a value that is too large to fit
on an index page.
それぞれのリーフタプルおよび内部タプルは1つのインデックスページ内(デフォルトで8kB)に収まらなければなりません。
従って、可変長のデータ型の値をインデックス付けするときは、長い値は基数木のようなメソッドによってのみサポートされます。つまり、ツリーのそれぞれのレベルではページに収まる短さの接頭辞を含み、最後のリーフレベルでは、やはりページに収まる短さの接尾辞を含む、というようなものです。
このようなことが発生する場合の対応の準備ができている場合のみ、演算子クラスはlongValuesOK
を真にセットするべきです。
そうでなければ、SP-GiSTのコアは、インデックスページに収めるには大きすぎる値についてのインデックス付け要求を拒絶します。
Likewise, it is the operator class's responsibility that inner tuples do not grow too large to fit on an index page; this limits the number of child nodes that can be used in one inner tuple, as well as the maximum size of a prefix value. 同様に、内部タプルが大きくなりすぎてインデックスページに収まらない、ということにならないようにするのは、演算子クラスの責任です。 これにより、1つの内部タプルで使うことができる子ノードの数、および接頭辞の値の最大サイズが制限されます。
Another limitation is that when an inner tuple's node points to a set
of leaf tuples, those tuples must all be in the same index page.
(This is a design decision to reduce seeking and save space in the
links that chain such tuples together.) If the set of leaf tuples
grows too large for a page, a split is performed and an intermediate
inner tuple is inserted. For this to fix the problem, the new inner
tuple <emphasis>must</emphasis> divide the set of leaf values into more than one
node group. If the operator class's <function>picksplit</function> function
fails to do that, the <acronym>SP-GiST</acronym> core resorts to
extraordinary measures described in <xref linkend="spgist-all-the-same"/>.
内部タプルのノードがリーフタプルの集合を指しているとき、それらのタプルはすべて同じインデックスページ内になければならない、という制限もあります。
(これは、シークの回数を減らし、そのようなタプルを一つにつなげるリンクに必要なスペースを減らす、という設計上の決定によるものです。)
リーフタプルの集合が大きくなって1ページに収まらなくなると、分割が実行され、中間の内部タプルが挿入されます。
これで問題を解決するためには、新しい内部タプルは、リーフの値の集合を2つ以上のノードのグループに分割しなければなりません。
演算子クラスのpicksplit
関数がそれをするのに失敗したときは、SP-GiSTのコアは、69.4.3に記述されている特別な手段に頼ることになります。
When <structfield>longValuesOK</structfield> is true, it is expected
that successive levels of the <acronym>SP-GiST</acronym> tree will
absorb more and more information into the prefixes and node labels of
the inner tuples, making the required leaf datum smaller and smaller,
so that eventually it will fit on a page.
To prevent bugs in operator classes from causing infinite insertion
loops, the <acronym>SP-GiST</acronym> core will raise an error if the
leaf datum does not become any smaller within ten cycles
of <function>choose</function> method calls.
longValuesOK
が真であれば、SP-GiSTツリーの後続のレベルは、より多くの情報を接頭辞と内部タプルのノードラベルへと吸収し、要求されるリーフデータより小さくして、最終的には1ページに収まるようになることが期待されます。
演算子クラスのバグが無限の挿入ループを引き起こすのを防ぐために、choose
メソッドの呼び出しの10サイクル以内でリーフデータが少しも小さくならなければ、SP-GiSTコアはエラーを発生します。
Some tree algorithms use a fixed set of nodes for each inner tuple;
for example, in a quad-tree there are always exactly four nodes
corresponding to the four quadrants around the inner tuple's centroid
point. In such a case the code typically works with the nodes by
number, and there is no need for explicit node labels. To suppress
node labels (and thereby save some space), the <function>picksplit</function>
function can return NULL for the <structfield>nodeLabels</structfield> array,
and likewise the <function>choose</function> function can return NULL for
the <structfield>prefixNodeLabels</structfield> array during
a <literal>spgSplitTuple</literal> action.
This will in turn result in <structfield>nodeLabels</structfield> being NULL during
subsequent calls to <function>choose</function> and <function>inner_consistent</function>.
In principle, node labels could be used for some inner tuples and omitted
for others in the same index.
木構造のアルゴリズムには、それぞれの内部タプルに対して固定された集合のノードを使うものがあります。
例えば四分木では、内部タプルの中心点の周りの4つの象限に対応するちょうど4つのノードが必ずあります。
このような場合、コードは典型的には数字を使ったノードで動作し、明示的なノードラベルは必要ありません。
ノードラベルを使わない(そしてそれによりいくらかのスペースを節約する)ために、picksplit
関数はnodeLabels
配列としてNULLを返すことができ、同様にchoose
関数はspgSplitTuple
アクションの間prefixNodeLabels
配列としてNULLを返すことができます。
この結果、その後のchoose
関数およびinner_consistent
関数の呼び出しにおいてもnodeLabels
はNULLになります。
原則として、ノードラベルは同じインデックス中の一部の内部タプルに使い、他の内部タプルには省略する、ということができます。
When working with an inner tuple having unlabeled nodes, it is an error
for <function>choose</function> to return <literal>spgAddNode</literal>, since the set
of nodes is supposed to be fixed in such cases.
ラベルのないノードを持つ内部タプルを処理するときに、choose
がspgAddNode
を返すのはエラーです。というのは、この場合、ノードの集合は固定されていると想定されるからです。
The <acronym>SP-GiST</acronym> core can override the results of the
operator class's <function>picksplit</function> function when
<function>picksplit</function> fails to divide the supplied leaf values into
at least two node categories. When this happens, the new inner tuple
is created with multiple nodes that each have the same label (if any)
that <function>picksplit</function> gave to the one node it did use, and the
leaf values are divided at random among these equivalent nodes.
The <literal>allTheSame</literal> flag is set on the inner tuple to warn the
<function>choose</function> and <function>inner_consistent</function> functions that the
tuple does not have the node set that they might otherwise expect.
picksplit
が入力のリーフ値を少なくとも2つのノード分類に分割できなかった場合、SP-GiSTのコアは演算子クラスのpicksplit
関数の結果を無効にすることがあります。
これが起きると、複数のノードを持つ新しい内部タプルが作成されます。それぞれのノードは、picksplit
が一つのノードに付与したもの(あれば)と同じラベルを持ち、リーフ値はこれらの等価なノード間でランダムに分割されます。
内部タプルにはallTheSame
のフラグがセットされ、choose
関数およびinner_consistent
関数に対し、そのタプルが通常期待されるようなノードの集合を持っていないことを警告します。
When dealing with an <literal>allTheSame</literal> tuple, a <function>choose</function>
result of <literal>spgMatchNode</literal> is interpreted to mean that the new
value can be assigned to any of the equivalent nodes; the core code will
ignore the supplied <structfield>nodeN</structfield> value and descend into one
of the nodes at random (so as to keep the tree balanced). It is an
error for <function>choose</function> to return <literal>spgAddNode</literal>, since
that would make the nodes not all equivalent; the
<literal>spgSplitTuple</literal> action must be used if the value to be inserted
doesn't match the existing nodes.
allTheSame
の処理において、choose
のspgMatchNode
という結果は、新しい値は等価なノードのどれに割り当てられても良い、という意味に解釈されます。
コアのコードは入力されたnodeN
の値を無視し、(ツリーの平衡を保つために)ノードの1つにランダムに降りていきます。
choose
がspgAddNode
を返すのはエラーです。というのは、そうするとすべてのノードが等価ではなくなるからです。
挿入する値が既存のノードとマッチしない時は、spgSplitTuple
のアクションを使わなければなりません。
When dealing with an <literal>allTheSame</literal> tuple, the
<function>inner_consistent</function> function should return either all or none
of the nodes as targets for continuing the index search, since they are
all equivalent. This may or may not require any special-case code,
depending on how much the <function>inner_consistent</function> function normally
assumes about the meaning of the nodes.
allTheSame
のタプルの処理において、すべてのノードは等価なので、inner_consistent
関数は、インデックス検索を続けるためのターゲットとして、すべてのノードを返すか、ノードを1つも返さないかのいずれかであるべきです。
このために、特殊ケースを扱うコードが必要になるかもしれませんし、必要ないかもしれません。それは、inner_consistent
関数が、通常、ノードの意味についてどの程度のことを仮定しているかに依存します。