mod impls;
mod store;
pub use self::store::{NodeTemplate, Store};
use packed_simd::u16x16;
use std::hash::{Hash, Hasher};
const LEVEL_4_UPPER_HALF_MASK: u16x16 = u16x16::new(
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
);
const LEVEL_4_LOWER_HALF_MASK: u16x16 = u16x16::new(
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
0b1111_1111_1111_1111,
);
const LEVEL_4_NW_MASK: u16x16 = u16x16::new(
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
);
const LEVEL_4_NE_MASK: u16x16 = u16x16::new(
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
);
const LEVEL_4_SW_MASK: u16x16 = u16x16::new(
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
0b1111_1111_0000_0000,
);
const LEVEL_4_SE_MASK: u16x16 = u16x16::new(
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_0000_0000,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
0b0000_0000_1111_1111,
);
fn center(nw_grid: u16x16, ne_grid: u16x16, sw_grid: u16x16, se_grid: u16x16) -> u16x16 {
let nw_grid = nw_grid << 8;
let sw_grid = sw_grid << 8;
let left: u16x16 = shuffle!(
nw_grid,
sw_grid,
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
);
let ne_grid = ne_grid >> 8;
let se_grid = se_grid >> 8;
let right: u16x16 = shuffle!(
ne_grid,
se_grid,
[8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
);
left | right
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct Index(u32);
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Level(pub u8);
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum Quadrant {
Northwest,
Northeast,
Southwest,
Southeast,
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct NodeId {
index: Index,
}
#[derive(Clone, Copy, Debug)]
pub enum Node {
Leaf {
grid: u16x16,
},
Interior {
nw: NodeId,
ne: NodeId,
sw: NodeId,
se: NodeId,
level: Level,
population: u128,
},
}
impl PartialEq for Node {
fn eq(&self, other: &Node) -> bool {
match (self, other) {
(Node::Leaf { grid }, Node::Leaf { grid: other_grid }) => grid == other_grid,
(
Node::Interior { nw, ne, sw, se, .. },
Node::Interior {
nw: other_nw,
ne: other_ne,
sw: other_sw,
se: other_se,
..
},
) => nw == other_nw && ne == other_ne && sw == other_sw && se == other_se,
_ => false,
}
}
}
impl Eq for Node {}
impl Hash for Node {
fn hash<H>(&self, state: &mut H)
where
H: Hasher,
{
match self {
Node::Leaf { grid } => grid.hash(state),
Node::Interior { nw, ne, sw, se, .. } => {
nw.hash(state);
ne.hash(state);
sw.hash(state);
se.hash(state);
}
}
}
}
impl Node {
fn unwrap_leaf(&self) -> u16x16 {
match *self {
Node::Leaf { grid } => grid,
Node::Interior { .. } => panic!(),
}
}
}