Strengthen abstraction for node types
This commit is contained in:
parent
d80a2e3f67
commit
28f133a9f8
18
src/lib.rs
18
src/lib.rs
|
@ -301,11 +301,7 @@ where
|
||||||
// with `nearest` truncated to `M` elements.
|
// with `nearest` truncated to `M` elements.
|
||||||
if layer.0 > 0 {
|
if layer.0 > 0 {
|
||||||
let mut upper = Vec::with_capacity(zero.len());
|
let mut upper = Vec::with_capacity(zero.len());
|
||||||
upper.extend(zero.iter().map(|zero| {
|
upper.extend(zero.iter().map(UpperNode::from_zero));
|
||||||
let mut upper = UpperNode::default();
|
|
||||||
upper.nearest.copy_from_slice(&zero.nearest[..M]);
|
|
||||||
upper
|
|
||||||
}));
|
|
||||||
layers[layer.0 - 1] = upper;
|
layers[layer.0 - 1] = upper;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -416,7 +412,7 @@ fn insert<P: Point>(
|
||||||
|
|
||||||
let found =
|
let found =
|
||||||
insertion.select_heuristic(&layer, M * 2, candidate_point, points, *heuristic);
|
insertion.select_heuristic(&layer, M * 2, candidate_point, points, *heuristic);
|
||||||
for (i, slot) in layer[pid].nearest.iter_mut().enumerate() {
|
for (i, slot) in layer[pid].0.iter_mut().enumerate() {
|
||||||
if let Some(&Candidate { pid, .. }) = found.get(i) {
|
if let Some(&Candidate { pid, .. }) = found.get(i) {
|
||||||
*slot = pid;
|
*slot = pid;
|
||||||
} else if *slot != PointId::invalid() {
|
} else if *slot != PointId::invalid() {
|
||||||
|
@ -426,11 +422,11 @@ fn insert<P: Point>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layer[new].nearest[i] = pid;
|
layer[new].set(i, pid);
|
||||||
} else {
|
} else {
|
||||||
// Find the correct index to insert at to keep the neighbor's neighbors sorted
|
// Find the correct index to insert at to keep the neighbor's neighbors sorted
|
||||||
let old = &points[pid];
|
let old = &points[pid];
|
||||||
let nearest = &layer[pid].nearest;
|
let nearest = &layer[pid].0;
|
||||||
let idx = nearest
|
let idx = nearest
|
||||||
.binary_search_by(|third| {
|
.binary_search_by(|third| {
|
||||||
// `third` here is one of the neighbors of the new node's neighbor.
|
// `third` here is one of the neighbors of the new node's neighbor.
|
||||||
|
@ -447,18 +443,18 @@ fn insert<P: Point>(
|
||||||
// It might be possible for all the neighbor's current neighbors to be closer to our
|
// It might be possible for all the neighbor's current neighbors to be closer to our
|
||||||
// neighbor than to the new node, in which case we skip insertion of our new node's ID.
|
// neighbor than to the new node, in which case we skip insertion of our new node's ID.
|
||||||
if idx >= nearest.len() {
|
if idx >= nearest.len() {
|
||||||
layer[new].nearest[i] = pid;
|
layer[new].set(i, pid);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let nearest = &mut layer[pid].nearest;
|
let nearest = &mut layer[pid].0;
|
||||||
if nearest[idx].is_valid() {
|
if nearest[idx].is_valid() {
|
||||||
let end = (M * 2) - 1;
|
let end = (M * 2) - 1;
|
||||||
nearest.copy_within(idx..end, idx + 1);
|
nearest.copy_within(idx..end, idx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
nearest[idx] = new;
|
nearest[idx] = new;
|
||||||
layer[new].nearest[i] = pid;
|
layer[new].set(i, pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
32
src/types.rs
32
src/types.rs
|
@ -59,42 +59,44 @@ impl Visited {
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub(crate) struct UpperNode {
|
pub(crate) struct UpperNode([PointId; M]);
|
||||||
/// The nearest neighbors on this layer
|
|
||||||
///
|
impl UpperNode {
|
||||||
/// This is always kept in sorted order (near to far).
|
pub(crate) fn from_zero(node: &ZeroNode) -> Self {
|
||||||
pub(crate) nearest: [PointId; M],
|
let mut nearest = [PointId::invalid(); M];
|
||||||
|
nearest.copy_from_slice(&node.0[..M]);
|
||||||
|
Self(nearest)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layer for &Vec<UpperNode> {
|
impl Layer for &Vec<UpperNode> {
|
||||||
fn nearest_iter(&self, pid: PointId) -> NearestIter<'_> {
|
fn nearest_iter(&self, pid: PointId) -> NearestIter<'_> {
|
||||||
NearestIter {
|
NearestIter {
|
||||||
nearest: &self[pid.0 as usize].nearest,
|
nearest: &self[pid.0 as usize].0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub(crate) struct ZeroNode {
|
pub(crate) struct ZeroNode(pub(crate) [PointId; M * 2]);
|
||||||
/// The nearest neighbors on this layer
|
|
||||||
///
|
impl ZeroNode {
|
||||||
/// This is always kept in sorted order (near to far).
|
pub(crate) fn set(&mut self, idx: usize, pid: PointId) {
|
||||||
pub(crate) nearest: [PointId; M * 2],
|
self.0[idx] = pid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ZeroNode {
|
impl Default for ZeroNode {
|
||||||
fn default() -> ZeroNode {
|
fn default() -> ZeroNode {
|
||||||
ZeroNode {
|
ZeroNode([PointId::invalid(); M * 2])
|
||||||
nearest: [PointId::invalid(); M * 2],
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layer for &Vec<ZeroNode> {
|
impl Layer for &Vec<ZeroNode> {
|
||||||
fn nearest_iter(&self, pid: PointId) -> NearestIter<'_> {
|
fn nearest_iter(&self, pid: PointId) -> NearestIter<'_> {
|
||||||
NearestIter {
|
NearestIter {
|
||||||
nearest: &self[pid.0 as usize].nearest,
|
nearest: &self[pid.0 as usize].0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue