Skip to content

Commit f29be69

Browse files
committed
refactor(indexeddb): add migrations and types for media retention metadata index
Signed-off-by: Michael Goldenberg <[email protected]>
1 parent e7fe986 commit f29be69

File tree

2 files changed

+88
-2
lines changed

2 files changed

+88
-2
lines changed

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ pub mod v1 {
139139
pub const MEDIA_CONTENT_SIZE_KEY_PATH: &str = "content_size";
140140
pub const MEDIA_LAST_ACCESS: &str = "media_last_access";
141141
pub const MEDIA_LAST_ACCESS_KEY_PATH: &str = "last_access";
142+
pub const MEDIA_RETENTION_METADATA: &str = "media_retention_metadata";
143+
pub const MEDIA_RETENTION_METADATA_KEY_PATH: &str = "retention_metadata";
142144
}
143145

144146
/// Create all object stores and indices for v1 database
@@ -237,6 +239,8 @@ pub mod v1 {
237239
/// whether to ignore the [`MediaRetentionPolicy`][2]
238240
/// * Index - `last_access` - tracks the last time the associated media was
239241
/// accessed
242+
/// * Index - `retention_metadata` - tracks all retention metadata - i.e.,
243+
/// joins `content_size` and `last_access`
240244
///
241245
/// [1]: ruma::events::room::MediaSource
242246
/// [2]: matrix_sdk_base::event_cache::store::media::MediaRetentionPolicy
@@ -247,6 +251,10 @@ pub mod v1 {
247251
media.create_index(keys::MEDIA_SOURCE, &keys::MEDIA_SOURCE_KEY_PATH.into())?;
248252
media.create_index(keys::MEDIA_CONTENT_SIZE, &keys::MEDIA_CONTENT_SIZE_KEY_PATH.into())?;
249253
media.create_index(keys::MEDIA_LAST_ACCESS, &keys::MEDIA_LAST_ACCESS_KEY_PATH.into())?;
254+
media.create_index(
255+
keys::MEDIA_RETENTION_METADATA,
256+
&keys::MEDIA_RETENTION_METADATA_KEY_PATH.into(),
257+
)?;
250258
Ok(())
251259
}
252260
}

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

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,23 @@ static INDEXED_KEY_UPPER_EVENT_POSITION: LazyLock<Position> = LazyLock::new(|| P
154154
index: INDEXED_KEY_UPPER_EVENT_INDEX,
155155
});
156156

157+
/// An [`IndexedMediaContentSize`] set to it's minimal value - i.e., `0`.
158+
///
159+
/// This value is useful for constructing a key range over all keys which
160+
/// contain [`IndexedMediaContentSize`] values when used in conjunction with
161+
/// [`INDEXED_KEY_UPPER_MEDIA_CONTENT_SIZE`].
162+
const INDEXED_KEY_LOWER_MEDIA_CONTENT_SIZE: IndexedMediaContentSize = 0;
163+
164+
/// An [`IndexedMediaContentSize`] set to [`js_sys::Number::MAX_SAFE_INTEGER`].
165+
/// Note that this restricts the size of [`IndexedMedia::content`], which
166+
/// ultimately restricts the size of [`Media::content`].
167+
///
168+
/// This value is useful for constructing a key range over all keys which
169+
/// contain [`IndexedMediaContentSize`] values when used in conjunction with
170+
/// [`INDEXED_KEY_LOWER_MEDIA_CONTENT_SIZE`].
171+
const INDEXED_KEY_UPPER_MEDIA_CONTENT_SIZE: IndexedMediaContentSize =
172+
js_sys::Number::MAX_SAFE_INTEGER as usize;
173+
157174
/// The minimum possible [`Duration`].
158175
///
159176
/// This value is useful for constructing a key range over all keys which
@@ -939,6 +956,9 @@ pub struct IndexedMedia {
939956
/// The last time the media was accessed and whether to ignore the
940957
/// [`MediaRetentionPolicy`]
941958
pub last_access: IndexedMediaLastAccessKey,
959+
/// The last the media was accessed, the size (in bytes) of the media
960+
/// content, and whether to ignore the [`MediaRetentionPolicy`]
961+
pub retention_metadata: IndexedMediaRetentionMetadataKey,
942962
/// The (possibly) encrypted metadata - i.e., [`MediaMetadata`][1]
943963
///
944964
/// [1]: crate::event_cache_store::types::MediaMetadata
@@ -985,6 +1005,10 @@ impl Indexed for Media {
9851005
(self.metadata.ignore_policy, self.metadata.last_access),
9861006
serializer,
9871007
),
1008+
retention_metadata: IndexedMediaRetentionMetadataKey::encode(
1009+
(self.metadata.ignore_policy, self.metadata.last_access, content.len()),
1010+
serializer,
1011+
),
9881012
metadata: serializer.maybe_encrypt_value(&self.metadata)?,
9891013
content,
9901014
})
@@ -1088,13 +1112,13 @@ impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
10881112
fn lower_key_components_with_prefix(
10891113
prefix: IgnoreMediaRetentionPolicy,
10901114
) -> Self::KeyComponents<'a> {
1091-
(prefix, IndexedMediaContentSize::MIN)
1115+
(prefix, INDEXED_KEY_LOWER_MEDIA_CONTENT_SIZE)
10921116
}
10931117

