From 8fcf1b74e7551ef6bf929403406e235465fb2adc Mon Sep 17 00:00:00 2001 From: Lionel Sambuc Date: Tue, 8 Oct 2019 10:46:31 +0200 Subject: [PATCH] Implement Hash for SpaceObject --- src/database/db_core.rs | 8 +++++--- src/database/mod.rs | 17 +++++------------ src/database/space/coordinate.rs | 21 +++++++++++++++++++++ src/database/space/position.rs | 8 +++++--- 4 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/database/db_core.rs b/src/database/db_core.rs index 8818767..cc73b95 100644 --- a/src/database/db_core.rs +++ b/src/database/db_core.rs @@ -14,7 +14,7 @@ pub struct CoreQueryParameters<'a> { pub resolution: Option>, } -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum Properties { Feature(String), Unknown(String, String), @@ -50,13 +50,15 @@ impl Properties { } } +// FIXME: Which is faster, the code below or the automatically generated +// implementation? +/* impl PartialEq for Properties { fn eq(&self, other: &Self) -> bool { self.id() == other.id() && self.type_name() == other.type_name() } } - -impl Eq for Properties {} +*/ #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Core { diff --git a/src/database/mod.rs b/src/database/mod.rs index 5fff56e..4671db3 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -5,8 +5,6 @@ mod space_index; use std::collections::HashMap; use std::fs::File; -use std::hash::Hash; -use std::hash::Hasher; use ironsea_index::Indexed; use ironsea_table_vector::VectorTable; @@ -57,13 +55,16 @@ impl PartialEq for SpaceId { } } -#[derive(Clone, Debug, Serialize)] +#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)] pub struct SpaceObject { pub space_id: String, pub position: Position, pub value: Properties, } +// FIXME: Which is faster, the code below or the automatically generated +// implementation? +/* impl PartialEq for SpaceObject { fn eq(&self, other: &Self) -> bool { self.space_id == other.space_id @@ -71,15 +72,7 @@ impl PartialEq for SpaceObject { && self.position == other.position } } - -impl Eq for SpaceObject {} - -impl Hash for SpaceObject { - //FIXME: ADD HASHING IMPLEMENTATION, REQUIRED FOR distinct()! - fn hash(&self, state: &mut H) { - unimplemented!() - } -} +*/ #[derive(Clone, Debug, Deserialize, Serialize)] pub struct DataBase { diff --git a/src/database/space/coordinate.rs b/src/database/space/coordinate.rs index daef3f4..e9c53de 100644 --- a/src/database/space/coordinate.rs +++ b/src/database/space/coordinate.rs @@ -2,6 +2,8 @@ use std::cmp::Ordering; use std::fmt; use std::fmt::Display; use std::fmt::Formatter; +use std::hash::Hash; +use std::hash::Hasher; use std::ops::Add; use std::ops::Mul; use std::ops::Sub; @@ -255,3 +257,22 @@ impl PartialEq for Coordinate { self.u64() == other.u64() } } + +impl Hash for Coordinate { + fn hash(&self, state: &mut H) { + match self { + Coordinate::CoordinateU8(v) => v.hash(state), + Coordinate::CoordinateU16(v) => v.hash(state), + Coordinate::CoordinateU32(v) => v.hash(state), + Coordinate::CoordinateU64(v) => v.hash(state), + // FIXME: Ugly workaround... 16 decimal position is enough to + // represent any mantissa of 2^53 bits. + Coordinate::CoordinateF64(v) => format!("{:.*}", 16, v).hash(state), + } + } + + /* + fn hash_slice(data: &[Self], state: &mut H) where Self: Sized { + unimplemented!() + }*/ +} diff --git a/src/database/space/position.rs b/src/database/space/position.rs index e3afbce..42d03b0 100644 --- a/src/database/space/position.rs +++ b/src/database/space/position.rs @@ -13,7 +13,7 @@ use std::ops::SubAssign; use super::coordinate::Coordinate; -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum Position { Position1(Coordinate), Position2([Coordinate; 2]), @@ -204,6 +204,9 @@ impl Mul for Position { } } +// FIXME: Which is faster, the code below or the automatically generated +// implementation? +/* impl PartialEq for Position { fn eq(&self, other: &Self) -> bool { for i in 0..self.dimensions() { @@ -214,8 +217,7 @@ impl PartialEq for Position { true } } - -impl Eq for Position {} +*/ impl<'s> From<&'s Position> for Vec<&'s Coordinate> { fn from(position: &'s Position) -> Self {