バージョンごとのドキュメント一覧

69.4. 実装 #

<title>Implementation</title>

This section covers implementation details and other tricks that are useful for implementers of <acronym>SP-GiST</acronym> operator classes to know. この節では、SP-GiSTの演算子クラスを実装する人にとって知っていると役に立つ、実装についての詳細とその他の秘訣について説明します。

69.4.1. SP-GiSTの制限 #

<title>SP-GiST Limits</title>

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コアはエラーを発生します。

69.4.2. ノードラベルのないSP-GiST #

<title>SP-GiST Without Node Labels</title>

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. ラベルのないノードを持つ内部タプルを処理するときに、choosespgAddNodeを返すのはエラーです。というのは、この場合、ノードの集合は固定されていると想定されるからです。

69.4.3. All-the-Same内部タプル #

<title><quote>All-the-Same</quote> Inner Tuples</title>

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の処理において、choosespgMatchNodeという結果は、新しい値は等価なノードのどれに割り当てられても良い、という意味に解釈されます。 コアのコードは入力されたnodeNの値を無視し、(ツリーの平衡を保つために)ノードの1つにランダムに降りていきます。 choosespgAddNodeを返すのはエラーです。というのは、そうするとすべてのノードが等価ではなくなるからです。 挿入する値が既存のノードとマッチしない時は、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関数が、通常、ノードの意味についてどの程度のことを仮定しているかに依存します。