From 0275b36fb0db758a6fb32b3a933ba2595e9a578d Mon Sep 17 00:00:00 2001 From: tamo Date: Mon, 10 May 2021 20:24:14 +0200 Subject: [PATCH] [WIP] rebase on main --- meilisearch-http/src/index/updates.rs | 9 +- .../src/index_controller/dump/mod.rs | 4 +- .../src/index_controller/dump/v1.rs | 6 +- .../src/index_controller/dump/v2.rs | 2 +- .../src/index_controller/index_actor/actor.rs | 4 +- .../index_actor/handle_impl.rs | 6 +- .../index_controller/index_actor/message.rs | 2 +- .../src/index_controller/index_actor/mod.rs | 2 + meilisearch-http/src/index_controller/mod.rs | 3 + .../index_controller/update_actor/actor.rs | 125 +++++------------- .../update_actor/handle_impl.rs | 11 +- .../index_controller/update_actor/message.rs | 6 +- .../src/index_controller/update_actor/mod.rs | 6 +- .../update_actor/update_store.rs | 55 +++----- .../index_controller/uuid_resolver/actor.rs | 2 +- .../uuid_resolver/handle_impl.rs | 2 +- .../index_controller/uuid_resolver/message.rs | 2 +- .../src/index_controller/uuid_resolver/mod.rs | 2 +- .../index_controller/uuid_resolver/store.rs | 14 +- meilisearch-http/src/routes/index.rs | 4 +- 20 files changed, 93 insertions(+), 174 deletions(-) diff --git a/meilisearch-http/src/index/updates.rs b/meilisearch-http/src/index/updates.rs index a3012fe9a..75d0dc3e6 100644 --- a/meilisearch-http/src/index/updates.rs +++ b/meilisearch-http/src/index/updates.rs @@ -5,17 +5,12 @@ use std::marker::PhantomData; use flate2::read::GzDecoder; use log::info; -use milli::update::{DocumentAdditionResult, IndexDocumentsMethod, UpdateBuilder, UpdateFormat}; +use milli::update::{IndexDocumentsMethod, UpdateBuilder, UpdateFormat}; use serde::{Deserialize, Serialize}; use super::{deserialize_some, deserialize_wildcard, Index}; +use crate::index_controller::UpdateResult; -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum UpdateResult { - DocumentsAddition(DocumentAdditionResult), - DocumentDeletion { deleted: u64 }, - Other, -} #[derive(Clone, Default, Debug)] pub struct Checked; diff --git a/meilisearch-http/src/index_controller/dump/mod.rs b/meilisearch-http/src/index_controller/dump/mod.rs index 1f42466cb..c12041e9d 100644 --- a/meilisearch-http/src/index_controller/dump/mod.rs +++ b/meilisearch-http/src/index_controller/dump/mod.rs @@ -9,8 +9,6 @@ use log::{error, info}; use milli::update::{IndexDocumentsMethod, UpdateBuilder, UpdateFormat}; use serde::{Deserialize, Serialize}; use tempfile::TempDir; -use tokio::fs; -use tokio::task::spawn_blocking; use super::update_actor::UpdateActorHandle; use super::uuid_resolver::UuidResolverHandle; @@ -109,6 +107,7 @@ where } async fn perform_dump(&self) -> anyhow::Result<()> { + /* info!("Performing dump."); let dump_dir = self.dump_path.clone(); @@ -144,6 +143,7 @@ where .await??; info!("Created dump in {:?}.", dump_path); + */ Ok(()) } diff --git a/meilisearch-http/src/index_controller/dump/v1.rs b/meilisearch-http/src/index_controller/dump/v1.rs index 02d97e8c6..89b55c51e 100644 --- a/meilisearch-http/src/index_controller/dump/v1.rs +++ b/meilisearch-http/src/index_controller/dump/v1.rs @@ -29,13 +29,11 @@ struct Settings { /// we need to **always** be able to convert the old settings to the settings currently being used impl From for index_controller::Settings { fn from(settings: Settings) -> Self { - if settings.distinct_attribute.flatten().is_some() { - error!("`distinct_attribute` are not yet implemented and thus will be ignored"); - } if settings.synonyms.flatten().is_some() { error!("`synonyms` are not yet implemented and thus will be ignored"); } Self { + distinct_attribute: settings.distinct_attribute, // we need to convert the old `Vec` into a `BTreeSet` displayed_attributes: settings.displayed_attributes.map(|o| o.map(|vec| vec.into_iter().collect())), searchable_attributes: settings.searchable_attributes, @@ -109,7 +107,7 @@ pub fn import_index(size: usize, dump_path: &Path, index_path: &Path) -> anyhow: index.update_documents( UpdateFormat::JsonStream, IndexDocumentsMethod::ReplaceDocuments, - reader, + Some(reader), update_builder, None, )?; diff --git a/meilisearch-http/src/index_controller/dump/v2.rs b/meilisearch-http/src/index_controller/dump/v2.rs index f9303af0d..7b9a56772 100644 --- a/meilisearch-http/src/index_controller/dump/v2.rs +++ b/meilisearch-http/src/index_controller/dump/v2.rs @@ -34,7 +34,7 @@ pub fn import_index(size: usize, dump_path: &Path, index_path: &Path) -> anyhow: index.update_documents( UpdateFormat::JsonStream, IndexDocumentsMethod::ReplaceDocuments, - reader, + Some(reader), update_builder, None, )?; diff --git a/meilisearch-http/src/index_controller/index_actor/actor.rs b/meilisearch-http/src/index_controller/index_actor/actor.rs index 535c405dc..ecf71b62b 100644 --- a/meilisearch-http/src/index_controller/index_actor/actor.rs +++ b/meilisearch-http/src/index_controller/index_actor/actor.rs @@ -312,7 +312,7 @@ impl IndexActor { Ok(()) } - async fn handle_dump(&self, uuid: Uuid, mut path: PathBuf) -> Result<()> { + async fn handle_dump(&self, uuid: Uuid, mut path: PathBuf) -> IndexResult<()> { use tokio::fs::create_dir_all; path.push("indexes"); @@ -340,7 +340,7 @@ impl IndexActor { Ok(()) } - async fn handle_get_stats(&self, uuid: Uuid) -> Result { + async fn handle_get_stats(&self, uuid: Uuid) -> IndexResult { let index = self .store .get(uuid) diff --git a/meilisearch-http/src/index_controller/index_actor/handle_impl.rs b/meilisearch-http/src/index_controller/index_actor/handle_impl.rs index d625a763e..26aa189d0 100644 --- a/meilisearch-http/src/index_controller/index_actor/handle_impl.rs +++ b/meilisearch-http/src/index_controller/index_actor/handle_impl.rs @@ -136,14 +136,14 @@ impl IndexActorHandle for IndexActorHandleImpl { Ok(receiver.await.expect("IndexActor has been killed")?) } - async fn dump(&self, uuid: Uuid, path: PathBuf) -> Result<()> { + async fn dump(&self, uuid: Uuid, path: PathBuf) -> IndexResult<()> { let (ret, receiver) = oneshot::channel(); let msg = IndexMsg::Dump { uuid, path, ret }; - let _ = self.read_sender.send(msg).await; + let _ = self.sender.send(msg).await; Ok(receiver.await.expect("IndexActor has been killed")?) } - async fn get_index_stats(&self, uuid: Uuid) -> Result { + async fn get_index_stats(&self, uuid: Uuid) -> IndexResult { let (ret, receiver) = oneshot::channel(); let msg = IndexMsg::GetStats { uuid, ret }; let _ = self.sender.send(msg).await; diff --git a/meilisearch-http/src/index_controller/index_actor/message.rs b/meilisearch-http/src/index_controller/index_actor/message.rs index 0d88532ca..714a30ecc 100644 --- a/meilisearch-http/src/index_controller/index_actor/message.rs +++ b/meilisearch-http/src/index_controller/index_actor/message.rs @@ -63,7 +63,7 @@ pub enum IndexMsg { Dump { uuid: Uuid, path: PathBuf, - ret: oneshot::Sender>, + ret: oneshot::Sender>, }, GetStats { uuid: Uuid, diff --git a/meilisearch-http/src/index_controller/index_actor/mod.rs b/meilisearch-http/src/index_controller/index_actor/mod.rs index 46105742b..7522acc67 100644 --- a/meilisearch-http/src/index_controller/index_actor/mod.rs +++ b/meilisearch-http/src/index_controller/index_actor/mod.rs @@ -97,6 +97,7 @@ pub trait IndexActorHandle { index_settings: IndexSettings, ) -> IndexResult; async fn snapshot(&self, uuid: Uuid, path: PathBuf) -> IndexResult<()>; + async fn dump(&self, uuid: Uuid, path: PathBuf) -> IndexResult<()>; async fn get_index_stats(&self, uuid: Uuid) -> IndexResult; } @@ -180,4 +181,5 @@ mod test { async fn get_index_stats(&self, uuid: Uuid) -> IndexResult { self.as_ref().get_index_stats(uuid).await } + } } diff --git a/meilisearch-http/src/index_controller/mod.rs b/meilisearch-http/src/index_controller/mod.rs index 7a67265a7..9ed6f10e4 100644 --- a/meilisearch-http/src/index_controller/mod.rs +++ b/meilisearch-http/src/index_controller/mod.rs @@ -5,6 +5,7 @@ use std::time::Duration; use actix_web::web::{Bytes, Payload}; use anyhow::bail; +use chrono::{DateTime, Utc}; use futures::stream::StreamExt; use log::info; use milli::FieldsDistribution; @@ -22,6 +23,8 @@ use uuid_resolver::{UuidError, UuidResolverHandle}; use crate::index::{Checked, Document, SearchQuery, SearchResult, Settings}; use crate::option::Opt; +use self::dump::load_dump; + mod index_actor; mod snapshot; mod dump; diff --git a/meilisearch-http/src/index_controller/update_actor/actor.rs b/meilisearch-http/src/index_controller/update_actor/actor.rs index 7885d0b3b..6789bc6ce 100644 --- a/meilisearch-http/src/index_controller/update_actor/actor.rs +++ b/meilisearch-http/src/index_controller/update_actor/actor.rs @@ -13,7 +13,7 @@ use tokio::sync::mpsc; use uuid::Uuid; use super::{PayloadData, Result, UpdateError, UpdateMsg, UpdateStore, UpdateStoreInfo}; -use crate::index_controller::index_actor::{IndexActorHandle, CONCURRENT_INDEX_MSG}; +use crate::index_controller::{index_actor::{IndexActorHandle, CONCURRENT_INDEX_MSG}}; use crate::index_controller::{UpdateMeta, UpdateStatus}; pub struct UpdateActor { @@ -71,16 +71,14 @@ where Some(Delete { uuid, ret }) => { let _ = ret.send(self.handle_delete(uuid).await); } - Some(Snapshot { uuid, path, ret }) => { - let _ = ret.send(self.handle_snapshot(uuid, path).await); + Some(Snapshot { uuids, path, ret }) => { + let _ = ret.send(self.handle_snapshot(uuids, path).await); } - Some(Dump { uuid, path, ret }) => { - let _ = ret.send(self.handle_dump(uuid, path).await); + Some(Dump { uuids, path, ret }) => { + let _ = ret.send(self.handle_dump(uuids, path).await); } Some(GetInfo { ret }) => { let _ = ret.send(self.handle_get_info().await); - Some(GetSize { uuid, ret }) => { - let _ = ret.send(self.handle_get_size(uuid).await); } None => break, } @@ -199,51 +197,9 @@ where } async fn handle_delete(&self, uuid: Uuid) -> Result<()> { - let store = self.store.delete(uuid).await?; + let store = self.store.clone(); - if let Some(store) = store { - tokio::task::spawn(async move { - let store = get_arc_ownership_blocking(store).await; - tokio::task::spawn_blocking(move || { - store.prepare_for_closing().wait(); - info!("Update store {} was closed.", uuid); - }); - }); - } - - Ok(()) - } - - async fn handle_create(&self, uuid: Uuid) -> Result<()> { - let _ = self.store.get_or_create(uuid).await?; - Ok(()) - } - - Ok(()) - } - - async fn handle_create(&self, uuid: Uuid) -> Result<()> { - let _ = self.store.get_or_create(uuid).await?; - Ok(()) - } - - async fn handle_snapshot(&self, uuid: Uuid, path: PathBuf) -> Result<()> { - let index_handle = self.index_handle.clone(); - if let Some(update_store) = self.store.get(uuid).await? { - tokio::task::spawn_blocking(move || -> anyhow::Result<()> { - // acquire write lock to prevent further writes during snapshot - // the update lock must be acquired BEFORE the write lock to prevent dead lock - let _lock = update_store.update_lock.lock(); - let mut txn = update_store.env.write_txn()?; - - // create db snapshot - update_store.snapshot(&mut txn, &path, uuid)?; - - futures::executor::block_on( - async move { index_handle.snapshot(uuid, path).await }, - )?; - Ok(()) - }) + tokio::task::spawn_blocking(move || store.delete_all(uuid)) .await .map_err(|e| UpdateError::Error(e.into()))? .map_err(|e| UpdateError::Error(e.into()))?; @@ -280,6 +236,35 @@ where Ok(()) } + async fn handle_dump(&self, uuids: HashSet, path: PathBuf) -> Result<()> { + let index_handle = self.index_handle.clone(); + let update_store = self.store.clone(); + tokio::task::spawn_blocking(move || -> anyhow::Result<()> { + update_store.dump(&uuids, &path)?; + + // Perform the snapshot of each index concurently. Only a third of the capabilities of + // the index actor at a time not to put too much pressure on the index actor + let path = &path; + let handle = &index_handle; + + let mut stream = futures::stream::iter(uuids.iter()) + .map(|&uuid| handle.dump(uuid, path.clone())) + .buffer_unordered(CONCURRENT_INDEX_MSG / 3); + + Handle::current().block_on(async { + while let Some(res) = stream.next().await { + res?; + } + Ok(()) + }) + }) + .await + .map_err(|e| UpdateError::Error(e.into()))? + .map_err(|e| UpdateError::Error(e.into()))?; + + Ok(()) + } + async fn handle_get_info(&self) -> Result { let update_store = self.store.clone(); let info = tokio::task::spawn_blocking(move || -> anyhow::Result { @@ -292,42 +277,4 @@ where Ok(info) } - - async fn handle_dump(&self, uuid: Uuid, path: PathBuf) -> Result<()> { - let index_handle = self.index_handle.clone(); - if let Some(update_store) = self.store.get(uuid).await? { - tokio::task::spawn_blocking(move || -> anyhow::Result<()> { - // acquire write lock to prevent further writes during the dump - // the update lock must be acquired BEFORE the write lock to prevent dead lock - let _lock = update_store.update_lock.lock(); - let mut txn = update_store.env.write_txn()?; - - // create db dump - update_store.dump(&mut txn, &path, uuid)?; - - futures::executor::block_on( - async move { index_handle.dump(uuid, path).await }, - )?; - Ok(()) - }) - .await - .map_err(|e| UpdateError::Error(e.into()))? - .map_err(|e| UpdateError::Error(e.into()))?; - } - - Ok(()) - } - - async fn handle_get_size(&self, uuid: Uuid) -> Result { - let size = match self.store.get(uuid).await? { - Some(update_store) => tokio::task::spawn_blocking(move || -> anyhow::Result { - let txn = update_store.env.read_txn()?; - - update_store.get_size(&txn) - }) - .await - .map_err(|e| UpdateError::Error(e.into()))? - .map_err(|e| UpdateError::Error(e.into()))?, - None => 0, - }; } diff --git a/meilisearch-http/src/index_controller/update_actor/handle_impl.rs b/meilisearch-http/src/index_controller/update_actor/handle_impl.rs index 569b896b0..09a242377 100644 --- a/meilisearch-http/src/index_controller/update_actor/handle_impl.rs +++ b/meilisearch-http/src/index_controller/update_actor/handle_impl.rs @@ -78,16 +78,9 @@ where receiver.await.expect("update actor killed.") } - async fn dump(&self, uuid: Uuid, path: PathBuf) -> Result<()> { + async fn dump(&self, uuids: HashSet, path: PathBuf) -> Result<()> { let (ret, receiver) = oneshot::channel(); - let msg = UpdateMsg::Dump { uuid, path, ret }; - let _ = self.sender.send(msg).await; - receiver.await.expect("update actor killed.") - } - - async fn get_size(&self, uuid: Uuid) -> Result { - let (ret, receiver) = oneshot::channel(); - let msg = UpdateMsg::GetSize { uuid, ret }; + let msg = UpdateMsg::Dump { uuids, path, ret }; let _ = self.sender.send(msg).await; receiver.await.expect("update actor killed.") } diff --git a/meilisearch-http/src/index_controller/update_actor/message.rs b/meilisearch-http/src/index_controller/update_actor/message.rs index 3f39c224f..37df2af32 100644 --- a/meilisearch-http/src/index_controller/update_actor/message.rs +++ b/meilisearch-http/src/index_controller/update_actor/message.rs @@ -32,15 +32,11 @@ pub enum UpdateMsg { ret: oneshot::Sender>, }, Dump { - uuid: Uuid, + uuids: HashSet, path: PathBuf, ret: oneshot::Sender>, }, GetInfo { ret: oneshot::Sender>, }, - GetSize { - uuid: Uuid, - ret: oneshot::Sender>, - }, } diff --git a/meilisearch-http/src/index_controller/update_actor/mod.rs b/meilisearch-http/src/index_controller/update_actor/mod.rs index 4d8ab6f20..36390c290 100644 --- a/meilisearch-http/src/index_controller/update_actor/mod.rs +++ b/meilisearch-http/src/index_controller/update_actor/mod.rs @@ -40,11 +40,9 @@ pub trait UpdateActorHandle { async fn get_all_updates_status(&self, uuid: Uuid) -> Result>; async fn update_status(&self, uuid: Uuid, id: u64) -> Result; async fn delete(&self, uuid: Uuid) -> Result<()>; - async fn create(&self, uuid: Uuid) -> Result<()>; - async fn snapshot(&self, uuid: Uuid, path: PathBuf) -> Result<()>; - async fn dump(&self, uuid: Uuid, path: PathBuf) -> Result<()>; + async fn snapshot(&self, uuid: HashSet, path: PathBuf) -> Result<()>; + async fn dump(&self, uuid: HashSet, path: PathBuf) -> Result<()>; async fn get_info(&self) -> Result; - async fn get_size(&self, uuid: Uuid) -> Result; async fn update( &self, meta: UpdateMeta, diff --git a/meilisearch-http/src/index_controller/update_actor/update_store.rs b/meilisearch-http/src/index_controller/update_actor/update_store.rs index 4bc4c8c75..6f698e693 100644 --- a/meilisearch-http/src/index_controller/update_actor/update_store.rs +++ b/meilisearch-http/src/index_controller/update_actor/update_store.rs @@ -499,31 +499,37 @@ impl UpdateStore { Ok(()) } - pub fn dump( - &self, - txn: &mut heed::RwTxn, - path: impl AsRef, - uuid: Uuid, - ) -> anyhow::Result<()> { + pub fn dump(&self, uuids: &HashSet, path: impl AsRef) -> anyhow::Result<()> { + let state_lock = self.state.write(); + state_lock.swap(State::Snapshoting); // TODO: rename the state + + let txn = self.env.write_txn()?; + let update_path = path.as_ref().join("updates"); create_dir_all(&update_path)?; - let mut dump_path = update_path.join(format!("update-{}", uuid)); // acquire write lock to prevent further writes during dump - create_dir_all(&dump_path)?; - dump_path.push("data.mdb"); + create_dir_all(&update_path)?; + let db_path = update_path.join("data.mdb"); + // TODO: everything // create db dump - self.env.copy_to_path(&dump_path, CompactionOption::Enabled)?; + self.env.copy_to_path(&db_path, CompactionOption::Enabled)?; let update_files_path = update_path.join("update_files"); create_dir_all(&update_files_path)?; - for path in self.pending.iter(&txn)? { - let (_, path) = path?; - let name = path.file_name().unwrap(); - let to = update_files_path.join(name); - copy(path, to)?; + let pendings = self.pending_queue.iter(&txn)?.lazily_decode_data(); + + for entry in pendings { + let ((_, uuid, _), pending) = entry?; + if uuids.contains(&uuid) { + if let Some(path) = pending.decode()?.content_path() { + let name = path.file_name().unwrap(); + let to = update_files_path.join(name); + copy(path, to)?; + } + } } Ok(()) @@ -545,25 +551,6 @@ impl UpdateStore { Ok(UpdateStoreInfo { size, processing }) } - - pub fn get_size(&self, txn: &heed::RoTxn) -> anyhow::Result { - let mut size = self.env.size(); - let txn = self.env.read_txn()?; - - for entry in self.pending_queue.iter(&txn)? { - let (_, pending) = entry?; - if let Some(path) = pending.content_path() { - size += File::open(path)?.metadata()?.len(); - } - } - - let processing = match *self.state.read() { - State::Processing(uuid, _) => Some(uuid), - _ => None, - }; - - Ok(UpdateStoreInfo { size, processing }) - } } #[cfg(test)] diff --git a/meilisearch-http/src/index_controller/uuid_resolver/actor.rs b/meilisearch-http/src/index_controller/uuid_resolver/actor.rs index 9c180e4a8..df83ceba9 100644 --- a/meilisearch-http/src/index_controller/uuid_resolver/actor.rs +++ b/meilisearch-http/src/index_controller/uuid_resolver/actor.rs @@ -85,7 +85,7 @@ impl UuidResolverActor { self.store.snapshot(path).await } - async fn handle_dump(&self, path: PathBuf) -> Result> { + async fn handle_dump(&self, path: PathBuf) -> Result> { self.store.dump(path).await } diff --git a/meilisearch-http/src/index_controller/uuid_resolver/handle_impl.rs b/meilisearch-http/src/index_controller/uuid_resolver/handle_impl.rs index e47f9a8e0..d9e9a20fc 100644 --- a/meilisearch-http/src/index_controller/uuid_resolver/handle_impl.rs +++ b/meilisearch-http/src/index_controller/uuid_resolver/handle_impl.rs @@ -78,7 +78,7 @@ impl UuidResolverHandle for UuidResolverHandleImpl { .expect("Uuid resolver actor has been killed")?) } - async fn dump(&self, path: PathBuf) -> Result> { + async fn dump(&self, path: PathBuf) -> Result> { let (ret, receiver) = oneshot::channel(); let msg = UuidResolveMsg::DumpRequest { path, ret }; let _ = self.sender.send(msg).await; diff --git a/meilisearch-http/src/index_controller/uuid_resolver/message.rs b/meilisearch-http/src/index_controller/uuid_resolver/message.rs index 67493c2cd..78f62eea2 100644 --- a/meilisearch-http/src/index_controller/uuid_resolver/message.rs +++ b/meilisearch-http/src/index_controller/uuid_resolver/message.rs @@ -33,7 +33,7 @@ pub enum UuidResolveMsg { }, DumpRequest { path: PathBuf, - ret: oneshot::Sender>>, + ret: oneshot::Sender>>, }, GetSize { ret: oneshot::Sender>, diff --git a/meilisearch-http/src/index_controller/uuid_resolver/mod.rs b/meilisearch-http/src/index_controller/uuid_resolver/mod.rs index b3f70ba2e..aca730db9 100644 --- a/meilisearch-http/src/index_controller/uuid_resolver/mod.rs +++ b/meilisearch-http/src/index_controller/uuid_resolver/mod.rs @@ -32,7 +32,7 @@ pub trait UuidResolverHandle { async fn delete(&self, name: String) -> anyhow::Result; async fn list(&self) -> anyhow::Result>; async fn snapshot(&self, path: PathBuf) -> Result>; - async fn dump(&self, path: PathBuf) -> Result>; + async fn dump(&self, path: PathBuf) -> Result>; async fn get_size(&self) -> Result; } diff --git a/meilisearch-http/src/index_controller/uuid_resolver/store.rs b/meilisearch-http/src/index_controller/uuid_resolver/store.rs index 1d387ddc3..917e0b4a5 100644 --- a/meilisearch-http/src/index_controller/uuid_resolver/store.rs +++ b/meilisearch-http/src/index_controller/uuid_resolver/store.rs @@ -21,7 +21,7 @@ pub trait UuidStore { async fn list(&self) -> Result>; async fn insert(&self, name: String, uuid: Uuid) -> Result<()>; async fn snapshot(&self, path: PathBuf) -> Result>; - async fn dump(&self, path: PathBuf) -> Result>; + async fn dump(&self, path: PathBuf) -> Result>; async fn get_size(&self) -> Result; } @@ -116,7 +116,7 @@ impl HeedUuidStore { // TODO: we should merge this function and the following function for the dump. it's exactly // the same code - pub fn snapshot(&self, mut path: PathBuf) -> Result> { + pub fn snapshot(&self, mut path: PathBuf) -> Result> { let env = self.env.clone(); let db = self.db; // Write transaction to acquire a lock on the database. @@ -138,16 +138,16 @@ impl HeedUuidStore { Ok(entries) } - pub fn dump(&self, mut path: PathBuf) -> Result> { + pub fn dump(&self, mut path: PathBuf) -> Result> { let env = self.env.clone(); let db = self.db; // Write transaction to acquire a lock on the database. let txn = env.write_txn()?; - let mut entries = Vec::new(); + let mut entries = HashSet::new(); for entry in db.iter(&txn)? { let (_, uuid) = entry?; let uuid = Uuid::from_slice(uuid)?; - entries.push(uuid) + entries.insert(uuid); } // only perform dump if there are indexes @@ -192,12 +192,12 @@ impl UuidStore for HeedUuidStore { tokio::task::spawn_blocking(move || this.insert(name, uuid)).await? } - async fn snapshot(&self, path: PathBuf) -> Result> { + async fn snapshot(&self, path: PathBuf) -> Result> { let this = self.clone(); tokio::task::spawn_blocking(move || this.snapshot(path)).await? } - async fn dump(&self, path: PathBuf) -> Result> { + async fn dump(&self, path: PathBuf) -> Result> { let this = self.clone(); tokio::task::spawn_blocking(move || this.dump(path)).await? } diff --git a/meilisearch-http/src/routes/index.rs b/meilisearch-http/src/routes/index.rs index 1afc01806..62717c90d 100644 --- a/meilisearch-http/src/routes/index.rs +++ b/meilisearch-http/src/routes/index.rs @@ -1,7 +1,7 @@ use actix_web::{delete, get, post, put}; use actix_web::{web, HttpResponse}; -use chrono::DateTime; -use serde::Deserialize; +use chrono::{DateTime, Utc}; +use serde::{Serialize, Deserialize}; use crate::error::ResponseError; use crate::helpers::Authentication;