improve document deletion returned meta

returns both the remaining number of documents and the number of deleted
documents.
This commit is contained in:
Marin Postma 2021-11-09 20:19:49 +01:00
parent 8dff08d772
commit 721fc294be

View File

@ -6,6 +6,7 @@ use fst::IntoStreamer;
use heed::types::ByteSlice; use heed::types::ByteSlice;
use heed::{BytesDecode, BytesEncode}; use heed::{BytesDecode, BytesEncode};
use roaring::RoaringBitmap; use roaring::RoaringBitmap;
use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use super::ClearDocuments; use super::ClearDocuments;
@ -25,6 +26,12 @@ pub struct DeleteDocuments<'t, 'u, 'i> {
update_id: u64, update_id: u64,
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DocumentDeletionResult {
pub deleted_documents: u64,
pub remaining_documents: u64,
}
impl<'t, 'u, 'i> DeleteDocuments<'t, 'u, 'i> { impl<'t, 'u, 'i> DeleteDocuments<'t, 'u, 'i> {
pub fn new( pub fn new(
wtxn: &'t mut heed::RwTxn<'i, 'u>, wtxn: &'t mut heed::RwTxn<'i, 'u>,
@ -56,26 +63,34 @@ impl<'t, 'u, 'i> DeleteDocuments<'t, 'u, 'i> {
Some(docid) Some(docid)
} }
pub fn execute(self) -> Result<u64> { pub fn execute(self) -> Result<DocumentDeletionResult> {
self.index.set_updated_at(self.wtxn, &Utc::now())?; self.index.set_updated_at(self.wtxn, &Utc::now())?;
// We retrieve the current documents ids that are in the database. // We retrieve the current documents ids that are in the database.
let mut documents_ids = self.index.documents_ids(self.wtxn)?; let mut documents_ids = self.index.documents_ids(self.wtxn)?;
let current_documents_ids_len = documents_ids.len();
// We can and must stop removing documents in a database that is empty. // We can and must stop removing documents in a database that is empty.
if documents_ids.is_empty() { if documents_ids.is_empty() {
return Ok(0); return Ok(DocumentDeletionResult {
deleted_documents: 0,
remaining_documents: current_documents_ids_len,
});
} }
// We remove the documents ids that we want to delete // We remove the documents ids that we want to delete
// from the documents in the database and write them back. // from the documents in the database and write them back.
let current_documents_ids_len = documents_ids.len();
documents_ids -= &self.documents_ids; documents_ids -= &self.documents_ids;
self.index.put_documents_ids(self.wtxn, &documents_ids)?; self.index.put_documents_ids(self.wtxn, &documents_ids)?;
// We can execute a ClearDocuments operation when the number of documents // We can execute a ClearDocuments operation when the number of documents
// to delete is exactly the number of documents in the database. // to delete is exactly the number of documents in the database.
if current_documents_ids_len == self.documents_ids.len() { if current_documents_ids_len == self.documents_ids.len() {
return ClearDocuments::new(self.wtxn, self.index, self.update_id).execute(); let remaining_documents =
ClearDocuments::new(self.wtxn, self.index, self.update_id).execute()?;
return Ok(DocumentDeletionResult {
deleted_documents: current_documents_ids_len,
remaining_documents,
});
} }
let fields_ids_map = self.index.fields_ids_map(self.wtxn)?; let fields_ids_map = self.index.fields_ids_map(self.wtxn)?;
@ -86,11 +101,11 @@ impl<'t, 'u, 'i> DeleteDocuments<'t, 'u, 'i> {
} }
})?; })?;
// If we can't find the id of the primary key it means that the database // Since we already checked if the DB was empty, if we can't find the primary key, then
// is empty and it should be safe to return that we deleted 0 documents. // something is wrong, and we must return an error.
let id_field = match fields_ids_map.id(primary_key) { let id_field = match fields_ids_map.id(primary_key) {
Some(field) => field, Some(field) => field,
None => return Ok(0), None => return Err(UserError::MissingPrimaryKey.into()),
}; };
let Index { let Index {
@ -439,7 +454,10 @@ impl<'t, 'u, 'i> DeleteDocuments<'t, 'u, 'i> {
)?; )?;
} }
Ok(self.documents_ids.len()) Ok(DocumentDeletionResult {
deleted_documents: self.documents_ids.len(),
remaining_documents: documents_ids.len(),
})
} }
} }