nodedb_array/coord/
encode.rs1use super::{hilbert, normalize, zorder};
12use crate::error::ArrayResult;
13use crate::schema::ArraySchema;
14use crate::schema::cell_order::{CellOrder, TileOrder};
15use crate::types::coord::value::CoordValue;
16
17pub fn encode_hilbert_prefix(schema: &ArraySchema, coord: &[CoordValue]) -> ArrayResult<u64> {
20 let bits = normalize::bits_per_dim(schema.arity());
21 let normalized = normalize::normalize_coord(schema, coord, bits)?;
22 hilbert::encode(&normalized, bits)
23}
24
25pub fn encode_zorder_prefix(schema: &ArraySchema, coord: &[CoordValue]) -> ArrayResult<u64> {
27 let bits = normalize::bits_per_dim(schema.arity());
28 let normalized = normalize::normalize_coord(schema, coord, bits)?;
29 zorder::encode(&normalized, bits)
30}
31
32pub fn encode_cell_prefix(schema: &ArraySchema, coord: &[CoordValue]) -> ArrayResult<u64> {
34 match schema.cell_order {
35 CellOrder::Hilbert | CellOrder::RowMajor | CellOrder::ColMajor => {
36 encode_hilbert_prefix(schema, coord)
37 }
38 CellOrder::ZOrder => encode_zorder_prefix(schema, coord),
39 }
40}
41
42pub fn encode_tile_prefix_with_order(
44 schema: &ArraySchema,
45 tile_indices: &[u64],
46 bits: u32,
47) -> ArrayResult<u64> {
48 match schema.tile_order {
49 TileOrder::Hilbert | TileOrder::RowMajor | TileOrder::ColMajor => {
50 hilbert::encode(tile_indices, bits)
51 }
52 TileOrder::ZOrder => zorder::encode(tile_indices, bits),
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use crate::schema::ArraySchemaBuilder;
60 use crate::schema::attr_spec::{AttrSpec, AttrType};
61 use crate::schema::dim_spec::{DimSpec, DimType};
62 use crate::types::domain::{Domain, DomainBound};
63
64 fn schema() -> ArraySchema {
65 ArraySchemaBuilder::new("g")
66 .dim(DimSpec::new(
67 "x",
68 DimType::Int64,
69 Domain::new(DomainBound::Int64(0), DomainBound::Int64(31)),
70 ))
71 .dim(DimSpec::new(
72 "y",
73 DimType::Int64,
74 Domain::new(DomainBound::Int64(0), DomainBound::Int64(31)),
75 ))
76 .attr(AttrSpec::new("v", AttrType::Int64, false))
77 .tile_extents(vec![8, 8])
78 .build()
79 .unwrap()
80 }
81
82 #[test]
83 fn hilbert_prefix_distinct_for_distinct_cells() {
84 let s = schema();
85 let a = encode_hilbert_prefix(&s, &[CoordValue::Int64(0), CoordValue::Int64(0)]).unwrap();
86 let b = encode_hilbert_prefix(&s, &[CoordValue::Int64(31), CoordValue::Int64(31)]).unwrap();
87 assert_ne!(a, b);
88 }
89
90 #[test]
91 fn zorder_prefix_distinct_for_distinct_cells() {
92 let s = schema();
93 let a = encode_zorder_prefix(&s, &[CoordValue::Int64(0), CoordValue::Int64(0)]).unwrap();
94 let b = encode_zorder_prefix(&s, &[CoordValue::Int64(31), CoordValue::Int64(31)]).unwrap();
95 assert_ne!(a, b);
96 }
97
98 #[test]
99 fn cell_prefix_dispatches_on_order() {
100 let s = schema();
101 let p = encode_cell_prefix(&s, &[CoordValue::Int64(7), CoordValue::Int64(13)]);
102 assert!(p.is_ok());
103 }
104}