Repository: meilisearch/meilisearch
File: crates/milli/src/vector/mod.rs (Rust)

Code before:
    /// Embed in search context

    #[tracing::instrument(level = "debug", skip_all, target = "search")]
    pub fn embed_search(
        &self,
        text: &str,
        deadline: Option<Instant>,
    ) -> std::result::Result<Embedding, EmbedError> {
        if let Some(cache) = self.cache() {
            if let Some(embedding) = cache.get(text) {
                tracing::trace!(text, "embedding found in cache");
                return Ok(embedding);
            }
        }
        let embedding = match self {
            Embedder::HuggingFace(embedder) => embedder.embed_one(text),
            Embedder::OpenAi(embedder) => {
                embedder.embed(&[text], deadline)?.pop().ok_or_else(EmbedError::missing_embedding)
            }
            Embedder::Ollama(embedder) => {
                embedder.embed(&[text], deadline)?.pop().ok_or_else(EmbedError::missing_embedding)
            }
            Embedder::UserProvided(embedder) => embedder.embed_one(text),
            Embedder::Rest(embedder) => embedder
                .embed_ref(&[text], deadline)?
                .pop()
                .ok_or_else(EmbedError::missing_embedding),
            Embedder::Composite(embedder) => embedder.search.embed_one(text, deadline),
        }?;

        if let Some(cache) = self.cache() {
            tracing::trace!(text, "embedding added to cache");
            cache.put(text.to_owned(), embedding.clone());
        }

        Ok(embedding)
    }

    /// Embed multiple chunks of texts.
    ///
    /// Each chunk is composed of one or multiple texts.
    pub fn embed_index(
        &self,
        text_chunks: Vec<Vec<String>>,
        threads: &ThreadPoolNoAbort,
    ) -> std::result::Result<Vec<Vec<Embedding>>, EmbedError> {
        match self {
            Embedder::HuggingFace(embedder) => embedder.embed_index(text_chunks),
            Embedder::OpenAi(embedder) => embedder.embed_index(text_chunks, threads),
            Embedder::Ollama(embedder) => embedder.embed_index(text_chunks, threads),
            Embedder::UserProvided(embedder) => embedder.embed_index(text_chunks),

Review comment (performance):
Better as, indeed, there is a change the `&str` is in the cache and doesn't need to be copied.

Code after:
            EmbedderOptions::OpenAi(options) => {
                Self::OpenAi(openai::Embedder::new(options, cache_cap)?)
            }
            EmbedderOptions::Ollama(options) => {
                Self::Ollama(ollama::Embedder::new(options, cache_cap)?)
            }
            EmbedderOptions::UserProvided(options) => {
                Self::UserProvided(manual::Embedder::new(options))
            }
            EmbedderOptions::Rest(options) => Self::Rest(rest::Embedder::new(
                options,
                cache_cap,
                rest::ConfigurationSource::User,
            )?),
            EmbedderOptions::Composite(options) => {
                Self::Composite(composite::Embedder::new(options, cache_cap)?)
            }
        })
    }

    /// Embed in search context

    #[tracing::instrument(level = "debug", skip_all, target = "search")]
    pub fn embed_search(
        &self,
        text: &str,
        deadline: Option<Instant>,
    ) -> std::result::Result<Embedding, EmbedError> {
        if let Some(cache) = self.cache() {
            if let Some(embedding) = cache.get(text) {
                tracing::trace!(text, "embedding found in cache");
                return Ok(embedding);
            }
        }
        let embedding = match self {
            Embedder::HuggingFace(embedder) => embedder.embed_one(text),
            Embedder::OpenAi(embedder) => {
                embedder.embed(&[text], deadline)?.pop().ok_or_else(EmbedError::missing_embedding)
            }
            Embedder::Ollama(embedder) => {
                embedder.embed(&[text], deadline)?.pop().ok_or_else(EmbedError::missing_embedding)
            }
            Embedder::UserProvided(embedder) => embedder.embed_one(text),
            Embedder::Rest(embedder) => embedder
                .embed_ref(&[text], deadline)?
                .pop()
                .ok_or_else(EmbedError::missing_embedding),
            Embedder::Composite(embedder) => embedder.search.embed_one(text, deadline),
        }?;

        if let Some(cache) = self.cache() {