Database schema optimization - part 11

This commit is contained in:
mdecimus
2025-11-12 19:09:06 +01:00
parent 3e181ae467
commit 8bbcb999d1
40 changed files with 541 additions and 493 deletions

View File

@@ -18,7 +18,7 @@ use crate::{
use common::{Server, auth::ResourceToken, storage::index::ObjectIndexBuilder};
use mail_parser::{HeaderName, HeaderValue, parsers::fields::thread::thread_name};
use store::write::{
BatchBuilder, IndexPropertyClass, SearchIndex, TaskQueueClass, ValueClass, now,
BatchBuilder, IndexPropertyClass, SearchIndex, TaskEpoch, TaskQueueClass, ValueClass,
};
use trc::AddContext;
use types::{
@@ -179,7 +179,6 @@ impl EmailCopy for Server {
.log_container_insert(SyncCollection::Thread);
document_id
};
let due = now();
batch
.with_collection(Collection::Email)
.with_document(document_id)
@@ -201,7 +200,7 @@ impl EmailCopy for Server {
.set(
ValueClass::TaskQueue(TaskQueueClass::UpdateIndex {
index: SearchIndex::Email,
due,
due: TaskEpoch::now(),
is_insert: true,
}),
vec![],
@@ -210,7 +209,9 @@ impl EmailCopy for Server {
// Merge threads if necessary
if let Some(merge_threads) = MergeThreadIds::new(thread_result).serialize() {
batch.set(
ValueClass::TaskQueue(TaskQueueClass::MergeThreads { due }),
ValueClass::TaskQueue(TaskQueueClass::MergeThreads {
due: TaskEpoch::now(),
}),
merge_threads,
);
}

View File

@@ -12,7 +12,7 @@ use groupware::calendar::storage::ItipAutoExpunge;
use std::future::Future;
use store::rand::prelude::SliceRandom;
use store::write::key::DeserializeBigEndian;
use store::write::{IndexPropertyClass, SearchIndex, TaskQueueClass, now};
use store::write::{IndexPropertyClass, SearchIndex, TaskEpoch, TaskQueueClass, now};
use store::{IterateParams, SerializeInfallible, U32_LEN, U64_LEN, ValueKey};
use store::{
roaring::RoaringBitmap,
@@ -54,7 +54,6 @@ impl EmailDeletion for Server {
batch: &mut BatchBuilder,
document_ids: RoaringBitmap,
) -> trc::Result<RoaringBitmap> {
let due = now();
let mut deleted_ids = RoaringBitmap::new();
batch
.with_account_id(account_id)
@@ -81,7 +80,7 @@ impl EmailDeletion for Server {
.set(
ValueClass::TaskQueue(TaskQueueClass::UpdateIndex {
index: SearchIndex::Email,
due,
due: TaskEpoch::now(),
is_insert: false,
}),
0u64.serialize(),
@@ -359,113 +358,4 @@ impl EmailDeletion for Server {
Ok(())
}
/*async fn emails_purge_tombstoned(&self, account_id: u32) -> trc::Result<()> {
// Obtain tombstoned messages
let tombstoned_ids = self
.core
.storage
.data
.get_bitmap(BitmapKey {
account_id,
collection: Collection::Email.into(),
class: BitmapClass::Tag {
field: EmailField::MailboxIds.into(),
value: TagValue::Id(TOMBSTONE_ID),
},
document_id: 0,
})
.await?
.unwrap_or_default();
if tombstoned_ids.is_empty() {
return Ok(());
}
trc::event!(
Purge(trc::PurgeEvent::TombstoneCleanup),
AccountId = account_id,
Total = tombstoned_ids.len(),
);
// Delete full-text index
self.core
.storage
.fts
.remove(account_id, Collection::Email, &tombstoned_ids)
.await?;
// Obtain tenant id
let tenant_id = self
.get_access_token(account_id)
.await
.caused_by(trc::location!())?
.tenant
.map(|t| t.id);
// Delete messages
let mut batch = BatchBuilder::new();
batch.with_account_id(account_id);
for document_id in tombstoned_ids {
batch
.with_collection(Collection::Email)
.delete_document(document_id)
.clear(EmailField::Archive)
.untag(EmailField::MailboxIds, TagValue::Id(TOMBSTONE_ID));
// Remove message metadata
if let Some(metadata_) = self
.core
.storage
.data
.get_value::<Archive<AlignedBytes>>(ValueKey {
account_id,
collection: Collection::Email.into(),
document_id,
class: ValueClass::Property(EmailField::Metadata.into()),
})
.await?
{
let metadata = metadata_
.unarchive::<MessageMetadata>()
.caused_by(trc::location!())?;
// SPDX-SnippetBegin
// SPDX-FileCopyrightText: 2020 Stalwart Labs LLC <hello@stalw.art>
// SPDX-License-Identifier: LicenseRef-SEL
// Hold blob for undeletion
#[cfg(feature = "enterprise")]
self.core.hold_undelete(
&mut batch,
Collection::Email.into(),
&BlobHash::from(&metadata.blob_hash),
u32::from(metadata.size) as usize,
);
// SPDX-SnippetEnd
// Delete message
metadata
.index(&mut batch, account_id, tenant_id, false)
.caused_by(trc::location!())?;
// Commit point
batch.commit_point();
} else {
trc::event!(
Purge(trc::PurgeEvent::Error),
AccountId = account_id,
DocumentId = document_id,
Reason = "Failed to fetch message metadata.",
CausedBy = trc::location!(),
);
}
}
self.commit_batch(batch).await?;
Ok(())
}*/
}

View File

@@ -33,7 +33,7 @@ use store::{
IndexKeyPrefix, IterateParams, U32_LEN, ValueKey,
ahash::{AHashMap, AHashSet},
write::{
BatchBuilder, IndexPropertyClass, SearchIndex, TaskQueueClass, ValueClass,
BatchBuilder, IndexPropertyClass, SearchIndex, TaskEpoch, TaskQueueClass, ValueClass,
key::DeserializeBigEndian, now,
},
};
@@ -623,7 +623,6 @@ impl EmailIngest for Server {
.log_container_insert(SyncCollection::Thread);
document_id
};
let due = now();
batch
.with_collection(Collection::Email)
@@ -651,7 +650,7 @@ impl EmailIngest for Server {
.set(
ValueClass::TaskQueue(TaskQueueClass::UpdateIndex {
index: SearchIndex::Email,
due,
due: TaskEpoch::now(),
is_insert: true,
}),
vec![],
@@ -660,7 +659,9 @@ impl EmailIngest for Server {
// Merge threads if necessary
if let Some(merge_threads) = MergeThreadIds::new(thread_result).serialize() {
batch.set(
ValueClass::TaskQueue(TaskQueueClass::MergeThreads { due }),
ValueClass::TaskQueue(TaskQueueClass::MergeThreads {
due: TaskEpoch::now(),
}),
merge_threads,
);
}
@@ -668,7 +669,10 @@ impl EmailIngest for Server {
// Request spam training
if let Some(learn_spam) = train_spam {
batch.set(
ValueClass::TaskQueue(TaskQueueClass::BayesTrain { due, learn_spam }),
ValueClass::TaskQueue(TaskQueueClass::BayesTrain {
due: TaskEpoch::now(),
learn_spam,
}),
vec![],
);
}