github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/geo/hilbert.go (about)

     1  // Copyright 2020 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package geo
    12  
    13  // hilbertInverse converts (x,y) to d on a Hilbert Curve.
    14  // Adapted from `xy2d` from https://en.wikipedia.org/wiki/Hilbert_curve#Applications_and_mapping_algorithms.
    15  func hilbertInverse(n, x, y uint64) uint64 {
    16  	var d uint64
    17  	for s := n / 2; s > 0; s /= 2 {
    18  		var rx uint64
    19  		if (x & s) > 0 {
    20  			rx = 1
    21  		}
    22  		var ry uint64
    23  		if (y & s) > 0 {
    24  			ry = 1
    25  		}
    26  		d += s * s * ((3 * rx) ^ ry)
    27  		x, y = hilbertRotate(n, x, y, rx, ry)
    28  	}
    29  	return d
    30  }
    31  
    32  // hilbertRotate rotates/flips a quadrant appropriately.
    33  // Adapted from `rot` in https://en.wikipedia.org/wiki/Hilbert_curve#Applications_and_mapping_algorithms.
    34  func hilbertRotate(n, x, y, rx, ry uint64) (uint64, uint64) {
    35  	if ry == 0 {
    36  		if rx == 1 {
    37  			x = n - 1 - x
    38  			y = n - 1 - y
    39  		}
    40  
    41  		x, y = y, x
    42  	}
    43  	return x, y
    44  }