From 05476712462272c280f646c313f67290c56db918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Renault?= Date: Fri, 26 Apr 2019 12:18:39 +0200 Subject: [PATCH] feat: Take ranked attributes into account --- meilidb-data/src/database.rs | 22 ++- meilidb-data/src/number.rs | 2 +- meilidb-data/src/serde/convert_to_number.rs | 180 ++++++++++++++++++++ meilidb-data/src/serde/mod.rs | 15 +- meilidb-data/src/serde/serializer.rs | 15 +- 5 files changed, 224 insertions(+), 10 deletions(-) create mode 100644 meilidb-data/src/serde/convert_to_number.rs diff --git a/meilidb-data/src/database.rs b/meilidb-data/src/database.rs index 357693ad8..da43dd4bc 100644 --- a/meilidb-data/src/database.rs +++ b/meilidb-data/src/database.rs @@ -251,8 +251,12 @@ impl RawIndex { Ok(()) } - pub fn update_ranked_map(&self, ranked_map: Arc) { - self.ranked_map.store(ranked_map) + pub fn update_ranked_map(&self, ranked_map: Arc) -> sled::Result<()> { + let data = bincode::serialize(ranked_map.as_ref()).unwrap(); + self.inner.set("ranked-map", data).map(drop)?; + self.ranked_map.store(ranked_map); + + Ok(()) } pub fn set_document_attribute( @@ -343,7 +347,8 @@ impl Index { pub fn documents_addition(&self) -> DocumentsAddition { let index = self.0.clone(); - DocumentsAddition::from_raw(index) + let ranked_map = self.0.ranked_map().clone(); + DocumentsAddition::from_raw(index, ranked_map) } pub fn documents_deletion(&self) -> DocumentsDeletion { @@ -381,11 +386,12 @@ impl Index { pub struct DocumentsAddition { inner: RawIndex, indexer: Indexer, + ranked_map: RankedMap, } impl DocumentsAddition { - pub fn from_raw(inner: RawIndex) -> DocumentsAddition { - DocumentsAddition { inner, indexer: Indexer::new() } + pub fn from_raw(inner: RawIndex, ranked_map: RankedMap) -> DocumentsAddition { + DocumentsAddition { inner, indexer: Indexer::new(), ranked_map } } pub fn update_document(&mut self, document: D) -> Result<(), Error> @@ -403,6 +409,7 @@ impl DocumentsAddition { schema, index: &self.inner, indexer: &mut self.indexer, + ranked_map: &mut self.ranked_map, document_id, }; @@ -430,7 +437,10 @@ pub struct DocumentsDeletion { impl DocumentsDeletion { pub fn from_raw(inner: RawIndex) -> DocumentsDeletion { - DocumentsDeletion { inner, documents: Vec::new() } + DocumentsDeletion { + inner, + documents: Vec::new(), + } } pub fn delete_document(&mut self, id: DocumentId) { diff --git a/meilidb-data/src/number.rs b/meilidb-data/src/number.rs index 9a2d0ea24..5e64cc78f 100644 --- a/meilidb-data/src/number.rs +++ b/meilidb-data/src/number.rs @@ -36,7 +36,7 @@ impl FromStr for Number { } } -#[derive(Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ParseNumberError { uint_error: ParseIntError, int_error: ParseIntError, diff --git a/meilidb-data/src/serde/convert_to_number.rs b/meilidb-data/src/serde/convert_to_number.rs new file mode 100644 index 000000000..57223a6c1 --- /dev/null +++ b/meilidb-data/src/serde/convert_to_number.rs @@ -0,0 +1,180 @@ +use std::str::FromStr; + +use ordered_float::OrderedFloat; +use serde::ser; +use serde::Serialize; + +use super::SerializerError; +use crate::Number; + +pub struct ConvertToNumber; + +impl ser::Serializer for ConvertToNumber { + type Ok = Number; + type Error = SerializerError; + type SerializeSeq = ser::Impossible; + type SerializeTuple = ser::Impossible; + type SerializeTupleStruct = ser::Impossible; + type SerializeTupleVariant = ser::Impossible; + type SerializeMap = ser::Impossible; + type SerializeStruct = ser::Impossible; + type SerializeStructVariant = ser::Impossible; + + fn serialize_bool(self, value: bool) -> Result { + Ok(Number::Unsigned(u64::from(value))) + } + + fn serialize_char(self, value: char) -> Result { + unimplemented!() + } + + fn serialize_i8(self, value: i8) -> Result { + Ok(Number::Signed(i64::from(value))) + } + + fn serialize_i16(self, value: i16) -> Result { + Ok(Number::Signed(i64::from(value))) + } + + fn serialize_i32(self, value: i32) -> Result { + Ok(Number::Signed(i64::from(value))) + } + + fn serialize_i64(self, value: i64) -> Result { + Ok(Number::Signed(value)) + } + + fn serialize_u8(self, value: u8) -> Result { + Ok(Number::Unsigned(u64::from(value))) + } + + fn serialize_u16(self, value: u16) -> Result { + Ok(Number::Unsigned(u64::from(value))) + } + + fn serialize_u32(self, value: u32) -> Result { + Ok(Number::Unsigned(u64::from(value))) + } + + fn serialize_u64(self, value: u64) -> Result { + Ok(Number::Unsigned(value)) + } + + fn serialize_f32(self, value: f32) -> Result { + Ok(Number::Float(OrderedFloat(value as f64))) + } + + fn serialize_f64(self, value: f64) -> Result { + Ok(Number::Float(OrderedFloat(value))) + } + + fn serialize_str(self, value: &str) -> Result { + Ok(Number::from_str(value)?) + } + + fn serialize_bytes(self, _v: &[u8]) -> Result { + Err(SerializerError::UnserializableType { type_name: "&[u8]" }) + } + + fn serialize_none(self) -> Result { + Err(SerializerError::UnserializableType { type_name: "Option" }) + } + + fn serialize_some(self, _value: &T) -> Result + where T: Serialize, + { + Err(SerializerError::UnserializableType { type_name: "Option" }) + } + + fn serialize_unit(self) -> Result { + Err(SerializerError::UnserializableType { type_name: "()" }) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result { + Err(SerializerError::UnserializableType { type_name: "unit struct" }) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str + ) -> Result + { + Err(SerializerError::UnserializableType { type_name: "unit variant" }) + } + + fn serialize_newtype_struct( + self, + _name: &'static str, + value: &T + ) -> Result + where T: Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T + ) -> Result + where T: Serialize, + { + Err(SerializerError::UnserializableType { type_name: "newtype variant" }) + } + + fn serialize_seq(self, _len: Option) -> Result { + Err(SerializerError::UnserializableType { type_name: "sequence" }) + } + + fn serialize_tuple(self, _len: usize) -> Result { + Err(SerializerError::UnserializableType { type_name: "tuple" }) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + _len: usize + ) -> Result + { + Err(SerializerError::UnserializableType { type_name: "tuple struct" }) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize + ) -> Result + { + Err(SerializerError::UnserializableType { type_name: "tuple variant" }) + } + + fn serialize_map(self, _len: Option) -> Result { + Err(SerializerError::UnserializableType { type_name: "map" }) + } + + fn serialize_struct( + self, + _name: &'static str, + _len: usize + ) -> Result + { + Err(SerializerError::UnserializableType { type_name: "struct" }) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize + ) -> Result + { + Err(SerializerError::UnserializableType { type_name: "struct variant" }) + } +} diff --git a/meilidb-data/src/serde/mod.rs b/meilidb-data/src/serde/mod.rs index 94e3172dd..75209c574 100644 --- a/meilidb-data/src/serde/mod.rs +++ b/meilidb-data/src/serde/mod.rs @@ -8,27 +8,31 @@ macro_rules! forward_to_unserializable_type { } } +mod convert_to_number; +mod convert_to_string; mod deserializer; mod extract_document_id; -mod convert_to_string; mod indexer; mod serializer; pub use self::deserializer::Deserializer; pub use self::extract_document_id::extract_document_id; pub use self::convert_to_string::ConvertToString; +pub use self::convert_to_number::ConvertToNumber; pub use self::indexer::Indexer; pub use self::serializer::Serializer; use std::{fmt, error::Error}; use rmp_serde::encode::Error as RmpError; use serde::ser; +use crate::number::ParseNumberError; #[derive(Debug)] pub enum SerializerError { DocumentIdNotFound, RmpError(RmpError), SledError(sled::Error), + ParseNumberError(ParseNumberError), UnserializableType { type_name: &'static str }, UnindexableType { type_name: &'static str }, Custom(String), @@ -48,6 +52,9 @@ impl fmt::Display for SerializerError { } SerializerError::RmpError(e) => write!(f, "rmp serde related error: {}", e), SerializerError::SledError(e) => write!(f, "sled related error: {}", e), + SerializerError::ParseNumberError(e) => { + write!(f, "error while trying to parse a number: {}", e) + }, SerializerError::UnserializableType { type_name } => { write!(f, "{} are not a serializable type", type_name) }, @@ -78,3 +85,9 @@ impl From for SerializerError { SerializerError::SledError(error) } } + +impl From for SerializerError { + fn from(error: ParseNumberError) -> SerializerError { + SerializerError::ParseNumberError(error) + } +} diff --git a/meilidb-data/src/serde/serializer.rs b/meilidb-data/src/serde/serializer.rs index d71c87f14..37b3c7036 100644 --- a/meilidb-data/src/serde/serializer.rs +++ b/meilidb-data/src/serde/serializer.rs @@ -2,14 +2,16 @@ use meilidb_core::DocumentId; use serde::ser; use crate::database::RawIndex; +use crate::ranked_map::RankedMap; use crate::indexer::Indexer as RawIndexer; use crate::schema::{Schema, SchemaAttr}; -use super::{SerializerError, ConvertToString, Indexer}; +use super::{SerializerError, ConvertToString, ConvertToNumber, Indexer}; pub struct Serializer<'a> { pub schema: &'a Schema, pub index: &'a RawIndex, pub indexer: &'a mut RawIndexer, + pub ranked_map: &'a mut RankedMap, pub document_id: DocumentId, } @@ -134,6 +136,7 @@ impl<'a> ser::Serializer for Serializer<'a> { document_id: self.document_id, index: self.index, indexer: self.indexer, + ranked_map: self.ranked_map, current_key_name: None, }) } @@ -149,6 +152,7 @@ impl<'a> ser::Serializer for Serializer<'a> { document_id: self.document_id, index: self.index, indexer: self.indexer, + ranked_map: self.ranked_map, }) } @@ -169,6 +173,7 @@ pub struct MapSerializer<'a> { document_id: DocumentId, index: &'a RawIndex, indexer: &'a mut RawIndexer, + ranked_map: &'a mut RankedMap, current_key_name: Option, } @@ -205,6 +210,7 @@ impl<'a> ser::SerializeMap for MapSerializer<'a> { self.document_id, self.index, self.indexer, + self.ranked_map, &key, value, ) @@ -220,6 +226,7 @@ pub struct StructSerializer<'a> { document_id: DocumentId, index: &'a RawIndex, indexer: &'a mut RawIndexer, + ranked_map: &'a mut RankedMap, } impl<'a> ser::SerializeStruct for StructSerializer<'a> { @@ -238,6 +245,7 @@ impl<'a> ser::SerializeStruct for StructSerializer<'a> { self.document_id, self.index, self.indexer, + self.ranked_map, key, value, ) @@ -253,6 +261,7 @@ fn serialize_value( document_id: DocumentId, index: &RawIndex, indexer: &mut RawIndexer, + ranked_map: &mut RankedMap, key: &str, value: &T, ) -> Result<(), SerializerError> @@ -276,7 +285,9 @@ where T: ser::Serialize, } if props.is_ranked() { - unimplemented!() + let key = (document_id, attr); + let number = value.serialize(ConvertToNumber)?; + ranked_map.insert(key, number); } }