mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-09-18 10:46:26 +00:00
increase rust version from 1.85 to 1.89
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
# Compile
|
# Compile
|
||||||
FROM rust:1.85-alpine3.20 AS compiler
|
FROM rust:1.89-alpine3.20 AS compiler
|
||||||
|
|
||||||
RUN apk add -q --no-cache build-base openssl-dev
|
RUN apk add -q --no-cache build-base openssl-dev
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ impl CompatV2ToV3 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum CompatIndexV2ToV3 {
|
pub enum CompatIndexV2ToV3 {
|
||||||
V2(v2::V2IndexReader),
|
V2(v2::V2IndexReader),
|
||||||
Compat(Box<CompatIndexV1ToV2>),
|
Compat(Box<CompatIndexV1ToV2>),
|
||||||
|
@ -124,7 +124,7 @@ pub fn parse_not_exists(input: Span) -> IResult<FilterCondition> {
|
|||||||
Ok((input, FilterCondition::Not(Box::new(FilterCondition::Condition { fid: key, op: Exists }))))
|
Ok((input, FilterCondition::Not(Box::new(FilterCondition::Condition { fid: key, op: Exists }))))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_vectors(input: Span) -> IResult<(Token, Option<Token>, VectorFilter<'_>)> {
|
fn parse_vectors(input: Span) -> IResult<(Token, Option<Token>, VectorFilter)> {
|
||||||
let (input, _) = multispace0(input)?;
|
let (input, _) = multispace0(input)?;
|
||||||
let (input, fid) = tag("_vectors")(input)?;
|
let (input, fid) = tag("_vectors")(input)?;
|
||||||
|
|
||||||
|
@ -116,7 +116,7 @@ impl<'a> Token<'a> {
|
|||||||
self.span
|
self.span
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_finite_float(&self) -> Result<f64, Error> {
|
pub fn parse_finite_float(&self) -> Result<f64, Error<'a>> {
|
||||||
let value: f64 = self.value().parse().map_err(|e| self.as_external_error(e))?;
|
let value: f64 = self.value().parse().map_err(|e| self.as_external_error(e))?;
|
||||||
if value.is_finite() {
|
if value.is_finite() {
|
||||||
Ok(value)
|
Ok(value)
|
||||||
@ -166,7 +166,7 @@ pub enum TraversedElement<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FilterCondition<'a> {
|
impl<'a> FilterCondition<'a> {
|
||||||
pub fn use_contains_operator(&self) -> Option<&Token> {
|
pub fn use_contains_operator(&self) -> Option<&Token<'a>> {
|
||||||
match self {
|
match self {
|
||||||
FilterCondition::Condition { fid: _, op } => match op {
|
FilterCondition::Condition { fid: _, op } => match op {
|
||||||
Condition::GreaterThan(_)
|
Condition::GreaterThan(_)
|
||||||
@ -193,7 +193,7 @@ impl<'a> FilterCondition<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_vector_filter(&self) -> Option<&Token> {
|
pub fn use_vector_filter(&self) -> Option<&Token<'a>> {
|
||||||
match self {
|
match self {
|
||||||
FilterCondition::Condition { .. } => None,
|
FilterCondition::Condition { .. } => None,
|
||||||
FilterCondition::Not(this) => this.use_vector_filter(),
|
FilterCondition::Not(this) => this.use_vector_filter(),
|
||||||
@ -207,7 +207,7 @@ impl<'a> FilterCondition<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fids(&self, depth: usize) -> Box<dyn Iterator<Item = &Token> + '_> {
|
pub fn fids(&self, depth: usize) -> Box<dyn Iterator<Item = &Token<'a>> + '_> {
|
||||||
if depth == 0 {
|
if depth == 0 {
|
||||||
return Box::new(std::iter::empty());
|
return Box::new(std::iter::empty());
|
||||||
}
|
}
|
||||||
@ -228,7 +228,7 @@ impl<'a> FilterCondition<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the first token found at the specified depth, `None` if no token at this depth.
|
/// Returns the first token found at the specified depth, `None` if no token at this depth.
|
||||||
pub fn token_at_depth(&self, depth: usize) -> Option<&Token> {
|
pub fn token_at_depth(&self, depth: usize) -> Option<&Token<'a>> {
|
||||||
match self {
|
match self {
|
||||||
FilterCondition::Condition { fid, .. } if depth == 0 => Some(fid),
|
FilterCondition::Condition { fid, .. } if depth == 0 => Some(fid),
|
||||||
FilterCondition::Or(subfilters) => {
|
FilterCondition::Or(subfilters) => {
|
||||||
@ -651,7 +651,7 @@ pub mod tests {
|
|||||||
/// Create a raw [Token]. You must specify the string that appear BEFORE your element followed by your element
|
/// Create a raw [Token]. You must specify the string that appear BEFORE your element followed by your element
|
||||||
pub fn rtok<'a>(before: &'a str, value: &'a str) -> Token<'a> {
|
pub fn rtok<'a>(before: &'a str, value: &'a str) -> Token<'a> {
|
||||||
// if the string is empty we still need to return 1 for the line number
|
// if the string is empty we still need to return 1 for the line number
|
||||||
let lines = before.is_empty().then_some(1).unwrap_or_else(|| before.lines().count());
|
let lines = if before.is_empty() { 1 } else { before.lines().count() };
|
||||||
let offset = before.chars().count();
|
let offset = before.chars().count();
|
||||||
// the extra field is not checked in the tests so we can set it to nothing
|
// the extra field is not checked in the tests so we can set it to nothing
|
||||||
unsafe { Span::new_from_raw_offset(offset, lines as u32, value, "") }.into()
|
unsafe { Span::new_from_raw_offset(offset, lines as u32, value, "") }.into()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#![allow(clippy::result_large_err)]
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ impl From<DateField> for Code {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("{1}")]
|
#[error("{1}")]
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
// The main Error type is large and boxing the large variant make the pattern matching fails
|
||||||
|
#![allow(clippy::result_large_err)]
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This crate defines the index scheduler, which is responsible for:
|
This crate defines the index scheduler, which is responsible for:
|
||||||
1. Keeping references to meilisearch's indexes and mapping them to their
|
1. Keeping references to meilisearch's indexes and mapping them to their
|
||||||
@ -344,7 +347,7 @@ impl IndexScheduler {
|
|||||||
Ok(this)
|
Ok(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_txn(&self) -> Result<RoTxn<WithoutTls>> {
|
fn read_txn(&self) -> Result<RoTxn<'_, WithoutTls>> {
|
||||||
self.env.read_txn().map_err(|e| e.into())
|
self.env.read_txn().map_err(|e| e.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -757,7 +760,7 @@ impl IndexScheduler {
|
|||||||
|
|
||||||
/// Register a new task coming from a dump in the scheduler.
|
/// Register a new task coming from a dump in the scheduler.
|
||||||
/// By taking a mutable ref we're pretty sure no one will ever import a dump while actix is running.
|
/// By taking a mutable ref we're pretty sure no one will ever import a dump while actix is running.
|
||||||
pub fn register_dumped_task(&mut self) -> Result<Dump> {
|
pub fn register_dumped_task(&mut self) -> Result<Dump<'_>> {
|
||||||
Dump::new(self)
|
Dump::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -806,10 +809,8 @@ impl IndexScheduler {
|
|||||||
.queue
|
.queue
|
||||||
.tasks
|
.tasks
|
||||||
.get_task(self.rtxn, task_id)
|
.get_task(self.rtxn, task_id)
|
||||||
.map_err(|err| io::Error::new(io::ErrorKind::Other, err))?
|
.map_err(io::Error::other)?
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| io::Error::other(Error::CorruptedTaskQueue))?;
|
||||||
io::Error::new(io::ErrorKind::Other, Error::CorruptedTaskQueue)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
serde_json::to_writer(&mut self.buffer, &TaskView::from_task(&task))?;
|
serde_json::to_writer(&mut self.buffer, &TaskView::from_task(&task))?;
|
||||||
self.buffer.push(b'\n');
|
self.buffer.push(b'\n');
|
||||||
|
@ -326,7 +326,7 @@ impl Queue {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// it's safe to unwrap here because we checked the len above
|
// it's safe to unwrap here because we checked the len above
|
||||||
let newest_task_id = to_delete.iter().last().unwrap();
|
let newest_task_id = to_delete.iter().next_back().unwrap();
|
||||||
let last_task_to_delete =
|
let last_task_to_delete =
|
||||||
self.tasks.get_task(wtxn, newest_task_id)?.ok_or(Error::CorruptedTaskQueue)?;
|
self.tasks.get_task(wtxn, newest_task_id)?.ok_or(Error::CorruptedTaskQueue)?;
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ pub(crate) enum DocumentOperation {
|
|||||||
|
|
||||||
/// A [batch](Batch) that combines multiple tasks operating on an index.
|
/// A [batch](Batch) that combines multiple tasks operating on an index.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub(crate) enum IndexOperation {
|
pub(crate) enum IndexOperation {
|
||||||
DocumentOperation {
|
DocumentOperation {
|
||||||
index_uid: String,
|
index_uid: String,
|
||||||
|
@ -370,7 +370,7 @@ fn ureq_error_into_error(error: ureq::Error) -> Error {
|
|||||||
}
|
}
|
||||||
Err(e) => e.into(),
|
Err(e) => e.into(),
|
||||||
},
|
},
|
||||||
ureq::Error::Transport(transport) => io::Error::new(io::ErrorKind::Other, transport).into(),
|
ureq::Error::Transport(transport) => io::Error::other(transport).into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ impl<'a> BytesDecode<'a> for UuidCodec {
|
|||||||
impl BytesEncode<'_> for UuidCodec {
|
impl BytesEncode<'_> for UuidCodec {
|
||||||
type EItem = Uuid;
|
type EItem = Uuid;
|
||||||
|
|
||||||
fn bytes_encode(item: &Self::EItem) -> Result<Cow<[u8]>, BoxedError> {
|
fn bytes_encode(item: &Self::EItem) -> Result<Cow<'_, [u8]>, BoxedError> {
|
||||||
Ok(Cow::Borrowed(item.as_bytes()))
|
Ok(Cow::Borrowed(item.as_bytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -315,7 +315,9 @@ impl<'a> heed::BytesDecode<'a> for KeyIdActionCodec {
|
|||||||
impl<'a> heed::BytesEncode<'a> for KeyIdActionCodec {
|
impl<'a> heed::BytesEncode<'a> for KeyIdActionCodec {
|
||||||
type EItem = (&'a KeyId, &'a Action, Option<&'a [u8]>);
|
type EItem = (&'a KeyId, &'a Action, Option<&'a [u8]>);
|
||||||
|
|
||||||
fn bytes_encode((key_id, action, index): &Self::EItem) -> StdResult<Cow<[u8]>, BoxedError> {
|
fn bytes_encode(
|
||||||
|
(key_id, action, index): &'_ Self::EItem,
|
||||||
|
) -> StdResult<Cow<'_, [u8]>, BoxedError> {
|
||||||
let mut bytes = Vec::new();
|
let mut bytes = Vec::new();
|
||||||
|
|
||||||
bytes.extend_from_slice(key_id.as_bytes());
|
bytes.extend_from_slice(key_id.as_bytes());
|
||||||
|
@ -12,6 +12,7 @@ use tokio::task::JoinError;
|
|||||||
use crate::routes::indexes::{PROXY_ORIGIN_REMOTE_HEADER, PROXY_ORIGIN_TASK_UID_HEADER};
|
use crate::routes::indexes::{PROXY_ORIGIN_REMOTE_HEADER, PROXY_ORIGIN_TASK_UID_HEADER};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum MeilisearchHttpError {
|
pub enum MeilisearchHttpError {
|
||||||
#[error("A Content-Type header is missing. Accepted values for the Content-Type header are: {}",
|
#[error("A Content-Type header is missing. Accepted values for the Content-Type header are: {}",
|
||||||
.0.iter().map(|s| format!("`{}`", s)).collect::<Vec<_>>().join(", "))]
|
.0.iter().map(|s| format!("`{}`", s)).collect::<Vec<_>>().join(", "))]
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
|
#![allow(clippy::result_large_err)]
|
||||||
#![allow(rustdoc::private_intra_doc_links)]
|
#![allow(rustdoc::private_intra_doc_links)]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod analytics;
|
pub mod analytics;
|
||||||
|
@ -219,7 +219,7 @@ struct SearchResultByQueryIterItem<'a> {
|
|||||||
|
|
||||||
fn merge_index_local_results(
|
fn merge_index_local_results(
|
||||||
results_by_query: Vec<SearchResultByQuery<'_>>,
|
results_by_query: Vec<SearchResultByQuery<'_>>,
|
||||||
) -> impl Iterator<Item = SearchResultByQueryIterItem> + '_ {
|
) -> impl Iterator<Item = SearchResultByQueryIterItem<'_>> + '_ {
|
||||||
itertools::kmerge_by(
|
itertools::kmerge_by(
|
||||||
results_by_query.into_iter().map(SearchResultByQueryIter::new),
|
results_by_query.into_iter().map(SearchResultByQueryIter::new),
|
||||||
|left: &SearchResultByQueryIterItem, right: &SearchResultByQueryIterItem| {
|
|left: &SearchResultByQueryIterItem, right: &SearchResultByQueryIterItem| {
|
||||||
|
@ -2080,7 +2080,7 @@ pub(crate) fn parse_filter(
|
|||||||
facets: &Value,
|
facets: &Value,
|
||||||
filter_parsing_error_code: Code,
|
filter_parsing_error_code: Code,
|
||||||
features: RoFeatures,
|
features: RoFeatures,
|
||||||
) -> Result<Option<Filter>, ResponseError> {
|
) -> Result<Option<Filter<'_>>, ResponseError> {
|
||||||
let filter = match facets {
|
let filter = match facets {
|
||||||
Value::String(expr) => Filter::from_str(expr).map_err(|e| e.into()),
|
Value::String(expr) => Filter::from_str(expr).map_err(|e| e.into()),
|
||||||
Value::Array(arr) => parse_filter_array(arr).map_err(|e| e.into()),
|
Value::Array(arr) => parse_filter_array(arr).map_err(|e| e.into()),
|
||||||
@ -2117,7 +2117,7 @@ pub(crate) fn parse_filter(
|
|||||||
Ok(filter)
|
Ok(filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_filter_array(arr: &[Value]) -> Result<Option<Filter>, MeilisearchHttpError> {
|
fn parse_filter_array(arr: &'_ [Value]) -> Result<Option<Filter<'_>>, MeilisearchHttpError> {
|
||||||
let mut ands = Vec::new();
|
let mut ands = Vec::new();
|
||||||
for value in arr {
|
for value in arr {
|
||||||
match value {
|
match value {
|
||||||
|
@ -13,9 +13,9 @@
|
|||||||
//! What is going to happen at this point is that you're going to send a oneshot::Sender over an async mpsc channel.
|
//! What is going to happen at this point is that you're going to send a oneshot::Sender over an async mpsc channel.
|
||||||
//! Then, the queue/scheduler is going to either:
|
//! Then, the queue/scheduler is going to either:
|
||||||
//! - Drop your oneshot channel => that means there are too many searches going on, and yours won't be executed.
|
//! - Drop your oneshot channel => that means there are too many searches going on, and yours won't be executed.
|
||||||
//! You should exit and free all the RAM you use ASAP.
|
//! You should exit and free all the RAM you use ASAP.
|
||||||
//! - Sends you a Permit => that will unlock the method, and you will be able to process your search.
|
//! - Sends you a Permit => that will unlock the method, and you will be able to process your search.
|
||||||
//! And should drop the Permit only once you have freed all the RAM consumed by the method.
|
//! And should drop the Permit only once you have freed all the RAM consumed by the method.
|
||||||
|
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
@ -1040,7 +1040,7 @@ async fn error_single_search_forbidden_token() {
|
|||||||
];
|
];
|
||||||
|
|
||||||
let failed_query_indexes: Vec<_> =
|
let failed_query_indexes: Vec<_> =
|
||||||
std::iter::repeat(Some(0)).take(5).chain(std::iter::repeat(None).take(6)).collect();
|
std::iter::repeat_n(Some(0), 5).chain(std::iter::repeat_n(None, 6)).collect();
|
||||||
|
|
||||||
let failed_query_indexes = vec![failed_query_indexes; ACCEPTED_KEYS_SINGLE.len()];
|
let failed_query_indexes = vec![failed_query_indexes; ACCEPTED_KEYS_SINGLE.len()];
|
||||||
|
|
||||||
@ -1118,10 +1118,9 @@ async fn error_multi_search_forbidden_token() {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
let failed_query_indexes: Vec<_> = std::iter::repeat(Some(0))
|
let failed_query_indexes: Vec<_> = std::iter::repeat_n(Some(0), 5)
|
||||||
.take(5)
|
.chain(std::iter::repeat_n(Some(1), 5))
|
||||||
.chain(std::iter::repeat(Some(1)).take(5))
|
.chain(std::iter::repeat_n(None, 6))
|
||||||
.chain(std::iter::repeat(None).take(6))
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let failed_query_indexes = vec![failed_query_indexes; ACCEPTED_KEYS_BOTH.len()];
|
let failed_query_indexes = vec![failed_query_indexes; ACCEPTED_KEYS_BOTH.len()];
|
||||||
|
@ -249,7 +249,7 @@ async fn user_provide_mismatched_embedding_dimension() {
|
|||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn generate_default_user_provided_documents(server: &Server) -> Index {
|
async fn generate_default_user_provided_documents(server: &Server) -> Index<'_> {
|
||||||
let index = server.index("doggo");
|
let index = server.index("doggo");
|
||||||
|
|
||||||
let (response, code) = index
|
let (response, code) = index
|
||||||
|
@ -17,7 +17,7 @@ impl<'a> BytesDecode<'a> for UuidCodec {
|
|||||||
impl BytesEncode<'_> for UuidCodec {
|
impl BytesEncode<'_> for UuidCodec {
|
||||||
type EItem = Uuid;
|
type EItem = Uuid;
|
||||||
|
|
||||||
fn bytes_encode(item: &Self::EItem) -> Result<Cow<[u8]>, BoxedError> {
|
fn bytes_encode(item: &'_ Self::EItem) -> Result<Cow<'_, [u8]>, BoxedError> {
|
||||||
Ok(Cow::Borrowed(item.as_bytes()))
|
Ok(Cow::Borrowed(item.as_bytes()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,7 +621,7 @@ impl From<HeedError> for Error {
|
|||||||
// TODO use the encoding
|
// TODO use the encoding
|
||||||
HeedError::Encoding(_) => InternalError(Serialization(Encoding { db_name: None })),
|
HeedError::Encoding(_) => InternalError(Serialization(Encoding { db_name: None })),
|
||||||
HeedError::Decoding(_) => InternalError(Serialization(Decoding { db_name: None })),
|
HeedError::Decoding(_) => InternalError(Serialization(Decoding { db_name: None })),
|
||||||
HeedError::EnvAlreadyOpened { .. } => UserError(EnvAlreadyOpened),
|
HeedError::EnvAlreadyOpened => UserError(EnvAlreadyOpened),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,14 +19,14 @@ impl RoaringBitmapLenCodec {
|
|||||||
if cookie == SERIAL_COOKIE_NO_RUNCONTAINER {
|
if cookie == SERIAL_COOKIE_NO_RUNCONTAINER {
|
||||||
(bytes.read_u32::<LittleEndian>()? as usize, true)
|
(bytes.read_u32::<LittleEndian>()? as usize, true)
|
||||||
} else if (cookie as u16) == SERIAL_COOKIE {
|
} else if (cookie as u16) == SERIAL_COOKIE {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "run containers are unsupported"));
|
return Err(io::Error::other("run containers are unsupported"));
|
||||||
} else {
|
} else {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "unknown cookie value"));
|
return Err(io::Error::other("unknown cookie value"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if size > u16::MAX as usize + 1 {
|
if size > u16::MAX as usize + 1 {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "size is greater than supported"));
|
return Err(io::Error::other("size is greater than supported"));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut description_bytes = vec![0u8; size * 4];
|
let mut description_bytes = vec![0u8; size * 4];
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#![allow(clippy::type_complexity)]
|
#![allow(clippy::type_complexity)]
|
||||||
|
#![allow(clippy::result_large_err)]
|
||||||
|
|
||||||
#[cfg(not(windows))]
|
#[cfg(not(windows))]
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -38,7 +38,7 @@ where
|
|||||||
let highest_level = get_highest_level(rtxn, db, field_id)?;
|
let highest_level = get_highest_level(rtxn, db, field_id)?;
|
||||||
|
|
||||||
if let Some(first_bound) = get_first_facet_value::<BytesRefCodec, _>(rtxn, db, field_id)? {
|
if let Some(first_bound) = get_first_facet_value::<BytesRefCodec, _>(rtxn, db, field_id)? {
|
||||||
fd.iterate(candidates, highest_level, first_bound, usize::MAX)?;
|
let _ = fd.iterate(candidates, highest_level, first_bound, usize::MAX)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -225,11 +225,11 @@ impl<'a> Filter<'a> {
|
|||||||
Ok(Some(Self { condition }))
|
Ok(Some(Self { condition }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_contains_operator(&self) -> Option<&Token> {
|
pub fn use_contains_operator(&self) -> Option<&Token<'_>> {
|
||||||
self.condition.use_contains_operator()
|
self.condition.use_contains_operator()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn use_vector_filter(&self) -> Option<&Token> {
|
pub fn use_vector_filter(&self) -> Option<&Token<'_>> {
|
||||||
self.condition.use_vector_filter()
|
self.condition.use_vector_filter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ impl<'a> SearchForFacetValues<'a> {
|
|||||||
let exact_words_fst = self.search_query.index.exact_words(rtxn)?;
|
let exact_words_fst = self.search_query.index.exact_words(rtxn)?;
|
||||||
if exact_words_fst.is_some_and(|fst| fst.contains(query)) {
|
if exact_words_fst.is_some_and(|fst| fst.contains(query)) {
|
||||||
if fst.contains(query) {
|
if fst.contains(query) {
|
||||||
self.fetch_original_facets_using_normalized(
|
let _ = self.fetch_original_facets_using_normalized(
|
||||||
fid,
|
fid,
|
||||||
query,
|
query,
|
||||||
query,
|
query,
|
||||||
|
@ -354,15 +354,14 @@ fn maybe_add_to_results<'ctx, Q: RankingRuleQueryTrait>(
|
|||||||
logger.add_to_results(&candidates);
|
logger.add_to_results(&candidates);
|
||||||
valid_docids.extend_from_slice(&candidates);
|
valid_docids.extend_from_slice(&candidates);
|
||||||
valid_scores
|
valid_scores
|
||||||
.extend(std::iter::repeat(ranking_rule_scores.to_owned()).take(candidates.len()));
|
.extend(std::iter::repeat_n(ranking_rule_scores.to_owned(), candidates.len()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if we have passed the offset already, add some of the documents (up to the limit)
|
// if we have passed the offset already, add some of the documents (up to the limit)
|
||||||
let candidates = candidates.iter().take(length - valid_docids.len()).collect::<Vec<u32>>();
|
let candidates = candidates.iter().take(length - valid_docids.len()).collect::<Vec<u32>>();
|
||||||
logger.add_to_results(&candidates);
|
logger.add_to_results(&candidates);
|
||||||
valid_docids.extend_from_slice(&candidates);
|
valid_docids.extend_from_slice(&candidates);
|
||||||
valid_scores
|
valid_scores.extend(std::iter::repeat_n(ranking_rule_scores.to_owned(), candidates.len()));
|
||||||
.extend(std::iter::repeat(ranking_rule_scores.to_owned()).take(candidates.len()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*cur_offset += candidates.len() as usize;
|
*cur_offset += candidates.len() as usize;
|
||||||
|
@ -193,6 +193,7 @@ impl<G: RankingRuleGraphTrait> VisitorState<G> {
|
|||||||
visit: VisitFn<'_, G>,
|
visit: VisitFn<'_, G>,
|
||||||
ctx: &mut VisitorContext<'_, G>,
|
ctx: &mut VisitorContext<'_, G>,
|
||||||
) -> Result<ControlFlow<(), bool>> {
|
) -> Result<ControlFlow<(), bool>> {
|
||||||
|
#[allow(clippy::manual_contains)] // there is no method contains on mapped interner
|
||||||
if !ctx
|
if !ctx
|
||||||
.all_costs_from_node
|
.all_costs_from_node
|
||||||
.get(dest_node)
|
.get(dest_node)
|
||||||
@ -243,6 +244,8 @@ impl<G: RankingRuleGraphTrait> VisitorState<G> {
|
|||||||
|
|
||||||
// Checking that from the destination node, there is at least
|
// Checking that from the destination node, there is at least
|
||||||
// one cost that we can visit that corresponds to our remaining budget.
|
// one cost that we can visit that corresponds to our remaining budget.
|
||||||
|
|
||||||
|
#[allow(clippy::manual_contains)] // there is no contains on MappedInterner
|
||||||
if !ctx
|
if !ctx
|
||||||
.all_costs_from_node
|
.all_costs_from_node
|
||||||
.get(dest_node)
|
.get(dest_node)
|
||||||
|
@ -401,7 +401,7 @@ impl Iterator for SmallBitmapInternalIter<'_> {
|
|||||||
*cur &= *cur - 1;
|
*cur &= *cur - 1;
|
||||||
Some(idx + *base)
|
Some(idx + *base)
|
||||||
} else if next.is_empty() {
|
} else if next.is_empty() {
|
||||||
return None;
|
None
|
||||||
} else {
|
} else {
|
||||||
*base += 64;
|
*base += 64;
|
||||||
*cur = next[0];
|
*cur = next[0];
|
||||||
|
@ -79,7 +79,7 @@ impl<'ctx, Query> Sort<'ctx, Query> {
|
|||||||
return Ok(false);
|
return Ok(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(!displayed_fields.iter().any(|&field| field == field_name))
|
Ok(!displayed_fields.contains(&field_name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +52,10 @@ const MAX_FRAME_HEADER_SIZE: usize = 9;
|
|||||||
/// a message in this queue only if it is empty to avoid filling
|
/// a message in this queue only if it is empty to avoid filling
|
||||||
/// the channel *and* the BBQueue.
|
/// the channel *and* the BBQueue.
|
||||||
pub fn extractor_writer_bbqueue(
|
pub fn extractor_writer_bbqueue(
|
||||||
bbbuffers: &mut Vec<BBBuffer>,
|
bbbuffers: &'_ mut Vec<BBBuffer>,
|
||||||
total_bbbuffer_capacity: usize,
|
total_bbbuffer_capacity: usize,
|
||||||
channel_capacity: usize,
|
channel_capacity: usize,
|
||||||
) -> (ExtractorBbqueueSender, WriterBbqueueReceiver) {
|
) -> (ExtractorBbqueueSender<'_>, WriterBbqueueReceiver<'_>) {
|
||||||
let current_num_threads = rayon::current_num_threads();
|
let current_num_threads = rayon::current_num_threads();
|
||||||
let bbbuffer_capacity = total_bbbuffer_capacity.checked_div(current_num_threads).unwrap();
|
let bbbuffer_capacity = total_bbbuffer_capacity.checked_div(current_num_threads).unwrap();
|
||||||
bbbuffers.resize_with(current_num_threads, || BBBuffer::new(bbbuffer_capacity));
|
bbbuffers.resize_with(current_num_threads, || BBBuffer::new(bbbuffer_capacity));
|
||||||
|
@ -6,9 +6,7 @@ use rustc_hash::FxBuildHasher;
|
|||||||
use serde::de::{DeserializeSeed, Deserializer as _, Visitor};
|
use serde::de::{DeserializeSeed, Deserializer as _, Visitor};
|
||||||
use serde_json::value::RawValue;
|
use serde_json::value::RawValue;
|
||||||
|
|
||||||
use crate::documents::{
|
use crate::documents::{validate_document_id_str, DocumentIdExtractionError, PrimaryKey};
|
||||||
validate_document_id_str, DocumentIdExtractionError, FieldIdMapper, PrimaryKey,
|
|
||||||
};
|
|
||||||
use crate::fields_ids_map::MutFieldIdMapper;
|
use crate::fields_ids_map::MutFieldIdMapper;
|
||||||
use crate::{FieldId, UserError};
|
use crate::{FieldId, UserError};
|
||||||
|
|
||||||
@ -235,28 +233,6 @@ impl<'de, 'a, Mapper: MutFieldIdMapper> Visitor<'de> for MutFieldIdMapVisitor<'a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FieldIdMapVisitor<'a, Mapper: FieldIdMapper>(pub &'a Mapper);
|
|
||||||
|
|
||||||
impl<'de, Mapper: FieldIdMapper> Visitor<'de> for FieldIdMapVisitor<'_, Mapper> {
|
|
||||||
type Value = Option<FieldId>;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
|
||||||
write!(formatter, "expecting a string")
|
|
||||||
}
|
|
||||||
fn visit_borrowed_str<E>(self, v: &'de str) -> std::result::Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: serde::de::Error,
|
|
||||||
{
|
|
||||||
Ok(self.0.id(v))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: serde::de::Error,
|
|
||||||
{
|
|
||||||
Ok(self.0.id(v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub struct DocumentIdVisitor<'indexer>(pub &'indexer Bump);
|
pub struct DocumentIdVisitor<'indexer>(pub &'indexer Bump);
|
||||||
|
|
||||||
impl<'de, 'indexer: 'de> Visitor<'de> for DocumentIdVisitor<'indexer> {
|
impl<'de, 'indexer: 'de> Visitor<'de> for DocumentIdVisitor<'indexer> {
|
||||||
|
@ -138,7 +138,7 @@ impl<T: MostlySend> ThreadLocal<T> {
|
|||||||
self.inner.get_or_default().as_ref()
|
self.inner.get_or_default().as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_mut(&mut self) -> IterMut<T> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, T> {
|
||||||
IterMut(self.inner.iter_mut())
|
IterMut(self.inner.iter_mut())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ use crate::ThreadPoolNoAbort;
|
|||||||
pub(in crate::vector) const MAX_COMPOSITE_DISTANCE: f32 = 0.01;
|
pub(in crate::vector) const MAX_COMPOSITE_DISTANCE: f32 = 0.01;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum SubEmbedder {
|
pub enum SubEmbedder {
|
||||||
/// An embedder based on running local models, fetched from the Hugging Face Hub.
|
/// An embedder based on running local models, fetched from the Hugging Face Hub.
|
||||||
HuggingFace(hf::Embedder),
|
HuggingFace(hf::Embedder),
|
||||||
|
@ -19,6 +19,7 @@ use crate::ThreadPoolNoAbort;
|
|||||||
|
|
||||||
/// An embedder can be used to transform text into embeddings.
|
/// An embedder can be used to transform text into embeddings.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum Embedder {
|
pub enum Embedder {
|
||||||
/// An embedder based on running local models, fetched from the Hugging Face Hub.
|
/// An embedder based on running local models, fetched from the Hugging Face Hub.
|
||||||
HuggingFace(hf::Embedder),
|
HuggingFace(hf::Embedder),
|
||||||
@ -64,6 +65,7 @@ impl EmbeddingConfig {
|
|||||||
/// This type is serialized in and deserialized from the DB, any modification should either go
|
/// This type is serialized in and deserialized from the DB, any modification should either go
|
||||||
/// through dumpless upgrade or be backward-compatible
|
/// through dumpless upgrade or be backward-compatible
|
||||||
#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
|
#[derive(Debug, Clone, Hash, PartialEq, Eq, serde::Deserialize, serde::Serialize)]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum EmbedderOptions {
|
pub enum EmbedderOptions {
|
||||||
HuggingFace(hf::EmbedderOptions),
|
HuggingFace(hf::EmbedderOptions),
|
||||||
OpenAi(openai::EmbedderOptions),
|
OpenAi(openai::EmbedderOptions),
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
[toolchain]
|
[toolchain]
|
||||||
channel = "1.85.1"
|
channel = "1.89.0"
|
||||||
components = ["clippy"]
|
components = ["clippy"]
|
||||||
|
Reference in New Issue
Block a user