10941118
fn upper_key_components_with_prefix(
10951119
prefix: IgnoreMediaRetentionPolicy,
10961120
) -> Self::KeyComponents<'a> {
1097-
(prefix, IndexedMediaContentSize::MAX)
1121+
(prefix, INDEXED_KEY_UPPER_MEDIA_CONTENT_SIZE)
10981122
}
10991123
}
11001124

@@ -1148,3 +1172,57 @@ impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
11481172
(prefix, INDEXED_KEY_UPPER_DURATION_SECONDS)
11491173
}
11501174
}
1175+
1176+
/// The value associated with the
1177+
/// [`retention_metadata`](IndexedMedia::retention_metadata) index of the
1178+
/// [`MEDIA`][1] object store, which is constructed from:
1179+
///
1180+
/// - The value of [`IgnoreMediaRetentionPolicy`]
1181+
/// - The last time the associated [`IndexedMedia`] was accessed (in seconds
1182+
/// since the Unix Epoch)
1183+
/// - The size in bytes of the associated [`IndexedMedia::content`]
1184+
///
1185+
/// [1]: crate::event_cache_store::migrations::v1::create_media_object_store
1186+
#[derive(Debug, Serialize, Deserialize)]
1187+
pub struct IndexedMediaRetentionMetadataKey(
1188+
#[serde(with = "ignore_media_retention_policy")] IgnoreMediaRetentionPolicy,
1189+
IndexedSecondsSinceUnixEpoch,
1190+
IndexedMediaContentSize,
1191+
);
1192+
1193+
impl IndexedKey<Media> for IndexedMediaRetentionMetadataKey {
1194+
type KeyComponents<'a> = (IgnoreMediaRetentionPolicy, Duration, IndexedMediaContentSize);
1195+
1196+
fn encode(
1197+
(ignore_policy, last_access, content_size): Self::KeyComponents<'_>,
1198+
_: &IndexeddbSerializer,
1199+
) -> Self {
1200+
Self(ignore_policy, last_access.as_secs(), content_size)
1201+
}
1202+
}
1203+
1204+
impl IndexedKeyComponentBounds<Media> for IndexedMediaRetentionMetadataKey {
1205+
fn lower_key_components() -> Self::KeyComponents<'static> {
1206+
Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::No)
1207+
}
1208+
1209+
fn upper_key_components() -> Self::KeyComponents<'static> {
1210+
Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::Yes)
1211+
}
1212+
}
1213+
1214+
impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
1215+
for IndexedMediaRetentionMetadataKey
1216+
{
1217+
fn lower_key_components_with_prefix(
1218+
prefix: IgnoreMediaRetentionPolicy,
1219+
) -> Self::KeyComponents<'a> {
1220+
(prefix, INDEXED_KEY_LOWER_DURATION, INDEXED_KEY_LOWER_MEDIA_CONTENT_SIZE)
1221+
}
1222+
1223+
fn upper_key_components_with_prefix(
1224+
prefix: IgnoreMediaRetentionPolicy,
1225+
) -> Self::KeyComponents<'a> {
1226+
(prefix, INDEXED_KEY_UPPER_DURATION_SECONDS, INDEXED_KEY_UPPER_MEDIA_CONTENT_SIZE)
1227+
}
1228+
}

0 commit comments

Comments
 (0)