Compare commits

..

No commits in common. "2496741ec7bd0220c1513b5c6400169cda2ed3fe" and "6190a676e79ef80a6276c0ca4e5b2a5333a6a1c9" have entirely different histories.

View file

@ -1,9 +1,11 @@
use std::{ use std::{
sync::{Arc, RwLock}, sync::{
atomic::{AtomicUsize, Ordering::Relaxed},
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,
@ -11,8 +13,8 @@ pub struct Point2d {
#[derive(Debug, Default, Clone, Copy)] #[derive(Debug, Default, Clone, Copy)]
pub struct PVal { pub struct PVal {
point_index: usize, pub point: usize,
val: f64, pub val: f64,
} }
impl PartialEq for PVal { impl PartialEq for PVal {
@ -39,25 +41,21 @@ impl Ord for PVal {
impl PVal { impl PVal {
pub fn new(point: usize, val: f64) -> Self { pub fn new(point: usize, val: f64) -> Self {
Self { Self { point, val }
point_index: point,
val,
}
} }
pub fn point_index(&self) -> usize { pub fn point_index(&self) -> usize {
self.point_index self.point
} }
pub fn val(&self) -> f64 { // pub fn val(&self) -> f64 {
self.val // f64::from_bits(self.val)
} // }
} }
#[derive(Debug, Default, Clone)]
pub struct Spindex2d { pub struct Spindex2d {
pub xpoints: Arc<RwLock<Vec<usize>>>, pub xpoints: Arc<Vec<AtomicUsize>>,
pub ypoints: Arc<RwLock<Vec<usize>>>, pub ypoints: Arc<Vec<AtomicUsize>>,
pub xs: Arc<RwLock<Vec<PVal>>>, pub xs: Arc<RwLock<Vec<PVal>>>,
pub ys: Arc<RwLock<Vec<PVal>>>, pub ys: Arc<RwLock<Vec<PVal>>>,
} }
@ -65,32 +63,28 @@ pub struct Spindex2d {
impl Spindex2d { impl Spindex2d {
pub fn new(points: &[Point2d]) -> Self { pub fn new(points: &[Point2d]) -> Self {
let mut xpoints = Vec::with_capacity(points.len()); let mut xpoints = Vec::with_capacity(points.len());
let mut xs = Vec::with_capacity(points.len());
let mut ypoints = Vec::with_capacity(points.len()); let mut ypoints = Vec::with_capacity(points.len());
let mut xs = Vec::with_capacity(points.len());
let mut ys = Vec::with_capacity(points.len()); let mut ys = Vec::with_capacity(points.len());
for (i, point) in points.iter().enumerate() {
let x = PVal {
point: i,
val: point.x,
};
xs.push(x);
let y = PVal {
point: i,
val: point.y,
};
ys.push(y);
thread::scope(|s| { xpoints.push(AtomicUsize::new(i));
s.spawn(|| { ypoints.push(AtomicUsize::new(i));
for (i, point) in points.iter().enumerate() { }
let x = PVal::new(i, point.x);
xs.push(x);
xpoints.push(i);
}
});
s.spawn(|| {
for (i, point) in points.iter().enumerate() {
let y = PVal::new(i, point.y);
ys.push(y);
ypoints.push(i);
}
});
});
let index = Self { let index = Self {
xpoints: Arc::new(RwLock::new(xpoints)), xpoints: xpoints.into(),
ypoints: Arc::new(RwLock::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)),
}; };
@ -104,30 +98,21 @@ impl Spindex2d {
/// when constructing this index. May panic if the updated points argument is longer than the /// when constructing this index. May panic if the updated points argument is longer than the
/// original points. /// original points.
pub fn update(&self, points: &[Point2d]) { pub fn update(&self, points: &[Point2d]) {
thread::scope(|s| { {
s.spawn(|| { let mut xs = self.xs.write().unwrap();
let mut xs = self.xs.write().unwrap(); let mut ys = self.ys.write().unwrap();
let xpoints = self.xpoints.read().unwrap(); for (i, point) in points.iter().enumerate() {
let xi = self.xpoints[i].load(Relaxed);
for (i, point) in points.iter().enumerate() { let yi = self.ypoints[i].load(Relaxed);
let xi = xpoints[i]; let x = point.x;
let x = PVal::new(i, point.x); let x = PVal { point: i, val: x };
xs[xi] = x; xs[xi] = x;
}
});
s.spawn(|| {
let mut ys = self.ys.write().unwrap();
let ypoints = self.ypoints.read().unwrap();
for (i, point) in points.iter().enumerate() {
let yi = ypoints[i];
let y = PVal::new(i, point.y);
ys[yi] = y;
}
});
});
let y = point.y;
let y = PVal { point: i, val: y };
ys[yi] = y;
}
}
self.sort(); self.sort();
} }
@ -137,10 +122,9 @@ impl Spindex2d {
let xhandle = thread::spawn(move || { let xhandle = thread::spawn(move || {
let mut xs = xs.write().unwrap(); let mut xs = xs.write().unwrap();
xs.sort_unstable(); xs.sort_unstable();
let mut points = points.write().unwrap();
for (i, x) in xs.iter().enumerate() { for (i, x) in xs.iter().enumerate() {
let p = x.point_index; let p = x.point;
points[p] = i; points[p].store(i, Relaxed);
} }
}); });
@ -149,10 +133,9 @@ 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();
let mut points = points.write().unwrap();
for (i, y) in ys.iter().enumerate() { for (i, y) in ys.iter().enumerate() {
let p = y.point_index; let p = y.point;
points[p] = i; points[p].store(i, Relaxed);
} }
}); });