Skip to content

Commit e2b3178

Browse files
committed
refactor(indexeddb): add migrations and types for media content size index
Signed-off-by: Michael Goldenberg <[email protected]>
1 parent d47afb1 commit e2b3178

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

crates/matrix-sdk-indexeddb/src/event_cache_store/migrations.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ pub mod v1 {
133133
pub const MEDIA_RETENTION_POLICY_KEY: &str = "media_retention_policy";
134134
pub const MEDIA: &str = "media";
135135
pub const MEDIA_KEY_PATH: &str = "id";
136+
pub const MEDIA_CONTENT_SIZE: &str = "media_content_size";
137+
pub const MEDIA_CONTENT_SIZE_KEY_PATH: &str = "content_size";
136138
}
137139

138140
/// Create all object stores and indices for v1 database
@@ -225,10 +227,15 @@ pub mod v1 {
225227
/// Create an object store for tracking information about media.
226228
///
227229
/// * Primary Key - `id`
230+
/// * Index - `content_size` - tracks the size of the media content and
231+
/// whether to ignore the [`MediaRetentionPolicy`][1]
232+
///
233+
/// [1]: matrix_sdk_base::event_cache::store::media::MediaRetentionPolicy
228234
fn create_media_object_store(db: &IdbDatabase) -> Result<(), DomException> {
229235
let mut object_store_params = IdbObjectStoreParameters::new();
230236
object_store_params.key_path(Some(&keys::MEDIA_KEY_PATH.into()));
231-
let _ = db.create_object_store_with_params(keys::MEDIA, &object_store_params)?;
237+
let media = db.create_object_store_with_params(keys::MEDIA, &object_store_params)?;
238+
media.create_index(keys::MEDIA_CONTENT_SIZE, &keys::MEDIA_CONTENT_SIZE_KEY_PATH.into())?;
232239
Ok(())
233240
}
234241
}

crates/matrix-sdk-indexeddb/src/event_cache_store/serializer/types.rs

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ use thiserror::Error;
4242
use crate::{
4343
event_cache_store::{
4444
migrations::current::keys,
45-
serializer::traits::{
46-
Indexed, IndexedKey, IndexedKeyBounds, IndexedKeyComponentBounds,
47-
IndexedPrefixKeyBounds, IndexedPrefixKeyComponentBounds,
45+
serializer::{
46+
foreign::ignore_media_retention_policy,
47+
traits::{
48+
Indexed, IndexedKey, IndexedKeyBounds, IndexedKeyComponentBounds,
49+
IndexedPrefixKeyBounds, IndexedPrefixKeyComponentBounds,
50+
},
4851
},
4952
types::{Chunk, Event, Gap, Lease, Media, Position},
5053
},
@@ -290,6 +293,10 @@ pub type IndexedMediaMetadata = MaybeEncrypted;
290293
/// A (possibly) encrypted representation of [`Media::content`]
291294
pub type IndexedMediaContent = Vec<u8>;
292295

296+
/// A representation of the size in bytes of the [`IndexedMediaContent`] which
297+
/// is suitable for use in an IndexedDB key
298+
pub type IndexedMediaContentSize = usize;
299+
293300
/// Represents the [`LEASES`][1] object store.
294301
///
295302
/// [1]: crate::event_cache_store::migrations::v1::create_lease_object_store
@@ -900,6 +907,9 @@ impl IndexedKey<MediaRetentionPolicy> for IndexedCoreIdKey {
900907
pub struct IndexedMedia {
901908
/// The primary key of the object store
902909
pub id: IndexedMediaIdKey,
910+
/// The size (in bytes) of the media content and whether to ignore the
911+
/// [`MediaRetentionPolicy`]
912+
pub content_size: IndexedMediaContentSizeKey,
903913
/// The (possibly) encrypted metadata - i.e., [`MediaMetadata`][1]
904914
///
905915
/// [1]: crate::event_cache_store::types::MediaMetadata
@@ -934,6 +944,10 @@ impl Indexed for Media {
934944
&self.metadata.request_parameters,
935945
serializer,
936946
),
947+
content_size: IndexedMediaContentSizeKey::encode(
948+
(self.metadata.ignore_policy, content.len()),
949+
serializer,
950+
),
937951
metadata: serializer.maybe_encrypt_value(&self.metadata)?,
938952
content,
939953
})
@@ -966,3 +980,66 @@ impl IndexedKey<Media> for IndexedMediaIdKey {
966980
Self(serializer.encode_key_as_string(keys::MEDIA, components.unique_key()))
967981
}
968982
}
983+
984+
/// The value associated with the [`content_size`](IndexedMedia::content_size)
985+
/// index of the [`MEDIA`][1] object store, which is constructed from:
986+
///
987+
/// - The value of [`IgnoreMediaRetentionPolicy`]
988+
/// - The size in bytes of the associated [`IndexedMedia::content`]
989+
///
990+
/// [1]: crate::event_cache_store::migrations::v1::create_media_object_store
991+
#[derive(Debug, Serialize, Deserialize)]
992+
pub struct IndexedMediaContentSizeKey(
993+
#[serde(with = "ignore_media_retention_policy")] IgnoreMediaRetentionPolicy,
994+
IndexedMediaContentSize,
995+
);
996+
997+
impl IndexedMediaContentSizeKey {
998+
/// Returns whether the associated [`IndexedMedia`] record should ignore the
999+
/// global [`MediaRetentionPolicy`]
1000+
pub fn ignore_policy(&self) -> bool {
1001+
self.0.is_yes()
1002+
}
1003+
1004+
/// Returns the size in bytes of the associated [`IndexedMedia::content`]
1005+
pub fn content_size(&self) -> usize {
1006+
self.1
1007+
}
1008+
}
1009+
1010+
impl IndexedKey<Media> for IndexedMediaContentSizeKey {
1011+
type KeyComponents<'a> = (IgnoreMediaRetentionPolicy, IndexedMediaContentSize);
1012+
1013+
fn encode(
1014+
(ignore_policy, content_size): Self::KeyComponents<'_>,
1015+
_: &IndexeddbSerializer,
1016+
) -> Self {
1017+
Self(ignore_policy, content_size)
1018+
}
1019+
}
1020+
1021+
impl IndexedKeyComponentBounds<Media> for IndexedMediaContentSizeKey {
1022+
fn lower_key_components() -> Self::KeyComponents<'static> {
1023+
Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::No)
1024+
}
1025+
1026+
fn upper_key_components() -> Self::KeyComponents<'static> {
1027+
Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::Yes)
1028+
}
1029+
}
1030+
1031+
impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
1032+
for IndexedMediaContentSizeKey
1033+
{
1034+
fn lower_key_components_with_prefix(
1035+
prefix: IgnoreMediaRetentionPolicy,
1036+
) -> Self::KeyComponents<'a> {
1037+
(prefix, IndexedMediaContentSize::MIN)
1038+
}
1039+
1040+
fn upper_key_components_with_prefix(
1041+
prefix: IgnoreMediaRetentionPolicy,
1042+
) -> Self::KeyComponents<'a> {
1043+
(prefix, IndexedMediaContentSize::MAX)
1044+
}
1045+
}

0 commit comments

Comments
 (0)