mirror of
https://github.com/meilisearch/meilisearch.git
synced 2024-11-26 03:55:07 +08:00
feat: Introduce the DocumentKey and DocumentKeyAttr structs
This commit is contained in:
parent
700d625c93
commit
3d0b334942
@ -1,6 +1,7 @@
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use fst::Automaton;
|
use fst::Automaton;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use levenshtein_automata::{
|
use levenshtein_automata::{
|
||||||
LevenshteinAutomatonBuilder as LevBuilder,
|
LevenshteinAutomatonBuilder as LevBuilder,
|
||||||
DFA, Distance,
|
DFA, Distance,
|
||||||
|
@ -8,6 +8,7 @@ pub use self::ops::OpBuilder;
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use serde_derive::{Serialize, Deserialize};
|
||||||
use serde::ser::{Serialize, Serializer, SerializeTuple};
|
use serde::ser::{Serialize, Serializer, SerializeTuple};
|
||||||
use serde::de::{self, Deserialize, Deserializer, SeqAccess, Visitor};
|
use serde::de::{self, Deserialize, Deserializer, SeqAccess, Visitor};
|
||||||
|
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
use std::io::{Cursor, Write};
|
use std::io::{Cursor, Read, Write};
|
||||||
use std::{fmt, marker};
|
use std::{fmt, marker};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::mem::size_of;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use rocksdb::rocksdb::{DB, Snapshot, DBVector};
|
use rocksdb::rocksdb::{DB, Snapshot, DBVector};
|
||||||
use rocksdb::rocksdb_options::ReadOptions;
|
use rocksdb::rocksdb_options::ReadOptions;
|
||||||
use byteorder::{NetworkEndian, WriteBytesExt};
|
use byteorder::{NativeEndian, WriteBytesExt, ReadBytesExt};
|
||||||
use serde::de::{DeserializeOwned, Visitor};
|
use serde::de::{DeserializeOwned, Visitor};
|
||||||
use serde::de::value::MapDeserializer;
|
use serde::de::value::MapDeserializer;
|
||||||
|
use serde::forward_to_deserialize_any;
|
||||||
|
|
||||||
use crate::index::schema::{Schema, SchemaAttr};
|
use crate::index::schema::{Schema, SchemaAttr};
|
||||||
use crate::blob::positive::PositiveBlob;
|
use crate::blob::positive::PositiveBlob;
|
||||||
@ -17,8 +19,8 @@ use crate::DocumentId;
|
|||||||
const DATA_INDEX: &[u8] = b"data-index";
|
const DATA_INDEX: &[u8] = b"data-index";
|
||||||
const DATA_SCHEMA: &[u8] = b"data-schema";
|
const DATA_SCHEMA: &[u8] = b"data-schema";
|
||||||
|
|
||||||
const DOC_KEY_LEN: usize = 4 + std::mem::size_of::<u64>();
|
const DOC_KEY_LEN: usize = 4 + size_of::<u64>();
|
||||||
const DOC_KEY_ATTR_LEN: usize = DOC_KEY_LEN + 1 + std::mem::size_of::<u32>();
|
const DOC_KEY_ATTR_LEN: usize = DOC_KEY_LEN + 1 + size_of::<u32>();
|
||||||
|
|
||||||
// FIXME Do not panic!
|
// FIXME Do not panic!
|
||||||
fn retrieve_data_schema(snapshot: &Snapshot<&DB>) -> Result<Schema, Box<Error>> {
|
fn retrieve_data_schema(snapshot: &Snapshot<&DB>) -> Result<Schema, Box<Error>> {
|
||||||
@ -35,36 +37,90 @@ fn retrieve_data_index(snapshot: &Snapshot<&DB>) -> Result<PositiveBlob, Box<Err
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn retrieve_document_attribute(
|
#[derive(Copy, Clone)]
|
||||||
snapshot: &Snapshot<&DB>,
|
pub struct DocumentKey([u8; DOC_KEY_LEN]);
|
||||||
id: DocumentId,
|
|
||||||
attr: SchemaAttr
|
|
||||||
) -> Result<Option<DBVector>, Box<Error>>
|
|
||||||
{
|
|
||||||
let attribute_key = document_key_attr(id, attr);
|
|
||||||
Ok(snapshot.get(&attribute_key)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn document_key(id: DocumentId) -> [u8; DOC_KEY_LEN] {
|
impl DocumentKey {
|
||||||
let mut key = [0; DOC_KEY_LEN];
|
pub fn new(id: DocumentId) -> DocumentKey {
|
||||||
|
let mut buffer = [0; DOC_KEY_LEN];
|
||||||
|
|
||||||
let mut wtr = Cursor::new(&mut key[..]);
|
let mut wtr = Cursor::new(&mut buffer[..]);
|
||||||
wtr.write_all(b"doc-").unwrap();
|
wtr.write_all(b"doc-").unwrap();
|
||||||
wtr.write_u64::<NetworkEndian>(id).unwrap();
|
wtr.write_u64::<NativeEndian>(id).unwrap();
|
||||||
|
|
||||||
key
|
DocumentKey(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_bytes(mut bytes: &[u8]) -> DocumentKey {
|
||||||
|
assert!(bytes.len() >= DOC_KEY_LEN);
|
||||||
|
assert_eq!(&bytes[..4], b"doc-");
|
||||||
|
|
||||||
|
let mut buffer = [0; DOC_KEY_LEN];
|
||||||
|
bytes.read_exact(&mut buffer).unwrap();
|
||||||
|
|
||||||
|
DocumentKey(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_attribute(&self, attr: SchemaAttr) -> DocumentKeyAttr {
|
||||||
|
DocumentKeyAttr::new(self.document_id(), attr)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn document_id(&self) -> DocumentId {
|
||||||
|
(&self.0[4..]).read_u64::<NativeEndian>().unwrap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn document_key_attr(id: DocumentId, attr: SchemaAttr) -> [u8; DOC_KEY_ATTR_LEN] {
|
impl AsRef<[u8]> for DocumentKey {
|
||||||
let mut key = [0; DOC_KEY_ATTR_LEN];
|
fn as_ref(&self) -> &[u8] {
|
||||||
let raw_key = document_key(id);
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut wtr = Cursor::new(&mut key[..]);
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct DocumentKeyAttr([u8; DOC_KEY_ATTR_LEN]);
|
||||||
|
|
||||||
|
impl DocumentKeyAttr {
|
||||||
|
pub fn new(id: DocumentId, attr: SchemaAttr) -> DocumentKeyAttr {
|
||||||
|
let mut buffer = [0; DOC_KEY_ATTR_LEN];
|
||||||
|
let DocumentKey(raw_key) = DocumentKey::new(id);
|
||||||
|
|
||||||
|
let mut wtr = Cursor::new(&mut buffer[..]);
|
||||||
wtr.write_all(&raw_key).unwrap();
|
wtr.write_all(&raw_key).unwrap();
|
||||||
wtr.write_all(b"-").unwrap();
|
wtr.write_all(b"-").unwrap();
|
||||||
wtr.write_u32::<NetworkEndian>(attr.as_u32()).unwrap();
|
wtr.write_u32::<NativeEndian>(attr.as_u32()).unwrap();
|
||||||
|
|
||||||
key
|
DocumentKeyAttr(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_bytes(mut bytes: &[u8]) -> DocumentKeyAttr {
|
||||||
|
assert!(bytes.len() >= DOC_KEY_ATTR_LEN);
|
||||||
|
assert_eq!(&bytes[..4], b"doc-");
|
||||||
|
|
||||||
|
let mut buffer = [0; DOC_KEY_ATTR_LEN];
|
||||||
|
bytes.read_exact(&mut buffer).unwrap();
|
||||||
|
|
||||||
|
DocumentKeyAttr(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn document_id(&self) -> DocumentId {
|
||||||
|
(&self.0[4..]).read_u64::<NativeEndian>().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn attribute(&self) -> SchemaAttr {
|
||||||
|
let offset = 4 + size_of::<u64>() + 1;
|
||||||
|
let value = (&self.0[offset..]).read_u32::<NativeEndian>().unwrap();
|
||||||
|
SchemaAttr::new(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_document_key(self) -> DocumentKey {
|
||||||
|
DocumentKey::new(self.document_id())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for DocumentKeyAttr {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Database(DB);
|
pub struct Database(DB);
|
||||||
@ -162,229 +218,56 @@ impl<'de, 'a, 'b> serde::de::Deserializer<'de> for &'b mut Deserializer<'a> {
|
|||||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor<'de>
|
where V: Visitor<'de>
|
||||||
{
|
{
|
||||||
unimplemented!()
|
self.deserialize_map(visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
forward_to_deserialize_any! {
|
||||||
where V: Visitor<'de>
|
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq
|
||||||
{
|
bytes byte_buf unit_struct tuple_struct
|
||||||
unimplemented!()
|
identifier tuple ignored_any option newtype_struct enum
|
||||||
}
|
struct
|
||||||
|
|
||||||
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_unit_struct<V>(
|
|
||||||
self,
|
|
||||||
name: &'static str,
|
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_newtype_struct<V>(
|
|
||||||
self,
|
|
||||||
name: &'static str,
|
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_tuple<V>(
|
|
||||||
self,
|
|
||||||
len: usize,
|
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_tuple_struct<V>(
|
|
||||||
self,
|
|
||||||
name: &'static str,
|
|
||||||
len: usize,
|
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
where V: Visitor<'de>
|
where V: Visitor<'de>
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_struct<V>(
|
|
||||||
self,
|
|
||||||
name: &'static str,
|
|
||||||
fields: &'static [&'static str],
|
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
{
|
||||||
let mut options = ReadOptions::new();
|
let mut options = ReadOptions::new();
|
||||||
options.set_iterate_lower_bound(&document_key(self.document_id));
|
let lower = DocumentKey::new(self.document_id);
|
||||||
options.set_iterate_upper_bound(&document_key(self.document_id + 1));
|
let upper = DocumentKey::new(self.document_id + 1);
|
||||||
|
options.set_iterate_lower_bound(lower.as_ref());
|
||||||
|
options.set_iterate_upper_bound(upper.as_ref());
|
||||||
|
|
||||||
let mut db_iter = self.snapshot.iter_opt(options);
|
let mut db_iter = self.snapshot.iter_opt(options);
|
||||||
let iter = db_iter.map(|(key, value)| ("hello", "ok"));
|
let iter = db_iter.map(|(key, value)| {
|
||||||
|
// retrieve the schema attribute name
|
||||||
// Create the DocumentKey and DocumentKeyAttr types
|
// from the schema attribute number
|
||||||
// to help create and parse document keys attributes...
|
let document_key_attr = DocumentKeyAttr::from_bytes(&key);
|
||||||
unimplemented!();
|
let schema_attr = document_key_attr.attribute();
|
||||||
|
let attribute_name = self.schema.attribute_name(schema_attr);
|
||||||
|
(attribute_name, value)
|
||||||
|
});
|
||||||
|
|
||||||
let map_deserializer = MapDeserializer::new(iter);
|
let map_deserializer = MapDeserializer::new(iter);
|
||||||
visitor.visit_map(map_deserializer)
|
visitor.visit_map(map_deserializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize_enum<V>(
|
|
||||||
self,
|
|
||||||
name: &'static str,
|
|
||||||
variants: &'static [&'static str],
|
|
||||||
visitor: V
|
|
||||||
) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>,
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
|
||||||
where V: Visitor<'de>
|
|
||||||
{
|
|
||||||
unimplemented!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct DeserializerError;
|
enum DeserializerError {
|
||||||
|
Custom(String),
|
||||||
|
}
|
||||||
|
|
||||||
impl serde::de::Error for DeserializerError {
|
impl serde::de::Error for DeserializerError {
|
||||||
fn custom<T: fmt::Display>(msg: T) -> Self {
|
fn custom<T: fmt::Display>(msg: T) -> Self {
|
||||||
unimplemented!()
|
DeserializerError::Custom(msg.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for DeserializerError {
|
impl fmt::Display for DeserializerError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
unimplemented!()
|
match self {
|
||||||
|
DeserializerError::Custom(s) => f.write_str(&s),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ use std::ops::BitOr;
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use serde_derive::{Serialize, Deserialize};
|
||||||
use linked_hash_map::LinkedHashMap;
|
use linked_hash_map::LinkedHashMap;
|
||||||
|
|
||||||
pub const STORED: SchemaProps = SchemaProps { stored: true, indexed: false };
|
pub const STORED: SchemaProps = SchemaProps { stored: true, indexed: false };
|
||||||
@ -118,6 +119,10 @@ impl Schema {
|
|||||||
pub struct SchemaAttr(u32);
|
pub struct SchemaAttr(u32);
|
||||||
|
|
||||||
impl SchemaAttr {
|
impl SchemaAttr {
|
||||||
|
pub fn new(value: u32) -> SchemaAttr {
|
||||||
|
SchemaAttr(value)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_u32(&self) -> u32 {
|
pub fn as_u32(&self) -> u32 {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#[macro_use] extern crate lazy_static;
|
|
||||||
#[macro_use] extern crate serde_derive;
|
|
||||||
|
|
||||||
pub mod automaton;
|
pub mod automaton;
|
||||||
pub mod blob;
|
pub mod blob;
|
||||||
pub mod database;
|
pub mod database;
|
||||||
|
Loading…
Reference in New Issue
Block a user