back to fast construction

This commit is contained in:
Joe 2025-10-17 16:06:25 -07:00
parent 9dc0c4b9aa
commit f0b5244a1c

View file

@ -1,26 +1,25 @@
use std::{ use std::{
sync::{ sync::{
atomic::{AtomicUsize, Ordering::Relaxed}, atomic::{AtomicU64, AtomicUsize, Ordering::Relaxed},
Arc, RwLock, Arc, RwLock,
}, },
thread, thread,
}; };
#[derive(Debug, Default, Clone, Copy, PartialEq, PartialOrd)]
pub struct Point2d { pub struct Point2d {
pub x: f64, pub x: f64,
pub y: f64, pub y: f64,
} }
#[derive(Debug, Default, Clone, Copy)] #[derive(Debug, Default)]
pub struct PVal { pub struct PVal {
point: usize, pub point: usize,
val: f64, pub val: AtomicU64,
} }
impl PartialEq for PVal { impl PartialEq for PVal {
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.val == other.val self.val.load(Relaxed) == other.val.load(Relaxed)
} }
} }
@ -28,22 +27,23 @@ impl Eq for PVal {}
impl PartialOrd for PVal { impl PartialOrd for PVal {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other)) let a = f64::from_bits(self.val.load(Relaxed));
let b = f64::from_bits(other.val.load(Relaxed));
a.partial_cmp(&b)
} }
} }
impl Ord for PVal { impl Ord for PVal {
fn cmp(&self, other: &Self) -> std::cmp::Ordering { fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.val.partial_cmp(&other.val).unwrap() self.partial_cmp(other).unwrap()
} }
} }
#[derive(Debug, Default, Clone)]
pub struct Spindex2d { pub struct Spindex2d {
xpoints: Arc<Vec<AtomicUsize>>, pub xpoints: Arc<Vec<AtomicUsize>>,
ypoints: Arc<Vec<AtomicUsize>>, pub ypoints: Arc<Vec<AtomicUsize>>,
xs: Arc<RwLock<Vec<PVal>>>, pub xs: Arc<RwLock<Vec<PVal>>>,
ys: Arc<RwLock<Vec<PVal>>>, pub ys: Arc<RwLock<Vec<PVal>>>,
} }
impl Spindex2d { impl Spindex2d {
@ -55,22 +55,22 @@ impl Spindex2d {
for (i, point) in points.iter().enumerate() { for (i, point) in points.iter().enumerate() {
let x = PVal { let x = PVal {
point: i, point: i,
val: point.x, val: AtomicU64::new(point.x.to_bits()),
}; };
xs.push(x); xs.push(x);
let y = PVal { let y = PVal {
point: i, point: i,
val: point.y, val: AtomicU64::new(point.y.to_bits()),
}; };
ys.push(y); ys.push(y);
xpoints.push(i.into()); xpoints.push(AtomicUsize::new(i));
ypoints.push(i.into()); ypoints.push(AtomicUsize::new(i));
} }
let index = Self { let index = Self {
xpoints: Arc::new(xpoints), xpoints: xpoints.into(),
ypoints: Arc::new(ypoints), ypoints: ypoints.into(),
xs: Arc::new(RwLock::new(xs)), xs: Arc::new(RwLock::new(xs)),
ys: Arc::new(RwLock::new(ys)), ys: Arc::new(RwLock::new(ys)),
}; };
@ -90,15 +90,17 @@ impl Spindex2d {
for (i, point) in points.iter().enumerate() { for (i, point) in points.iter().enumerate() {
let xi = self.xpoints[i].load(Relaxed); let xi = self.xpoints[i].load(Relaxed);
let yi = self.ypoints[i].load(Relaxed); let yi = self.ypoints[i].load(Relaxed);
let x = point.x.to_bits();
let x = PVal { let x = PVal {
point: i, point: i,
val: point.x, val: x.into(),
}; };
xs[xi] = x; xs[xi] = x;
let y = point.y.to_bits();
let y = PVal { let y = PVal {
point: i, point: i,
val: point.y, val: y.into(),
}; };
ys[yi] = y; ys[yi] = y;
} }
@ -123,7 +125,6 @@ impl Spindex2d {
let yhandle = thread::spawn(move || { let yhandle = thread::spawn(move || {
let mut ys = ys.write().unwrap(); let mut ys = ys.write().unwrap();
ys.sort_unstable(); ys.sort_unstable();
for (i, y) in ys.iter().enumerate() { for (i, y) in ys.iter().enumerate() {
let p = y.point; let p = y.point;
points[p].store(i, Relaxed); points[p].store(i, Relaxed);