Skip to content

Commit e961507

Browse files
committed
refactor(indexeddb): add migrations and types for media last access index
Signed-off-by: Michael Goldenberg <[email protected]>
1 parent 0b2daa7 commit e961507

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ pub mod v1 {
137137
pub const MEDIA_SOURCE_KEY_PATH: &str = "source";
138138
pub const MEDIA_CONTENT_SIZE: &str = "media_content_size";
139139
pub const MEDIA_CONTENT_SIZE_KEY_PATH: &str = "content_size";
140+
pub const MEDIA_LAST_ACCESS: &str = "media_last_access";
141+
pub const MEDIA_LAST_ACCESS_KEY_PATH: &str = "last_access";
140142
}
141143

142144
/// Create all object stores and indices for v1 database
@@ -233,6 +235,8 @@ pub mod v1 {
233235
/// media
234236
/// * Index - `content_size` - tracks the size of the media content and
235237
/// whether to ignore the [`MediaRetentionPolicy`][2]
238+
/// * Index - `last_access` - tracks the last time the associated media was
239+
/// accessed
236240
///
237241
/// [1]: ruma::events::room::MediaSource
238242
/// [2]: matrix_sdk_base::event_cache::store::media::MediaRetentionPolicy
@@ -242,6 +246,7 @@ pub mod v1 {
242246
let media = db.create_object_store_with_params(keys::MEDIA, &object_store_params)?;
243247
media.create_index(keys::MEDIA_SOURCE, &keys::MEDIA_SOURCE_KEY_PATH.into())?;
244248
media.create_index(keys::MEDIA_CONTENT_SIZE, &keys::MEDIA_CONTENT_SIZE_KEY_PATH.into())?;
249+
media.create_index(keys::MEDIA_LAST_ACCESS, &keys::MEDIA_LAST_ACCESS_KEY_PATH.into())?;
245250
Ok(())
246251
}
247252
}

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

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
//! These types mimic the structure of the object stores and indices created in
2828
//! [`crate::event_cache_store::migrations`].
2929
30-
use std::sync::LazyLock;
30+
use std::{sync::LazyLock, time::Duration};
3131

3232
use matrix_sdk_base::{
3333
event_cache::store::media::{IgnoreMediaRetentionPolicy, MediaRetentionPolicy},
@@ -154,6 +154,22 @@ static INDEXED_KEY_UPPER_EVENT_POSITION: LazyLock<Position> = LazyLock::new(|| P
154154
index: INDEXED_KEY_UPPER_EVENT_INDEX,
155155
});
156156

157+
/// The minimum possible [`Duration`].
158+
///
159+
/// This value is useful for constructing a key range over all keys which
160+
/// contain time-related values when used in conjunction with
161+
/// [`INDEXED_KEY_UPPER_DURATION`].
162+
const INDEXED_KEY_LOWER_DURATION: Duration = Duration::ZERO;
163+
164+
/// A [`Duration`] constructed with [`js_sys::Number::MAX_SAFE_INTEGER`]
165+
/// seconds.
166+
///
167+
/// This value is useful for constructing a key range over all keys which
168+
/// contain time-related values in seconds when used in conjunction with
169+
/// [`INDEXED_KEY_LOWER_DURATION`].
170+
const INDEXED_KEY_UPPER_DURATION_SECONDS: Duration =
171+
Duration::from_secs(js_sys::Number::MAX_SAFE_INTEGER as u64);
172+
157173
/// Representation of a range of keys of type `K`. This is loosely
158174
/// correlated with [IDBKeyRange][1], with a few differences.
159175
///
@@ -300,6 +316,10 @@ pub type IndexedMediaContent = Vec<u8>;
300316
/// is suitable for use in an IndexedDB key
301317
pub type IndexedMediaContentSize = usize;
302318

319+
/// A representation of time in seconds since the [Unix
320+
/// Epoch](std::time::UNIX_EPOCH) which is suitable for use in an IndexedDB key
321+
pub type IndexedSecondsSinceUnixEpoch = u64;
322+
303323
/// Represents the [`LEASES`][1] object store.
304324
///
305325
/// [1]: crate::event_cache_store::migrations::v1::create_lease_object_store
@@ -919,6 +939,7 @@ pub struct IndexedMedia {
919939
/// The (possibly) encrypted metadata - i.e., [`MediaMetadata`][1]
920940
///
921941
/// [1]: crate::event_cache_store::types::MediaMetadata
942+
pub last_access: IndexedMediaLastAccessKey,
922943
pub metadata: IndexedMediaMetadata,
923944
/// The (possibly) encrypted content - i.e., [`Media::content`]
924945
pub content: IndexedMediaContent,
@@ -958,6 +979,10 @@ impl Indexed for Media {
958979
(self.metadata.ignore_policy, content.len()),
959980
serializer,
960981
),
982+
last_access: IndexedMediaLastAccessKey::encode(
983+
(self.metadata.ignore_policy, self.metadata.last_access),
984+
serializer,
985+
),
961986
metadata: serializer.maybe_encrypt_value(&self.metadata)?,
962987
content,
963988
})
@@ -1070,3 +1095,54 @@ impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
10701095
(prefix, IndexedMediaContentSize::MAX)
10711096
}
10721097
}
1098+
1099+
/// The value associated with the [`last_access`](IndexedMedia::last_access)
1100+
/// index of the [`MEDIA`][1] object store, which is constructed from:
1101+
///
1102+
/// - The value of [`IgnoreMediaRetentionPolicy`]
1103+
/// - The last time the associated [`IndexedMedia`] was accessed (in seconds
1104+
/// since the Unix Epoch)
1105+
///
1106+
/// [1]: crate::event_cache_store::migrations::v1::create_media_object_store
1107+
#[derive(Debug, Serialize, Deserialize)]
1108+
pub struct IndexedMediaLastAccessKey(
1109+
#[serde(with = "ignore_media_retention_policy")] IgnoreMediaRetentionPolicy,
1110+
IndexedSecondsSinceUnixEpoch,
1111+
);
1112+
1113+
impl IndexedKey<Media> for IndexedMediaLastAccessKey {
1114+
type KeyComponents<'a> = (IgnoreMediaRetentionPolicy, Duration);
1115+
1116+
fn encode(
1117+
(ignore_policy, last_access): Self::KeyComponents<'_>,
1118+
_: &IndexeddbSerializer,
1119+
) -> Self {
1120+
Self(ignore_policy, last_access.as_secs())
1121+
}
1122+
}
1123+
1124+
impl IndexedKeyComponentBounds<Media> for IndexedMediaLastAccessKey {
1125+
fn lower_key_components() -> Self::KeyComponents<'static> {
1126+
Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::No)
1127+
}
1128+
1129+
fn upper_key_components() -> Self::KeyComponents<'static> {
1130+
Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::Yes)
1131+
}
1132+
}
1133+
1134+
impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
1135+
for IndexedMediaLastAccessKey
1136+
{
1137+
fn lower_key_components_with_prefix(
1138+
prefix: IgnoreMediaRetentionPolicy,
1139+
) -> Self::KeyComponents<'a> {
1140+
(prefix, INDEXED_KEY_LOWER_DURATION)
1141+
}
1142+
1143+
fn upper_key_components_with_prefix(
1144+
prefix: IgnoreMediaRetentionPolicy,
1145+
) -> Self::KeyComponents<'a> {
1146+
(prefix, INDEXED_KEY_UPPER_DURATION_SECONDS)
1147+
}
1148+
}

0 commit comments

Comments
 (0)