Package com.yahoo.geo

Class ZCurve


  • public class ZCurve
    extends java.lang.Object
    Contains utility methods for a Z-curve (Morton-order) encoder and decoder.
    Author:
    gjoranv
    • Constructor Summary

      Constructors 
      Constructor Description
      ZCurve()  
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static int[] decode​(long z)
      Decode a z-value into the original two integers.
      static int[] decode_slow​(long z)
      Decode a z-value into the original two integers.
      static long encode​(int x, int y)
      Encode two 32 bit integers by bit-interleaving them into one 64 bit integer value.
      static long encode_slow​(int x, int y)
      Encode two integers by bit-interleaving them into one Long value.
      static java.lang.String toFullBinaryString​(long l)
      Debugging utility that returns a long value as binary string including the leading zeroes.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • ZCurve

        public ZCurve()
    • Method Detail

      • encode

        public static long encode​(int x,
                                  int y)
        Encode two 32 bit integers by bit-interleaving them into one 64 bit integer value. The x-direction owns the least significant bit (bit 0). Both x and y can have negative values.

        This is a time-efficient implementation. In the first step, the input value is split in two blocks, one containing the most significant bits, and the other containing the least significant bits. The most significant block is then shifted left for as many bits it contains. For each following step every block from the previous step is split in the same manner, with a least and most significant block, and the most significant blocks are shifted left for as many bits they contain (half the number from the previous step). This continues until each block has only one bit.

        This algorithm works by placing the LSB of all blocks in the correct position after the bit-shifting is done in each step. This algorithm is quite similar to computing the Hamming Weight (or population count) of a bit string, see http://en.wikipedia.org/wiki/Hamming_weight.

        Efficiency considerations: The encoding operations in this method should require 42 cpu operations, of which many can be executed in parallell. Practical experiments show that one call takes ~15 ns on a 64-bit Intel Xeon processor @2.33GHz, or 35 cycles. This gives an efficiency gain of just ~17% due to the CPUs ability to process parallell instructions, compared to ~50% for the slow method. But still it is 5 times faster.

        Parameters:
        x - x value
        y - y value
        Returns:
        The bit-interleaved long containing x and y.
      • decode

        public static int[] decode​(long z)
        Decode a z-value into the original two integers. Returns an array of two Integers, x and y in indices 0 and 1 respectively.
        Parameters:
        z - The bit-interleaved long containing x and y.
        Returns:
        Array of two Integers, x and y.
      • encode_slow

        public static long encode_slow​(int x,
                                       int y)
        Encode two integers by bit-interleaving them into one Long value. The x-direction owns the least significant bit (bit 0). Both x and y can have negative values.
        Efficiency considerations: If Java compiles and runs this code as efficiently as would be the case with a good c-compiler, it should require 5 cpu operations per bit with optimal usage of the CPUs registers on a 64 bit processor(2 bit-shifts, 1 OR, 1 AND, and 1 conditional jump for the for-loop). This would correspond to 320+ cycles with no parallell execution. Practical experiments show that one call takes ~75 ns on a 64-bit Intel Xeon processor @2.33GHz, or 175 cycles. This gives an efficiency gain of ~50% due to the CPUs ability to perform several instructions in one clock-cycle. Here, it is probably the bit-shifts that can be done independently of the AND an OR operations, which must be done in sequence.
        Parameters:
        x - x value
        y - y value
        Returns:
        The bit-interleaved long containing x and y.
      • decode_slow

        public static int[] decode_slow​(long z)
        Decode a z-value into the original two integers. Returns an array of two Integers, x and y in indices 0 and 1 respectively.
        Parameters:
        z - The bit-interleaved long containing x and y.
        Returns:
        Array of two Integers, x and y.
      • toFullBinaryString

        public static java.lang.String toFullBinaryString​(long l)
        Debugging utility that returns a long value as binary string including the leading zeroes.