mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-11 07:28:56 +01:00
feat: Make the DatabaseView become Sync + Send
This commit is contained in:
parent
bec463a61a
commit
0e825e05bb
@ -1,4 +1,5 @@
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::{fmt, marker};
|
use std::{fmt, marker};
|
||||||
|
|
||||||
use rocksdb::rocksdb::{DB, DBVector, Snapshot, SeekKey};
|
use rocksdb::rocksdb::{DB, DBVector, Snapshot, SeekKey};
|
||||||
@ -14,14 +15,18 @@ use crate::database::schema::Schema;
|
|||||||
use crate::rank::QueryBuilder;
|
use crate::rank::QueryBuilder;
|
||||||
use crate::DocumentId;
|
use crate::DocumentId;
|
||||||
|
|
||||||
pub struct DatabaseView<'a> {
|
pub struct DatabaseView<D>
|
||||||
snapshot: Snapshot<&'a DB>,
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
snapshot: Snapshot<D>,
|
||||||
blob: PositiveBlob,
|
blob: PositiveBlob,
|
||||||
schema: Schema,
|
schema: Schema,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DatabaseView<'a> {
|
impl<D> DatabaseView<D>
|
||||||
pub fn new(snapshot: Snapshot<&'a DB>) -> Result<DatabaseView, Box<Error>> {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
pub fn new(snapshot: Snapshot<D>) -> Result<DatabaseView<D>, Box<Error>> {
|
||||||
let schema = retrieve_data_schema(&snapshot)?;
|
let schema = retrieve_data_schema(&snapshot)?;
|
||||||
let blob = retrieve_data_index(&snapshot)?;
|
let blob = retrieve_data_index(&snapshot)?;
|
||||||
Ok(DatabaseView { snapshot, blob, schema })
|
Ok(DatabaseView { snapshot, blob, schema })
|
||||||
@ -35,11 +40,11 @@ impl<'a> DatabaseView<'a> {
|
|||||||
&self.blob
|
&self.blob
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_snapshot(self) -> Snapshot<&'a DB> {
|
pub fn into_snapshot(self) -> Snapshot<D> {
|
||||||
self.snapshot
|
self.snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn snapshot(&self) -> &Snapshot<&'a DB> {
|
pub fn snapshot(&self) -> &Snapshot<D> {
|
||||||
&self.snapshot
|
&self.snapshot
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,20 +52,20 @@ impl<'a> DatabaseView<'a> {
|
|||||||
Ok(self.snapshot.get(key)?)
|
Ok(self.snapshot.get(key)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn query_builder(&self) -> Result<QueryBuilder<Box<dyn Criterion>>, Box<Error>> {
|
pub fn query_builder(&self) -> Result<QueryBuilder<D, Box<dyn Criterion<D>>>, Box<Error>> {
|
||||||
QueryBuilder::new(self)
|
QueryBuilder::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO create an enum error type
|
// TODO create an enum error type
|
||||||
pub fn retrieve_document<D>(&self, id: DocumentId) -> Result<D, Box<Error>>
|
pub fn retrieve_document<T>(&self, id: DocumentId) -> Result<T, Box<Error>>
|
||||||
where D: DeserializeOwned
|
where T: DeserializeOwned
|
||||||
{
|
{
|
||||||
let mut deserializer = Deserializer::new(&self.snapshot, &self.schema, id);
|
let mut deserializer = Deserializer::new(&self.snapshot, &self.schema, id);
|
||||||
Ok(D::deserialize(&mut deserializer)?)
|
Ok(T::deserialize(&mut deserializer)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn retrieve_documents<D, I>(&self, ids: I) -> DocumentIter<D, I::IntoIter>
|
pub fn retrieve_documents<T, I>(&self, ids: I) -> DocumentIter<D, T, I::IntoIter>
|
||||||
where D: DeserializeOwned,
|
where T: DeserializeOwned,
|
||||||
I: IntoIterator<Item=DocumentId>,
|
I: IntoIterator<Item=DocumentId>,
|
||||||
{
|
{
|
||||||
DocumentIter {
|
DocumentIter {
|
||||||
@ -71,7 +76,9 @@ impl<'a> DatabaseView<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Debug for DatabaseView<'a> {
|
impl<D> fmt::Debug for DatabaseView<D>
|
||||||
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut options = ReadOptions::new();
|
let mut options = ReadOptions::new();
|
||||||
let lower = DocumentKey::new(0);
|
let lower = DocumentKey::new(0);
|
||||||
@ -102,17 +109,20 @@ impl<'a> fmt::Debug for DatabaseView<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO this is just an iter::Map !!!
|
// TODO this is just an iter::Map !!!
|
||||||
pub struct DocumentIter<'a, D, I> {
|
pub struct DocumentIter<'a, D, T, I>
|
||||||
database_view: &'a DatabaseView<'a>,
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
database_view: &'a DatabaseView<D>,
|
||||||
document_ids: I,
|
document_ids: I,
|
||||||
_phantom: marker::PhantomData<D>,
|
_phantom: marker::PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D, I> Iterator for DocumentIter<'a, D, I>
|
impl<'a, D, T, I> Iterator for DocumentIter<'a, D, T, I>
|
||||||
where D: DeserializeOwned,
|
where D: Deref<Target=DB>,
|
||||||
|
T: DeserializeOwned,
|
||||||
I: Iterator<Item=DocumentId>,
|
I: Iterator<Item=DocumentId>,
|
||||||
{
|
{
|
||||||
type Item = Result<D, Box<Error>>;
|
type Item = Result<T, Box<Error>>;
|
||||||
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
self.document_ids.size_hint()
|
self.document_ids.size_hint()
|
||||||
@ -126,13 +136,15 @@ where D: DeserializeOwned,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, D, I> ExactSizeIterator for DocumentIter<'a, D, I>
|
impl<'a, D, T, I> ExactSizeIterator for DocumentIter<'a, D, T, I>
|
||||||
where D: DeserializeOwned,
|
where D: Deref<Target=DB>,
|
||||||
|
T: DeserializeOwned,
|
||||||
I: ExactSizeIterator + Iterator<Item=DocumentId>,
|
I: ExactSizeIterator + Iterator<Item=DocumentId>,
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
impl<'a, D, I> DoubleEndedIterator for DocumentIter<'a, D, I>
|
impl<'a, D, T, I> DoubleEndedIterator for DocumentIter<'a, D, T, I>
|
||||||
where D: DeserializeOwned,
|
where D: Deref<Target=DB>,
|
||||||
|
T: DeserializeOwned,
|
||||||
I: DoubleEndedIterator + Iterator<Item=DocumentId>,
|
I: DoubleEndedIterator + Iterator<Item=DocumentId>,
|
||||||
{
|
{
|
||||||
fn next_back(&mut self) -> Option<Self::Item> {
|
fn next_back(&mut self) -> Option<Self::Item> {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::ops::Deref;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rocksdb::rocksdb::{DB, Snapshot, SeekKey};
|
use rocksdb::rocksdb::{DB, Snapshot, SeekKey};
|
||||||
@ -11,19 +12,25 @@ use crate::database::document_key::{DocumentKey, DocumentKeyAttr};
|
|||||||
use crate::database::schema::Schema;
|
use crate::database::schema::Schema;
|
||||||
use crate::DocumentId;
|
use crate::DocumentId;
|
||||||
|
|
||||||
pub struct Deserializer<'a> {
|
pub struct Deserializer<'a, D>
|
||||||
snapshot: &'a Snapshot<&'a DB>,
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
snapshot: &'a Snapshot<D>,
|
||||||
schema: &'a Schema,
|
schema: &'a Schema,
|
||||||
document_id: DocumentId,
|
document_id: DocumentId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Deserializer<'a> {
|
impl<'a, D> Deserializer<'a, D>
|
||||||
pub fn new(snapshot: &'a Snapshot<&DB>, schema: &'a Schema, doc: DocumentId) -> Self {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
pub fn new(snapshot: &'a Snapshot<D>, schema: &'a Schema, doc: DocumentId) -> Self {
|
||||||
Deserializer { snapshot, schema, document_id: doc }
|
Deserializer { snapshot, schema, document_id: doc }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'de, 'a, 'b> de::Deserializer<'de> for &'b mut Deserializer<'a> {
|
impl<'de, 'a, 'b, D> de::Deserializer<'de> for &'b mut Deserializer<'a, D>
|
||||||
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
type Error = DeserializerError;
|
type Error = DeserializerError;
|
||||||
|
|
||||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
use std::sync::Arc;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use rocksdb::rocksdb_options::{DBOptions, IngestExternalFileOptions, ColumnFamilyOptions};
|
use rocksdb::rocksdb_options::{DBOptions, IngestExternalFileOptions, ColumnFamilyOptions};
|
||||||
@ -42,7 +43,8 @@ where D: Deref<Target=DB>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Database(DB);
|
#[derive(Clone)]
|
||||||
|
pub struct Database(Arc<DB>);
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
pub fn create<P: AsRef<Path>>(path: P, schema: Schema) -> Result<Database, Box<Error>> {
|
pub fn create<P: AsRef<Path>>(path: P, schema: Schema) -> Result<Database, Box<Error>> {
|
||||||
@ -66,7 +68,7 @@ impl Database {
|
|||||||
schema.write_to(&mut schema_bytes)?;
|
schema.write_to(&mut schema_bytes)?;
|
||||||
db.put(DATA_SCHEMA, &schema_bytes)?;
|
db.put(DATA_SCHEMA, &schema_bytes)?;
|
||||||
|
|
||||||
Ok(Database(db))
|
Ok(Database(Arc::new(db)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<Database, Box<Error>> {
|
pub fn open<P: AsRef<Path>>(path: P) -> Result<Database, Box<Error>> {
|
||||||
@ -86,7 +88,7 @@ impl Database {
|
|||||||
None => return Err(String::from("Database does not contain a schema").into()),
|
None => return Err(String::from("Database does not contain a schema").into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Database(db))
|
Ok(Database(Arc::new(db)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ingest_update_file(&self, update: Update) -> Result<(), Box<Error>> {
|
pub fn ingest_update_file(&self, update: Update) -> Result<(), Box<Error>> {
|
||||||
@ -114,10 +116,15 @@ impl Database {
|
|||||||
Ok(self.0.flush(true)?)
|
Ok(self.0.flush(true)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn view(&self) -> Result<DatabaseView, Box<Error>> {
|
pub fn view(&self) -> Result<DatabaseView<&DB>, Box<Error>> {
|
||||||
let snapshot = self.0.snapshot();
|
let snapshot = self.0.snapshot();
|
||||||
DatabaseView::new(snapshot)
|
DatabaseView::new(snapshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn view_arc(&self) -> Result<DatabaseView<Arc<DB>>, Box<Error>> {
|
||||||
|
let snapshot = Snapshot::new(self.0.clone());
|
||||||
|
DatabaseView::new(snapshot)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Database {
|
impl fmt::Debug for Database {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
use group_by::GroupBy;
|
use group_by::GroupBy;
|
||||||
|
|
||||||
use crate::rank::{match_query_index, Document};
|
use crate::rank::{match_query_index, Document};
|
||||||
@ -20,8 +22,10 @@ fn number_exact_matches(matches: &[Match]) -> usize {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Exact;
|
pub struct Exact;
|
||||||
|
|
||||||
impl Criterion for Exact {
|
impl<D> Criterion<D> for Exact
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
let lhs = number_exact_matches(&lhs.matches);
|
let lhs = number_exact_matches(&lhs.matches);
|
||||||
let rhs = number_exact_matches(&rhs.matches);
|
let rhs = number_exact_matches(&rhs.matches);
|
||||||
|
|
||||||
|
@ -5,8 +5,11 @@ mod sum_of_words_attribute;
|
|||||||
mod sum_of_words_position;
|
mod sum_of_words_position;
|
||||||
mod exact;
|
mod exact;
|
||||||
|
|
||||||
use std::vec;
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::vec;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
|
|
||||||
use crate::database::DatabaseView;
|
use crate::database::DatabaseView;
|
||||||
use crate::rank::Document;
|
use crate::rank::Document;
|
||||||
@ -20,32 +23,38 @@ pub use self::{
|
|||||||
exact::Exact,
|
exact::Exact,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Criterion {
|
pub trait Criterion<D>
|
||||||
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView) -> Ordering;
|
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> Ordering;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, lhs: &Document, rhs: &Document, view: &DatabaseView) -> bool {
|
fn eq(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> bool {
|
||||||
self.evaluate(lhs, rhs, view) == Ordering::Equal
|
self.evaluate(lhs, rhs, view) == Ordering::Equal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Criterion + ?Sized> Criterion for &'a T {
|
impl<'a, D, T: Criterion<D> + ?Sized> Criterion<D> for &'a T
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> Ordering {
|
||||||
(**self).evaluate(lhs, rhs, view)
|
(**self).evaluate(lhs, rhs, view)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eq(&self, lhs: &Document, rhs: &Document, view: &DatabaseView) -> bool {
|
fn eq(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> bool {
|
||||||
(**self).eq(lhs, rhs, view)
|
(**self).eq(lhs, rhs, view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Criterion + ?Sized> Criterion for Box<T> {
|
impl<D, T: Criterion<D> + ?Sized> Criterion<D> for Box<T>
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> Ordering {
|
||||||
(**self).evaluate(lhs, rhs, view)
|
(**self).evaluate(lhs, rhs, view)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eq(&self, lhs: &Document, rhs: &Document, view: &DatabaseView) -> bool {
|
fn eq(&self, lhs: &Document, rhs: &Document, view: &DatabaseView<D>) -> bool {
|
||||||
(**self).eq(lhs, rhs, view)
|
(**self).eq(lhs, rhs, view)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,15 +62,19 @@ impl<T: Criterion + ?Sized> Criterion for Box<T> {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct DocumentId;
|
pub struct DocumentId;
|
||||||
|
|
||||||
impl Criterion for DocumentId {
|
impl<D> Criterion<D> for DocumentId
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
lhs.id.cmp(&rhs.id)
|
lhs.id.cmp(&rhs.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO there is too much Box here, can we use
|
// TODO there is too much Box here, can we use
|
||||||
// static references or static closures
|
// static references or static closures
|
||||||
pub fn default() -> Vec<Box<dyn Criterion>> {
|
pub fn default<D>() -> Vec<Box<dyn Criterion<D>>>
|
||||||
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
vec![
|
vec![
|
||||||
Box::new(SumOfTypos),
|
Box::new(SumOfTypos),
|
||||||
Box::new(NumberOfWords),
|
Box::new(NumberOfWords),
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
use group_by::GroupBy;
|
use group_by::GroupBy;
|
||||||
|
|
||||||
use crate::rank::{match_query_index, Document};
|
use crate::rank::{match_query_index, Document};
|
||||||
@ -15,8 +17,10 @@ fn number_of_query_words(matches: &[Match]) -> usize {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct NumberOfWords;
|
pub struct NumberOfWords;
|
||||||
|
|
||||||
impl Criterion for NumberOfWords {
|
impl<D> Criterion<D> for NumberOfWords
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
let lhs = number_of_query_words(&lhs.matches);
|
let lhs = number_of_query_words(&lhs.matches);
|
||||||
let rhs = number_of_query_words(&rhs.matches);
|
let rhs = number_of_query_words(&rhs.matches);
|
||||||
|
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
|
|
||||||
use group_by::GroupBy;
|
use group_by::GroupBy;
|
||||||
|
|
||||||
@ -25,8 +28,10 @@ fn sum_matches_typos(matches: &[Match]) -> i8 {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct SumOfTypos;
|
pub struct SumOfTypos;
|
||||||
|
|
||||||
impl Criterion for SumOfTypos {
|
impl<D> Criterion<D> for SumOfTypos
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
let lhs = sum_matches_typos(&lhs.matches);
|
let lhs = sum_matches_typos(&lhs.matches);
|
||||||
let rhs = sum_matches_typos(&rhs.matches);
|
let rhs = sum_matches_typos(&rhs.matches);
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
use group_by::GroupBy;
|
use group_by::GroupBy;
|
||||||
|
|
||||||
use crate::database::DatabaseView;
|
use crate::database::DatabaseView;
|
||||||
@ -19,8 +21,10 @@ fn sum_matches_attributes(matches: &[Match]) -> u8 {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct SumOfWordsAttribute;
|
pub struct SumOfWordsAttribute;
|
||||||
|
|
||||||
impl Criterion for SumOfWordsAttribute {
|
impl<D> Criterion<D> for SumOfWordsAttribute
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
let lhs = sum_matches_attributes(&lhs.matches);
|
let lhs = sum_matches_attributes(&lhs.matches);
|
||||||
let rhs = sum_matches_attributes(&rhs.matches);
|
let rhs = sum_matches_attributes(&rhs.matches);
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
use group_by::GroupBy;
|
use group_by::GroupBy;
|
||||||
|
|
||||||
use crate::database::DatabaseView;
|
use crate::database::DatabaseView;
|
||||||
@ -19,8 +21,10 @@ fn sum_matches_attribute_index(matches: &[Match]) -> u32 {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct SumOfWordsPosition;
|
pub struct SumOfWordsPosition;
|
||||||
|
|
||||||
impl Criterion for SumOfWordsPosition {
|
impl<D> Criterion<D> for SumOfWordsPosition
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
let lhs = sum_matches_attribute_index(&lhs.matches);
|
let lhs = sum_matches_attribute_index(&lhs.matches);
|
||||||
let rhs = sum_matches_attribute_index(&rhs.matches);
|
let rhs = sum_matches_attribute_index(&rhs.matches);
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::cmp::{self, Ordering};
|
use std::cmp::{self, Ordering};
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
|
use rocksdb::DB;
|
||||||
use group_by::GroupBy;
|
use group_by::GroupBy;
|
||||||
|
|
||||||
use crate::rank::{match_query_index, Document};
|
use crate::rank::{match_query_index, Document};
|
||||||
@ -49,8 +51,10 @@ fn matches_proximity(matches: &[Match]) -> u32 {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct WordsProximity;
|
pub struct WordsProximity;
|
||||||
|
|
||||||
impl Criterion for WordsProximity {
|
impl<D> Criterion<D> for WordsProximity
|
||||||
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView) -> Ordering {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
fn evaluate(&self, lhs: &Document, rhs: &Document, _: &DatabaseView<D>) -> Ordering {
|
||||||
let lhs = matches_proximity(&lhs.matches);
|
let lhs = matches_proximity(&lhs.matches);
|
||||||
let rhs = matches_proximity(&rhs.matches);
|
let rhs = matches_proximity(&rhs.matches);
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
|
use std::ops::{Deref, Range};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::Range;
|
|
||||||
use std::{mem, vec, str};
|
use std::{mem, vec, str};
|
||||||
|
|
||||||
use group_by::GroupByMut;
|
use group_by::GroupByMut;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use fst::Streamer;
|
use fst::Streamer;
|
||||||
|
use rocksdb::DB;
|
||||||
|
|
||||||
use crate::automaton::{self, DfaExt, AutomatonExt};
|
use crate::automaton::{self, DfaExt, AutomatonExt};
|
||||||
use crate::rank::criterion::{self, Criterion};
|
use crate::rank::criterion::{self, Criterion};
|
||||||
@ -23,19 +24,25 @@ fn split_whitespace_automatons(query: &str) -> Vec<DfaExt> {
|
|||||||
automatons
|
automatons
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct QueryBuilder<'a, C> {
|
pub struct QueryBuilder<'a, D, C>
|
||||||
view: &'a DatabaseView<'a>,
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
view: &'a DatabaseView<D>,
|
||||||
criteria: Vec<C>,
|
criteria: Vec<C>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> QueryBuilder<'a, Box<dyn Criterion>> {
|
impl<'a, D> QueryBuilder<'a, D, Box<dyn Criterion<D>>>
|
||||||
pub fn new(view: &'a DatabaseView<'a>) -> Result<Self, Box<Error>> {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
pub fn new(view: &'a DatabaseView<D>) -> Result<Self, Box<Error>> {
|
||||||
QueryBuilder::with_criteria(view, criterion::default())
|
QueryBuilder::with_criteria(view, criterion::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C> QueryBuilder<'a, C> {
|
impl<'a, D, C> QueryBuilder<'a, D, C>
|
||||||
pub fn with_criteria(view: &'a DatabaseView<'a>, criteria: Vec<C>) -> Result<Self, Box<Error>> {
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
pub fn with_criteria(view: &'a DatabaseView<D>, criteria: Vec<C>) -> Result<Self, Box<Error>> {
|
||||||
Ok(QueryBuilder { view, criteria })
|
Ok(QueryBuilder { view, criteria })
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +51,7 @@ impl<'a, C> QueryBuilder<'a, C> {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_distinct<F>(self, function: F, size: usize) -> DistinctQueryBuilder<'a, F, C> {
|
pub fn with_distinct<F>(self, function: F, size: usize) -> DistinctQueryBuilder<'a, D, F, C> {
|
||||||
DistinctQueryBuilder {
|
DistinctQueryBuilder {
|
||||||
inner: self,
|
inner: self,
|
||||||
function: function,
|
function: function,
|
||||||
@ -92,8 +99,9 @@ impl<'a, C> QueryBuilder<'a, C> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, C> QueryBuilder<'a, C>
|
impl<'a, D, C> QueryBuilder<'a, D, C>
|
||||||
where C: Criterion
|
where D: Deref<Target=DB>,
|
||||||
|
C: Criterion<D>
|
||||||
{
|
{
|
||||||
pub fn query(&self, query: &str, limit: usize) -> Vec<Document> {
|
pub fn query(&self, query: &str, limit: usize) -> Vec<Document> {
|
||||||
let mut documents = self.query_all(query);
|
let mut documents = self.query_all(query);
|
||||||
@ -119,16 +127,19 @@ where C: Criterion
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DistinctQueryBuilder<'a, F, C> {
|
pub struct DistinctQueryBuilder<'a, D, F, C>
|
||||||
inner: QueryBuilder<'a, C>,
|
where D: Deref<Target=DB>
|
||||||
|
{
|
||||||
|
inner: QueryBuilder<'a, D, C>,
|
||||||
function: F,
|
function: F,
|
||||||
size: usize,
|
size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, F, K, C> DistinctQueryBuilder<'a, F, C>
|
impl<'a, D, F, K, C> DistinctQueryBuilder<'a, D, F, C>
|
||||||
where F: Fn(DocumentId, &DatabaseView) -> Option<K>,
|
where D: Deref<Target=DB>,
|
||||||
|
F: Fn(DocumentId, &DatabaseView<D>) -> Option<K>,
|
||||||
K: Hash + Eq,
|
K: Hash + Eq,
|
||||||
C: Criterion,
|
C: Criterion<D>,
|
||||||
{
|
{
|
||||||
pub fn query(&self, query: &str, range: Range<usize>) -> Vec<Document> {
|
pub fn query(&self, query: &str, range: Range<usize>) -> Vec<Document> {
|
||||||
let mut documents = self.inner.query_all(query);
|
let mut documents = self.inner.query_all(query);
|
||||||
|
Loading…
Reference in New Issue
Block a user