Commit 33da5ef143fe
tarball3 files changed+45-1
@@ -208,6 +208,28 @@ fn emit_new_first_chunk_updates<const CAP: usize, Item, Gap>(
208208
}209209
}210210
211
+/// Unload every chunk but the last, as [`replace_with`] does with that last chunk212
+/// read back from a store that matches memory, without the read.213
+pub fn unload_all_but_last<const CAP: usize, Item, Gap>(214
+ linked_chunk: &mut LinkedChunk<CAP, Item, Gap>,215
+) -> Result<(), LazyLoaderError>216
+where217
+ Item: Clone,218
+ Gap: Clone,219
+{220
+ let last = linked_chunk.links.latest_chunk();221
+ let chunk = RawChunk {222
+ content: last.content().clone(),223
+ previous: last.previous().map(|previous| previous.identifier()).or(last.lazy_previous()),224
+ identifier: last.identifier(),225
+ next: None,226
+ };227
+ let generator = ChunkIdentifierGenerator::new_from_previous_chunk_identifier(228
+ linked_chunk.chunk_identifier_generator.current(),229
+ );230
+ replace_with(linked_chunk, Some(chunk), generator)231
+}232
+211233
/// Replace the items with the given last chunk of items and generator.212234
///213235
/// This clears all the chunks in memory before resetting to the new chunk,@@ -633,6 +633,13 @@ impl EventLinkedChunk {
633633
})634634
}635635
636
+ /// Unload every chunk but the last, keeping the last as memory holds it.637
+ pub(in super::super) fn unload_all_but_last(&mut self) -> Result<(), LazyLoaderError> {638
+ self.inhibit_updates_to_ordering_tracker(|this| {639
+ lazy_loader::unload_all_but_last(&mut this.chunks)640
+ })641
+ }642
+636643
/// Prepends a lazily-loaded chunk at the beginning of the linked chunk.637644
#[instrument(err, skip_all, fields(sentry = true))]638645
pub(in super::super) fn insert_new_chunk_as_first(@@ -661,6 +661,21 @@ impl<'a> RoomEventCacheStateLockWriteGuard<'a> {
661661
self.state.find_event_with_relations(event_id, filters, &self.store).await662662
}663663
664
+ /// [`Self::shrink_to_last_chunk`] right after memory was persisted, so the last665
+ /// chunk is taken from memory rather than read back from the store.666
+ async fn shrink_to_last_chunk_in_memory(&mut self) -> Result<(), EventCacheError> {667
+ debug!("unloading the linked chunk, and keeping its last chunk from memory");668
+ if let Err(err) = self.state.room_linked_chunk.unload_all_but_last() {669
+ error!("error when unloading the linked chunk: {err}");670
+ return self.shrink_to_last_chunk().await;671
+ }672
+ self.state673
+ .pagination_status674
+ .set(SharedPaginationStatus::Idle { hit_timeline_start: false });675
+ let _ = self.state.room_linked_chunk.store_updates().take();676
+ Ok(())677
+ }678
+664679
/// If storage is enabled, unload all the chunks, then reloads only the665680
/// last one.666681
///@@ -1230,7 +1245,7 @@ impl<'a> RoomEventCacheStateLockWriteGuard<'a> {
12301245
//12311246
// We must do this *after* persisting these events to storage (in12321247
// `post_process_new_events`).1233
- self.shrink_to_last_chunk().await?;1248
+ self.shrink_to_last_chunk_in_memory().await?;12341249
}12351250
12361251
let timeline_event_diffs = self.state.room_linked_chunk.updates_as_vector_diffs();