mirror of
https://github.com/stalwartlabs/mail-server.git
synced 2025-10-13 22:15:47 +08:00
78 lines
2.3 KiB
Rust
78 lines
2.3 KiB
Rust
/*
|
|
* SPDX-FileCopyrightText: 2020 Stalwart Labs Ltd <hello@stalw.art>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL
|
|
*/
|
|
|
|
use std::sync::Arc;
|
|
|
|
use common::{Server, Threads};
|
|
use jmap_proto::types::{collection::Collection, property::Property};
|
|
use std::future::Future;
|
|
use trc::AddContext;
|
|
|
|
pub trait ThreadCache: Sync + Send {
|
|
fn get_cached_thread_ids(
|
|
&self,
|
|
account_id: u32,
|
|
message_ids: impl Iterator<Item = u32> + Send,
|
|
) -> impl Future<Output = trc::Result<Vec<(u32, u32)>>> + Send;
|
|
}
|
|
|
|
impl ThreadCache for Server {
|
|
async fn get_cached_thread_ids(
|
|
&self,
|
|
account_id: u32,
|
|
message_ids: impl Iterator<Item = u32> + Send,
|
|
) -> trc::Result<Vec<(u32, u32)>> {
|
|
// Obtain current state
|
|
let modseq = self
|
|
.core
|
|
.storage
|
|
.data
|
|
.get_last_change_id(account_id, Collection::Thread)
|
|
.await
|
|
.caused_by(trc::location!())?;
|
|
|
|
// Lock the cache
|
|
let thread_cache = if let Some(thread_cache) =
|
|
self.inner.cache.threads.get(&account_id).and_then(|t| {
|
|
if t.modseq.unwrap_or(0) >= modseq.unwrap_or(0) {
|
|
Some(t)
|
|
} else {
|
|
None
|
|
}
|
|
}) {
|
|
thread_cache
|
|
} else {
|
|
let thread_cache = Arc::new(Threads {
|
|
threads: self
|
|
.get_properties::<u32, _, _>(
|
|
account_id,
|
|
Collection::Email,
|
|
&(),
|
|
Property::ThreadId,
|
|
)
|
|
.await?
|
|
.into_iter()
|
|
.collect(),
|
|
modseq,
|
|
});
|
|
self.inner
|
|
.cache
|
|
.threads
|
|
.insert(account_id, thread_cache.clone());
|
|
thread_cache
|
|
};
|
|
|
|
// Obtain threadIds for matching messages
|
|
let mut thread_ids = Vec::with_capacity(message_ids.size_hint().0);
|
|
for document_id in message_ids {
|
|
if let Some(thread_id) = thread_cache.threads.get(&document_id) {
|
|
thread_ids.push((document_id, *thread_id));
|
|
}
|
|
}
|
|
|
|
Ok(thread_ids)
|
|
}
|
|
}
|