MeiliSearch/meilidb-core/src/store/documents_fields.rs

104 lines
3.2 KiB
Rust
Raw Normal View History

2019-10-03 11:49:13 +02:00
use std::convert::TryFrom;
use meilidb_schema::SchemaAttr;
use crate::DocumentId;
use super::{document_attribute_into_key, document_attribute_from_key};
2019-10-03 11:49:13 +02:00
2019-10-03 15:04:11 +02:00
#[derive(Copy, Clone)]
2019-10-03 11:49:13 +02:00
pub struct DocumentsFields {
pub(crate) documents_fields: rkv::SingleStore,
}
impl DocumentsFields {
2019-10-03 16:13:09 +02:00
pub fn put_document_field(
2019-10-03 15:04:11 +02:00
&self,
writer: &mut rkv::Writer,
document_id: DocumentId,
2019-10-03 16:13:09 +02:00
attribute: SchemaAttr,
value: &[u8],
) -> Result<(), rkv::StoreError>
2019-10-03 15:04:11 +02:00
{
2019-10-03 16:13:09 +02:00
let key = document_attribute_into_key(document_id, attribute);
self.documents_fields.put(writer, key, &rkv::Value::Blob(value))
2019-10-03 15:04:11 +02:00
}
2019-10-03 16:13:09 +02:00
pub fn del_all_document_fields(
2019-10-03 15:04:11 +02:00
&self,
2019-10-03 11:49:13 +02:00
writer: &mut rkv::Writer,
document_id: DocumentId,
2019-10-03 16:13:09 +02:00
) -> Result<usize, rkv::StoreError>
2019-10-03 11:49:13 +02:00
{
2019-10-03 16:13:09 +02:00
let document_id_bytes = document_id.0.to_be_bytes();
let mut keys_to_delete = Vec::new();
// WARN we can not delete the keys using the iterator
// so we store them and delete them just after
let iter = self.documents_fields.iter_from(writer, document_id_bytes)?;
for result in iter {
let (key, _) = result?;
let array = TryFrom::try_from(key).unwrap();
let (current_document_id, _) = document_attribute_from_key(array);
2019-10-03 16:13:09 +02:00
if current_document_id != document_id { break }
2019-10-03 16:13:09 +02:00
keys_to_delete.push(key.to_owned());
}
let count = keys_to_delete.len();
for key in keys_to_delete {
self.documents_fields.delete(writer, key)?;
}
Ok(count)
2019-10-03 11:49:13 +02:00
}
pub fn document_attribute<'a>(
2019-10-03 11:49:13 +02:00
&self,
2019-10-04 10:21:09 +02:00
reader: &'a impl rkv::Readable,
2019-10-03 11:49:13 +02:00
document_id: DocumentId,
attribute: SchemaAttr,
2019-10-03 16:13:09 +02:00
) -> Result<Option<&'a [u8]>, rkv::StoreError>
2019-10-03 11:49:13 +02:00
{
2019-10-03 16:13:09 +02:00
let key = document_attribute_into_key(document_id, attribute);
match self.documents_fields.get(reader, key)? {
Some(rkv::Value::Blob(bytes)) => Ok(Some(bytes)),
Some(value) => panic!("invalid type {:?}", value),
None => Ok(None),
}
2019-10-03 11:49:13 +02:00
}
pub fn document_fields<'r, T: rkv::Readable>(
&self,
reader: &'r T,
document_id: DocumentId,
2019-10-08 17:31:07 +02:00
) -> Result<DocumentFieldsIter<'r>, rkv::StoreError>
2019-10-03 11:49:13 +02:00
{
let document_id_bytes = document_id.0.to_be_bytes();
let iter = self.documents_fields.iter_from(reader, document_id_bytes)?;
2019-10-08 17:31:07 +02:00
Ok(DocumentFieldsIter { document_id, iter })
2019-10-03 11:49:13 +02:00
}
}
2019-10-08 17:31:07 +02:00
pub struct DocumentFieldsIter<'r> {
2019-10-03 11:49:13 +02:00
document_id: DocumentId,
iter: rkv::store::single::Iter<'r>,
}
2019-10-08 17:31:07 +02:00
impl<'r> Iterator for DocumentFieldsIter<'r> {
2019-10-03 11:49:13 +02:00
type Item = Result<(SchemaAttr, &'r [u8]), rkv::StoreError>;
fn next(&mut self) -> Option<Self::Item> {
match self.iter.next() {
Some(Ok((key, Some(rkv::Value::Blob(bytes))))) => {
let array = TryFrom::try_from(key).unwrap();
let (current_document_id, attr) = document_attribute_from_key(array);
if current_document_id != self.document_id { return None; }
2019-10-03 11:49:13 +02:00
Some(Ok((attr, bytes)))
},
Some(Ok((key, data))) => panic!("{:?}, {:?}", key, data),
Some(Err(e)) => Some(Err(e)),
None => None,
}
}
}