diff --git a/pageserver/src/tenant/storage_layer/delta_layer.rs b/pageserver/src/tenant/storage_layer/delta_layer.rs index 4324a6e9a0..bff42a1ec2 100644 --- a/pageserver/src/tenant/storage_layer/delta_layer.rs +++ b/pageserver/src/tenant/storage_layer/delta_layer.rs @@ -552,12 +552,17 @@ impl DeltaLayer { /// Loads all keys stored in the layer. Returns key, lsn, value size and value reference. /// /// The value can be obtained via the [`ValueRef::load`] function. - pub async fn load_keys(&self, ctx: &RequestContext) -> Result> { + pub(crate) async fn load_keys( + &self, + ctx: &RequestContext, + ) -> Result>>> { let inner = self .load(LayerAccessKind::KeyIter, ctx) .await .context("load delta layer keys")?; - DeltaLayerInner::load_keys(inner) + + let inner = Ref(&**inner); + DeltaLayerInner::load_keys(&inner) .await .context("Layer index is corrupted") } @@ -953,14 +958,14 @@ impl DeltaLayerInner { pub(super) async fn load_keys + Clone>( this: &T, - ) -> Result> { + ) -> Result>> { let dl = this.as_ref(); let file = &dl.file; let tree_reader = DiskBtreeReader::<_, DELTA_KEY_SIZE>::new(dl.index_start_blk, dl.index_root_blk, file); - let mut all_keys: Vec = Vec::new(); + let mut all_keys: Vec> = Vec::new(); tree_reader .visit( @@ -970,7 +975,7 @@ impl DeltaLayerInner { let delta_key = DeltaKey::from_slice(key); let val_ref = ValueRef { blob_ref: BlobRef(value), - reader: BlockCursor::new(Adapter(dl)), + reader: BlockCursor::new(Adapter(this.clone())), }; let pos = BlobRef(value).pos(); if let Some(last) = all_keys.last_mut() { @@ -999,14 +1004,34 @@ impl DeltaLayerInner { } } +/// Cloneable borrow wrapper to make borrows behave like smart pointers. +/// +/// Shared references are trivially copyable. This wrapper avoids (confusion) to otherwise attempt +/// cloning DeltaLayerInner. +pub(crate) struct Ref(T); + +impl<'a, T> AsRef for Ref<&'a T> { + fn as_ref(&self) -> &T { + self.0 + } +} + +impl<'a, T> Clone for Ref<&'a T> { + fn clone(&self) -> Self { + *self + } +} + +impl<'a, T> Copy for Ref<&'a T> {} + /// A set of data associated with a delta layer key and its value -pub struct DeltaEntry<'a> { +pub struct DeltaEntry> { pub key: Key, pub lsn: Lsn, /// Size of the stored value pub size: u64, /// Reference to the on-disk value - pub val: ValueRef<&'a DeltaLayerInner>, + pub val: ValueRef, } /// Reference to an on-disk value