DAV storage methods

This commit is contained in:
mdecimus
2025-03-06 18:35:46 +01:00
parent 3554dea4cb
commit eadd36f4cb
35 changed files with 1289 additions and 206 deletions

View File

@@ -254,3 +254,25 @@ impl CredentialsUsername for Credentials<String> {
}
}
}
pub trait AsTenantId {
fn tenant_id(&self) -> Option<u32>;
}
impl AsTenantId for Option<u32> {
fn tenant_id(&self) -> Option<u32> {
*self
}
}
impl AsTenantId for AccessToken {
fn tenant_id(&self) -> Option<u32> {
self.tenant.map(|t| t.id)
}
}
impl AsTenantId for ResourceToken {
fn tenant_id(&self) -> Option<u32> {
self.tenant.map(|t| t.id)
}
}

View File

@@ -9,14 +9,22 @@ use utils::config::Config;
#[derive(Debug, Clone, Default)]
pub struct DavConfig {
pub max_request_size: usize,
pub dead_property_size: Option<usize>,
pub live_property_size: usize,
}
impl DavConfig {
pub fn parse(config: &mut Config) -> Self {
DavConfig {
max_request_size: config
.property("dav.limits.request-size")
.property("dav.limits.size.request")
.unwrap_or(25 * 1024 * 1024),
dead_property_size: config
.property_or_default::<Option<usize>>("dav.limits.size.dead-property", "1024")
.unwrap_or(Some(1024)),
live_property_size: config
.property("dav.limits.size.live-property")
.unwrap_or(250),
}
}
}

View File

@@ -125,6 +125,12 @@ impl Caches {
MB_10,
(std::mem::size_of::<Threads>() + (500 * std::mem::size_of::<u64>())) as u64,
),
files: Cache::from_config(
config,
"file",
MB_10,
(std::mem::size_of::<Threads>() + (500 * std::mem::size_of::<u64>())) as u64,
),
bayes: CacheWithTtl::from_config(
config,
"bayes",

View File

@@ -45,6 +45,7 @@ use rustls::sign::CertifiedKey;
use tokio::sync::{Notify, Semaphore, mpsc};
use tokio_rustls::TlsConnector;
use utils::{
bimap::IdBimap,
cache::{Cache, CacheItemWeight, CacheWithTtl},
snowflake::SnowflakeIdGenerator,
};
@@ -143,6 +144,7 @@ pub struct Caches {
pub account: Cache<AccountId, Arc<Account>>,
pub mailbox: Cache<MailboxId, Arc<MailboxState>>,
pub threads: Cache<u32, Arc<Threads>>,
pub files: Cache<u32, Arc<Files>>,
pub bayes: CacheWithTtl<TokenHash, Weights>,
@@ -244,6 +246,15 @@ pub struct Threads {
pub modseq: Option<u64>,
}
pub struct NameWrapper(pub String);
#[derive(Debug, Default)]
pub struct Files {
pub files: IdBimap,
pub size: u64,
pub modseq: Option<u64>,
}
#[derive(Clone, Default)]
pub struct Core {
pub storage: Storage,
@@ -297,6 +308,12 @@ impl CacheItemWeight for HttpAuthCache {
}
}
impl CacheItemWeight for Files {
fn weight(&self) -> u64 {
self.size
}
}
impl MailboxState {
pub fn calculate_weight(&self) -> u64 {
std::mem::size_of::<MailboxState>() as u64
@@ -412,6 +429,7 @@ impl Default for Caches {
account: Cache::new(1024, 10 * 1024 * 1024),
mailbox: Cache::new(1024, 10 * 1024 * 1024),
threads: Cache::new(1024, 10 * 1024 * 1024),
files: Cache::new(1024, 10 * 1024 * 1024),
bayes: CacheWithTtl::new(1024, 10 * 1024 * 1024),
dns_rbl: CacheWithTtl::new(1024, 10 * 1024 * 1024),
dns_txt: CacheWithTtl::new(1024, 10 * 1024 * 1024),

View File

@@ -142,6 +142,14 @@ impl Server {
}
impl ExpandedFolders {
pub fn len(&self) -> usize {
self.names.len()
}
pub fn is_empty(&self) -> bool {
self.names.is_empty()
}
pub fn format<T>(mut self, formatter: T) -> Self
where
T: Fn(u32, &str) -> Option<String>,

View File

@@ -9,10 +9,13 @@ use std::{borrow::Cow, collections::HashSet, fmt::Debug};
use store::{
Serialize, SerializeInfallible,
write::{
Archiver, BatchBuilder, BitmapClass, DirectoryClass, IntoOperations, Operation, ValueOp,
assert::HashedValue,
Archiver, BatchBuilder, BitmapClass, BlobOp, DirectoryClass, IntoOperations, Operation,
ValueOp, assert::HashedValue,
},
};
use utils::BlobHash;
use crate::auth::AsTenantId;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum IndexValue<'x> {
@@ -21,6 +24,7 @@ pub enum IndexValue<'x> {
U64 { field: u8, value: Option<u64> },
U32List { field: u8, value: &'x [u32] },
Tag { field: u8, is_set: bool },
Blob { value: BlobHash },
Quota { used: u32 },
Acl { value: &'x [AclGrant] },
}
@@ -91,14 +95,10 @@ impl<T: IndexableObject> ObjectIndexBuilder<T> {
self.current.as_ref()
}
pub fn with_tenant_id(mut self, tenant_id: Option<u32>) -> Self {
self.tenant_id = tenant_id;
pub fn with_tenant_id(mut self, tenant: &impl AsTenantId) -> Self {
self.tenant_id = tenant.tenant_id();
self
}
pub fn set_tenant_id(&mut self, tenant_id: u32) {
self.tenant_id = tenant_id.into();
}
}
impl<T: IndexableObject> IntoOperations for ObjectIndexBuilder<T> {
@@ -182,6 +182,13 @@ fn build_batch<T: IndexableObject>(
});
}
}
IndexValue::Blob { value } => {
if set {
batch.set(BlobOp::Link { hash: value }, vec![]);
} else {
batch.clear(BlobOp::Link { hash: value });
}
}
IndexValue::Acl { value } => {
for item in value {
batch.ops.push(Operation::acl(
@@ -354,6 +361,10 @@ fn merge_batch<T: IndexableObject>(
});
}
}
(IndexValue::Blob { value: old_hash }, IndexValue::Blob { value: new_hash }) => {
batch.clear(BlobOp::Link { hash: old_hash });
batch.set(BlobOp::Link { hash: new_hash }, vec![]);
}
(IndexValue::Acl { value: old_acl }, IndexValue::Acl { value: new_acl }) => {
match (!old_acl.is_empty(), !new_acl.is_empty()) {
(true, true) => {