Removing memory allocations

This commit is contained in:
2019-10-18 20:56:10 +02:00
parent 6fc2cc5942
commit 7a0fbc612f
10 changed files with 67 additions and 45 deletions

View File

@@ -12,7 +12,7 @@ pub struct CoreQueryParameters<'a> {
pub output_space: Option<&'a str>, pub output_space: Option<&'a str>,
pub threshold_volume: Option<f64>, pub threshold_volume: Option<f64>,
pub view_port: &'a Option<(Vec<f64>, Vec<f64>)>, pub view_port: &'a Option<(Vec<f64>, Vec<f64>)>,
pub resolution: Option<Vec<u32>>, pub resolution: &'a Option<Vec<u32>>,
} }
impl CoreQueryParameters<'_> { impl CoreQueryParameters<'_> {

View File

@@ -178,10 +178,7 @@ impl DataBase {
} }
// Lookup a space within the reference spaces registered // Lookup a space within the reference spaces registered
pub fn space<S>(&self, name: S) -> Result<&Space, String> pub fn space(&self, name: &str) -> Result<&Space, String> {
where
S: Into<String>,
{
let name = name.into(); let name = name.into();
if &name == space::Space::universe().name() { if &name == space::Space::universe().name() {
Ok(space::Space::universe()) Ok(space::Space::universe())
@@ -198,10 +195,7 @@ impl DataBase {
} }
// Lookup a dataset within the datasets registered // Lookup a dataset within the datasets registered
pub fn core<S>(&self, name: S) -> Result<&Core, String> pub fn core(&self, name: &str) -> Result<&Core, String> {
where
S: Into<String>,
{
let name = name.into(); let name = name.into();
let r = self.cores.find(&name); let r = self.cores.find(&name);

View File

@@ -188,7 +188,7 @@ impl Axis {
// Apply Unit scaling // Apply Unit scaling
let d = d * self.measurement_unit.factor(); let d = d * self.measurement_unit.factor();
Ok(self.unit_vector.clone() * d) Ok(&self.unit_vector * d)
} }
// Value is expressed on the current Axis, not in absolute coordinates! // Value is expressed on the current Axis, not in absolute coordinates!

View File

@@ -5,7 +5,7 @@ use super::MAX_K;
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub enum CoordinateSystem { pub enum CoordinateSystem {
Universe, Universe { origin: Position },
// Coordinates in Universe, expressed in f64, and in the Universe number of dimensions. // Coordinates in Universe, expressed in f64, and in the Universe number of dimensions.
AffineSystem { origin: Position, axes: Vec<Axis> }, AffineSystem { origin: Position, axes: Vec<Axis> },
} }
@@ -18,19 +18,16 @@ impl CoordinateSystem {
} }
} }
pub fn origin(&self) -> Position { pub fn origin(&self) -> &Position {
match self { match self {
CoordinateSystem::Universe => { CoordinateSystem::Universe { origin, .. } => origin,
let origin = [0f64; MAX_K].to_vec(); CoordinateSystem::AffineSystem { origin, .. } => origin,
origin.into()
}
CoordinateSystem::AffineSystem { origin, .. } => origin.clone(),
} }
} }
pub fn axes(&self) -> Vec<Axis> { pub fn axes(&self) -> Vec<Axis> {
match self { match self {
CoordinateSystem::Universe => { CoordinateSystem::Universe { .. } => {
//FIXME: Generate a CoordinateSystem on the fly or store it as part of the Universe Space? //FIXME: Generate a CoordinateSystem on the fly or store it as part of the Universe Space?
unimplemented!() unimplemented!()
} }
@@ -40,7 +37,7 @@ impl CoordinateSystem {
pub fn dimensions(&self) -> usize { pub fn dimensions(&self) -> usize {
match self { match self {
CoordinateSystem::Universe => MAX_K, CoordinateSystem::Universe { .. } => MAX_K,
CoordinateSystem::AffineSystem { axes, .. } => axes.len(), CoordinateSystem::AffineSystem { axes, .. } => axes.len(),
} }
} }
@@ -50,10 +47,10 @@ impl CoordinateSystem {
let mut high = Vec::with_capacity(self.dimensions()); let mut high = Vec::with_capacity(self.dimensions());
match self { match self {
CoordinateSystem::Universe => { CoordinateSystem::Universe { .. } => {
for _ in 0..self.dimensions() { for _ in 0..self.dimensions() {
low.push(std::f64::MAX); low.push(std::f64::MIN);
high.push(std::f64::MIN); high.push(std::f64::MAX);
} }
} }
CoordinateSystem::AffineSystem { axes, .. } => { CoordinateSystem::AffineSystem { axes, .. } => {
@@ -84,16 +81,16 @@ impl CoordinateSystem {
// return a position in the current coordinate system. // return a position in the current coordinate system.
pub fn rebase(&self, position: &Position) -> Result<Position, String> { pub fn rebase(&self, position: &Position) -> Result<Position, String> {
match self { match self {
CoordinateSystem::Universe => { CoordinateSystem::Universe { origin } => {
// Ensure the coordinates are encoded into F64 variants of // Ensure the coordinates are encoded into F64 variants of
// coordinates by forcing an addition to the origin position // coordinates by forcing an addition to the origin position
// which is expressed as F64 variants. The addition will convert // which is expressed as F64 variants. The addition will convert
// to F64 automatically. // to F64 automatically.
Ok(self.origin().clone() + position.clone()) Ok(origin + position)
} }
CoordinateSystem::AffineSystem { origin, axes } => { CoordinateSystem::AffineSystem { origin, axes } => {
let dimensions = axes.len(); let dimensions = axes.len();
let translated = position.clone() - origin.clone(); let translated = position - origin;
let mut rebased = Vec::with_capacity(dimensions); let mut rebased = Vec::with_capacity(dimensions);
for a in axes.iter().take(dimensions) { for a in axes.iter().take(dimensions) {
@@ -110,16 +107,16 @@ impl CoordinateSystem {
// return a position in Universe coordinates. // return a position in Universe coordinates.
pub fn absolute_position(&self, position: &Position) -> Result<Position, String> { pub fn absolute_position(&self, position: &Position) -> Result<Position, String> {
match self { match self {
CoordinateSystem::Universe => { CoordinateSystem::Universe { origin } => {
// Ensure the coordinates are encoded into F64 variants of // Ensure the coordinates are encoded into F64 variants of
// coordinates by forcing an addition to the origin position // coordinates by forcing an addition to the origin position
// which is expressed as F64 variants. The addition will convert // which is expressed as F64 variants. The addition will convert
// to F64 automatically. // to F64 automatically.
Ok(self.origin().clone() + position.clone()) Ok(origin + position)
} }
CoordinateSystem::AffineSystem { axes, .. } => { CoordinateSystem::AffineSystem { axes, .. } => {
// Start from the base origin. // Start from the base origin.
let mut rebased = self.origin(); let mut rebased = self.origin().clone();
// Convert to Universe coordinates // Convert to Universe coordinates
for k in 0..axes.len() { for k in 0..axes.len() {
@@ -138,7 +135,7 @@ impl CoordinateSystem {
let mut encoded = vec![]; let mut encoded = vec![];
match self { match self {
CoordinateSystem::Universe => { CoordinateSystem::Universe { .. } => {
assert_eq!(position.len(), MAX_K); assert_eq!(position.len(), MAX_K);
for c in position { for c in position {
encoded.push(Coordinate::CoordinateF64(*c)); encoded.push(Coordinate::CoordinateF64(*c));
@@ -161,7 +158,7 @@ impl CoordinateSystem {
let mut decoded = vec![]; let mut decoded = vec![];
match self { match self {
CoordinateSystem::Universe => { CoordinateSystem::Universe { .. } => {
assert_eq!(position.dimensions(), MAX_K); assert_eq!(position.dimensions(), MAX_K);
for c in 0..position.dimensions() { for c in 0..position.dimensions() {
decoded.push(position[c].into()); decoded.push(position[c].into());

View File

@@ -20,7 +20,9 @@ pub const MAX_K: usize = 3;
lazy_static! { lazy_static! {
static ref UNIVERSE: Space = Space { static ref UNIVERSE: Space = Space {
name: "Universe".into(), name: "Universe".into(),
system: CoordinateSystem::Universe, system: CoordinateSystem::Universe {
origin: [0f64; MAX_K].to_vec().into()
},
}; };
} }
@@ -53,7 +55,7 @@ impl Space {
&self.name &self.name
} }
pub fn origin(&self) -> Position { pub fn origin(&self) -> &Position {
self.system.origin() self.system.origin()
} }

View File

@@ -67,19 +67,17 @@ impl Position {
// Unit / Normalized vector from self. // Unit / Normalized vector from self.
pub fn unit(&self) -> Self { pub fn unit(&self) -> Self {
self.clone() * (1f64 / self.norm()) self * (1f64 / self.norm())
} }
// This multiplies self^T with other, producing a scalar value // This multiplies self^T with other, producing a scalar value
pub fn dot_product(&self, other: &Self) -> f64 { pub fn dot_product(&self, other: &Self) -> f64 {
assert_eq!(self.dimensions(), other.dimensions()); assert_eq!(self.dimensions(), other.dimensions());
let point = self.clone();
let other = other.clone();
let mut product = 0f64; let mut product = 0f64;
for k in 0..self.dimensions() { for k in 0..self.dimensions() {
product += (point[k] * other[k]).f64(); product += (self[k] * other[k]).f64();
} }
product product
@@ -190,6 +188,22 @@ impl Add for Position {
} }
} }
impl Add for &Position {
type Output = Position;
fn add(self, rhs: Self) -> Self::Output {
let dimensions = self.dimensions();
assert_eq!(dimensions, rhs.dimensions());
let mut v = Vec::with_capacity(dimensions);
for k in 0..dimensions {
v.push(self[k] + rhs[k]);
}
v.into()
}
}
impl AddAssign for Position { impl AddAssign for Position {
fn add_assign(&mut self, rhs: Self) { fn add_assign(&mut self, rhs: Self) {
let dimensions = self.dimensions(); let dimensions = self.dimensions();
@@ -247,6 +261,21 @@ impl Mul<f64> for Position {
} }
} }
impl Mul<f64> for &Position {
type Output = Position;
fn mul(self, rhs: f64) -> Self::Output {
let dimensions = self.dimensions();
let mut v = Vec::with_capacity(dimensions);
for k in 0..dimensions {
v.push(self[k] * rhs);
}
v.into()
}
}
// Scalar product // Scalar product
impl MulAssign<f64> for Position { impl MulAssign<f64> for Position {
fn mul_assign(&mut self, rhs: f64) { fn mul_assign(&mut self, rhs: f64) {

View File

@@ -78,8 +78,8 @@ impl Shape {
for _ in 0..dimensions { for _ in 0..dimensions {
vr.push(*radius); vr.push(*radius);
} }
let vr: Position = vr.into(); let vr: &Position = &vr.into();
(center.clone() - vr.clone(), center.clone() + vr) (center - vr, center + vr)
} }
Shape::BoundingBox(lower, higher) => (lower.clone(), higher.clone()), Shape::BoundingBox(lower, higher) => (lower.clone(), higher.clone()),
} }
@@ -188,7 +188,7 @@ impl Shape {
let positions = Shape::gen(&lower, &higher) let positions = Shape::gen(&lower, &higher)
.into_iter() .into_iter()
.filter(|p| (p.clone() - center.clone()).norm() <= radius) .filter(|p| (p - center).norm() <= radius)
.collect(); .collect();
Ok(positions) Ok(positions)

View File

@@ -215,7 +215,7 @@ impl SpaceIndex {
let results = self let results = self
.find_range(&lower, &higher) .find_range(&lower, &higher)
.into_iter() .into_iter()
.filter(|p| (p.position().clone() - center.clone()).norm() <= radius.f64()) .filter(|p| (p.position() - center).norm() <= radius.f64())
.collect(); .collect();
Ok(results) Ok(results)

View File

@@ -110,7 +110,7 @@ impl From<&space::Space> for Space {
Space { Space {
name: space.name().clone(), name: space.name().clone(),
origin: space.origin().into(), origin: space.origin().clone().into(),
axes, axes,
} }
} }

View File

@@ -41,7 +41,7 @@ fn main() {
output_space: None, output_space: None,
threshold_volume: Some(std::f64::MAX), threshold_volume: Some(std::f64::MAX),
view_port: &None, view_port: &None,
resolution: None, resolution: &None,
}; };
let r = core.get_by_id(&c, id).unwrap(); let r = core.get_by_id(&c, id).unwrap();
println!("get_by_id {}: {}", id, r.len()); println!("get_by_id {}: {}", id, r.len());
@@ -52,7 +52,7 @@ fn main() {
output_space: None, output_space: None,
threshold_volume: Some(0.0), threshold_volume: Some(0.0),
view_port: &None, view_port: &None,
resolution: None, resolution: &None,
}; };
let r = core.get_by_id(&c, id).unwrap(); let r = core.get_by_id(&c, id).unwrap();
println!("get_by_id {}: {}", id, r.len()); println!("get_by_id {}: {}", id, r.len());
@@ -63,7 +63,7 @@ fn main() {
output_space: None, output_space: None,
threshold_volume: Some(std::f64::MAX), threshold_volume: Some(std::f64::MAX),
view_port: &None, view_port: &None,
resolution: None, resolution: &None,
}; };
let r = core.get_by_label(&c, id).unwrap(); let r = core.get_by_label(&c, id).unwrap();
println!("get_by_label {}: {}", id, r.len()); println!("get_by_label {}: {}", id, r.len());
@@ -81,7 +81,7 @@ fn main() {
output_space: None, output_space: None,
threshold_volume: Some(0.0), threshold_volume: Some(0.0),
view_port: &None, view_port: &None,
resolution: None, resolution: &None,
}; };
let r = core.get_by_shape(&c, &shape, "std").unwrap(); let r = core.get_by_shape(&c, &shape, "std").unwrap();
println!("get_by_shape {:?}: {}", shape, r.len()); println!("get_by_shape {:?}: {}", shape, r.len());