Space-filling Curves
3.1 Space Filling Curves
3.2.1 Address calculations
The addresses minS(Q) and maxS(Q), which must not exist as actual points in the table, are formally defined as:
Definition 3.13 (minS(Q))
minS(Q) = min({S(~p )|~p ∈ Q}).
Definition 3.14 (maxS(Q))
maxS(Q) = max({S(~p )|~p ∈ Q}).
While they are easily defined as the minimum resp. maximum address of the points within a query shape we definitely cannot afford to calculate them by calculating the minimum resp. maximum address of all points within the query. The same holds for the N J I and N J O.
Formally we define the N J I and N J O conforming to [Mar99, Ram02] as:
Definition 3.15 (Next Jump In, N J I(~q, Q), nji)
The next jump in w.r. to a given point ~c and a query Q is defined as N J I(~c, Q) = min({S(~n )|~n ∈ Q ∧ S(~c ) < S(~n )} for minS(Q) ≤ S(~c ) ≤ maxS(Q). Definition 3.16 (Next Jump Out, N J O(~q, Q), njo)
The next jump out w.r. to a given point ~p and a query Q is defined as N J O(~p, Q) = min({S(~q )|~q ∈ Q ∧ S−1(S(~q ) + 1) 6∈ Q} for ~p ∈ Q ∧ minS(Q) ≤ S(~p ) ≤ maxS(Q) While we are using a point ~c as input here, we may also use an address where appro-priate, i.e., when working just with addresses during query processing we can avoid calls to S and/or S−1. The NJI-algorithm returns a point greater than the input point, i.e., S(~c ) < N J I(~c, Q) ≤ maxs(Q). The NJO-algorithm may also return the point itself, i.e., S(~c ) ≤ N J O(~c, Q) ≤ maxs(Q).
In the following we will examine the algorithms and their cost for the calculation of addresses for different SFCs and a range query Q = [~l, ~u ].
3.2.1.1 Compound-curve and Snake-curve
The compound curve is dimension order preserving according to Definition 3.6 on page 31 and thus we can obtain the minimum resp. maximum address within the query shape as minS = S(~l) resp. maxS = S(~u ).
The compound curve can be seen as a tree of height d with branching degree of |Di| on level i. The N J I and N J O can be calculated in linear time w.r. to the number of dimensions. The calculations described here operate on dimension values, but as the address gets constructed by concatenating them we can easily adapt them to also work on addresses.
The N J I is calculated by, scanning from the start of the address to its end, we search for the last dimension which can still be incremented, i.e., its value qi is within [li, ui− 1].
We then increment this value and set all remaining ones to their minimum w.r. to the query, i.e., qj := lj.
This algorithm requires to scan the address once. [Ram02] presents a similar algorithm called skipper and analyses its performance.
It should be noted that practically all implementations of B-Trees supporting compound keys do not utilize the decomposition into smaller sub-intervals, but they simply fetch the whole range
[SF CM in(Q), SF CM ax(Q)] (3.9)
and apply post filtering to the results (see Figure 2.7(b) on page 27). This stems from the fact that the original B-Tree range query has been designed for single interval queries, but not for a set of simultaneous interval queries.
The N J O can be calculated for an input which is a nji as follows. Starting with the last dimension in the address it is set to its maximum, i.e., q1 := u1. If qi covers the whole dimension or there is no restriction on dimension i, we continue with the preceding dimension otherwise or if no dimension is left we stop.
For the snake scan the N J I and N J O calculations are performed in a similar way taking into account that we are reversing the direction with every even dimension value. Thus instead of setting dimension values always to li resp. ui in the N J I and N J O calculation we set it to their ui resp. li for even dimension values. In case of the N J I we also have to decrement instead of incrementing for even dimension values and thus additionally have to search for the last position where a decrement is allowed.
3.2.1.2 Fractal Curves
For dimension order preserving fractal curve the minimum and maximum addresses within the query shape are minS = S(~l) and maxS = S(~u ). This is true for the Z-curve, but not for the Gray-Code-curve and Hilbert-curve, since a higher dimension value does not guarantee a higher address. Furthermore, these points may not be located at the corners of the range query but somewhere else on its outline.
dimension 2
dimension 1
(a)
dimension 2
dimension 1
(b)
dimension 2
dimension 1
(c)
Figure 3.9: Brother-father-search with Z-curve
In order to find minS resp. maxS we have to descend the tree representation starting at its root along the path with the lowest resp. highest sub-cube number intersecting the range query. The tree is actually nowhere stored, but Z-addresses represent an encoded version of the tree and can be used for this traversal. Starting with the origin ~p = (0, · · · , 0), the sub-cube coordinates p1, · · · , pd can be calculated by pi =Ps
j=12s−j · b(i, qj), where b(i, qj) is 1 if the bit of dimension i is set in the sub-cube number qj. This is done iteratively while descending the tree. The decision for the path of the further descend is controlled by the sub-cube numbers specific to the used curve. These sub-cube numbers can be obtained from the calculation of S().
Thus s iterations are required, where s is the height of the tree, and 2d coordinate calculations and comparisons on each level leading to complexity of O(s · 2d).
A generic algorithm to calculate the N J I resp. N J O for all fractal curves is a brother/
father search in the underlying quad-tree in the order of the curve. The term brother refers to sub-cubes on the same level within tree node, while father refers to the node pointing to the current node.
Search for the next older bother intersecting the query shape starts at the leaf level of the tree where the starting point of the search is located. Older brothers are those with higher sub-cube numbers. If there is no match one goes to the father and search all older brothers w.r. to the father level. This continues until finding a match or no older brothers resp. fathers are left.
Instead of traversing the tree, which is never materialized, we again utilize the address representation α = q0.q1. · · · .qs−1 for traversal. Moving to the next older brother on level i is done by incrementing the sub-cube number of that level, i.e., α.qi = α.qi+ 1. If the sub-cube number has reached the maximum 2d− 1 we set it to 0 and increment the sub-cube number of the previous level (father level) qi−1+ 1.
[Bay96] proposed this algorithm for the Z-curve. The number of brothers to test for intersection is 2d− 1 on each level in worst case and we have to test on s levels in worst case, thus we have an exponential complexity with respect to the number of dimensions of
O(s · (2d−1)). Furthermore, the intersection test has to be performed on the coordinates in Ω and thus we have to calculate these coordinates from the addresses. In case of the Z-curve the comparison can be reduced to one per dimension, by comparing with the partitioning value w.r. to the dimension and thus get a linear complexity of O(s · d).
Working solely on addresses avoids comparisons of coordinates resulting in a significant performance gain as discussed in [Fri97, Mar99]. An algorithm developed by Volker Markl is presented and explained in detail in [Ram02]. It works by comparing the current Z-address with SZmin(Q) and SZmax(Q) detecting what dimensions fall below the queries lower bound l or exceed the queries upper bound u and thus know where to increment and correct the address in order to gain the nji or njo. [Ram02] presents detailed complexity discussions and also a N J O as they are used in the UB-Tree implementation. Furthermore, [Ram02] shows that these algorithms also work for other curves created by order-preserving bit-interleaving.
Also [TH81, Law00] present similar algorithms for the N J I calculation on the Z-curve.
The Hilbert-curve algorithms for the N J I calculation are all based on the tree traversal as described before but with different representations encoding the underlying tree. [Law00]
presents a N J I based on state-diagrams for the tree traversal. Recently [Tro03] provides a N J I algorithm based on addresses.
On the Gray-Code-curve there do not exist publications on the N J I and N J O algo-rithms, but as the tree traversal does not dependent on actual curve it can also be utilized here. In fact, the curve just determines the order in which sub-cubes are checked.
When tracking the orientation of the “U” in the Hilbert-curve and Gray-Code-curve we may also reduce the number of comparisons to one comparison per dimension by just comparing with the partitioning value w.r. to the dimension and thus getting a linear complexity of O(s · d). However, this requires additional book keeping of the orientations and corresponding data structures.