LCOV - differential code coverage report
Current view: top level - pageserver/src/tenant/storage_layer - layer_desc.rs (source / functions) Coverage Total Hit UBC CBC
Current: cd44433dd675caa99df17a61b18949c8387e2242.info Lines: 81.1 % 143 116 27 116
Current Date: 2024-01-09 02:06:09 Functions: 51.4 % 35 18 17 18
Baseline: 66c52a629a0f4a503e193045e0df4c77139e344b.info
Baseline Date: 2024-01-08 15:34:46

           TLA  Line data    Source code
       1                 : use core::fmt::Display;
       2                 : use pageserver_api::shard::TenantShardId;
       3                 : use std::ops::Range;
       4                 : use utils::{id::TimelineId, lsn::Lsn};
       5                 : 
       6                 : use crate::repository::Key;
       7                 : 
       8                 : use super::{DeltaFileName, ImageFileName, LayerFileName};
       9                 : 
      10                 : use serde::{Deserialize, Serialize};
      11                 : 
      12                 : #[cfg(test)]
      13                 : use utils::id::TenantId;
      14                 : 
      15                 : /// A unique identifier of a persistent layer. This is different from `LayerDescriptor`, which is only used in the
      16                 : /// benchmarks. This struct contains all necessary information to find the image / delta layer. It also provides
      17                 : /// a unified way to generate layer information like file name.
      18 CBC       83646 : #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
      19                 : pub struct PersistentLayerDesc {
      20                 :     pub tenant_shard_id: TenantShardId,
      21                 :     pub timeline_id: TimelineId,
      22                 :     /// Range of keys that this layer covers
      23                 :     pub key_range: Range<Key>,
      24                 :     /// Inclusive start, exclusive end of the LSN range that this layer holds.
      25                 :     ///
      26                 :     /// - For an open in-memory layer, the end bound is MAX_LSN
      27                 :     /// - For a frozen in-memory layer or a delta layer, the end bound is a valid lsn after the
      28                 :     /// range start
      29                 :     /// - An image layer represents snapshot at one LSN, so end_lsn is always the snapshot LSN + 1
      30                 :     pub lsn_range: Range<Lsn>,
      31                 :     /// Whether this is a delta layer, and also, is this incremental.
      32                 :     pub is_delta: bool,
      33                 :     pub file_size: u64,
      34                 : }
      35                 : 
      36                 : /// A unique identifier of a persistent layer within the context of one timeline.
      37        15681652 : #[derive(Debug, PartialEq, Eq, Clone, Hash)]
      38                 : pub struct PersistentLayerKey {
      39                 :     pub key_range: Range<Key>,
      40                 :     pub lsn_range: Range<Lsn>,
      41                 :     pub is_delta: bool,
      42                 : }
      43                 : 
      44                 : impl PersistentLayerDesc {
      45        15623577 :     pub fn key(&self) -> PersistentLayerKey {
      46        15623577 :         PersistentLayerKey {
      47        15623577 :             key_range: self.key_range.clone(),
      48        15623577 :             lsn_range: self.lsn_range.clone(),
      49        15623577 :             is_delta: self.is_delta,
      50        15623577 :         }
      51        15623577 :     }
      52                 : 
      53           53275 :     pub fn short_id(&self) -> impl Display {
      54           53275 :         self.filename()
      55           53275 :     }
      56                 : 
      57                 :     #[cfg(test)]
      58 UBC           0 :     pub fn new_test(key_range: Range<Key>) -> Self {
      59               0 :         Self {
      60               0 :             tenant_shard_id: TenantShardId::unsharded(TenantId::generate()),
      61               0 :             timeline_id: TimelineId::generate(),
      62               0 :             key_range,
      63               0 :             lsn_range: Lsn(0)..Lsn(1),
      64               0 :             is_delta: false,
      65               0 :             file_size: 0,
      66               0 :         }
      67               0 :     }
      68                 : 
      69 CBC       39000 :     pub fn new_img(
      70           39000 :         tenant_shard_id: TenantShardId,
      71           39000 :         timeline_id: TimelineId,
      72           39000 :         key_range: Range<Key>,
      73           39000 :         lsn: Lsn,
      74           39000 :         file_size: u64,
      75           39000 :     ) -> Self {
      76           39000 :         Self {
      77           39000 :             tenant_shard_id,
      78           39000 :             timeline_id,
      79           39000 :             key_range,
      80           39000 :             lsn_range: Self::image_layer_lsn_range(lsn),
      81           39000 :             is_delta: false,
      82           39000 :             file_size,
      83           39000 :         }
      84           39000 :     }
      85                 : 
      86           39253 :     pub fn new_delta(
      87           39253 :         tenant_shard_id: TenantShardId,
      88           39253 :         timeline_id: TimelineId,
      89           39253 :         key_range: Range<Key>,
      90           39253 :         lsn_range: Range<Lsn>,
      91           39253 :         file_size: u64,
      92           39253 :     ) -> Self {
      93           39253 :         Self {
      94           39253 :             tenant_shard_id,
      95           39253 :             timeline_id,
      96           39253 :             key_range,
      97           39253 :             lsn_range,
      98           39253 :             is_delta: true,
      99           39253 :             file_size,
     100           39253 :         }
     101           39253 :     }
     102                 : 
     103           57805 :     pub fn from_filename(
     104           57805 :         tenant_shard_id: TenantShardId,
     105           57805 :         timeline_id: TimelineId,
     106           57805 :         filename: LayerFileName,
     107           57805 :         file_size: u64,
     108           57805 :     ) -> Self {
     109           57805 :         match filename {
     110           33361 :             LayerFileName::Image(i) => {
     111           33361 :                 Self::new_img(tenant_shard_id, timeline_id, i.key_range, i.lsn, file_size)
     112                 :             }
     113           24444 :             LayerFileName::Delta(d) => Self::new_delta(
     114           24444 :                 tenant_shard_id,
     115           24444 :                 timeline_id,
     116           24444 :                 d.key_range,
     117           24444 :                 d.lsn_range,
     118           24444 :                 file_size,
     119           24444 :             ),
     120                 :         }
     121           57805 :     }
     122                 : 
     123                 :     /// Get the LSN that the image layer covers.
     124          927012 :     pub fn image_layer_lsn(&self) -> Lsn {
     125          927012 :         assert!(!self.is_delta);
     126          927012 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     127          927012 :         self.lsn_range.start
     128          927012 :     }
     129                 : 
     130                 :     /// Get the LSN range corresponding to a single image layer LSN.
     131           39000 :     pub fn image_layer_lsn_range(lsn: Lsn) -> Range<Lsn> {
     132           39000 :         lsn..(lsn + 1)
     133           39000 :     }
     134                 : 
     135                 :     /// Get a delta file name for this layer.
     136                 :     ///
     137                 :     /// Panic: if this is not a delta layer.
     138          557731 :     pub fn delta_file_name(&self) -> DeltaFileName {
     139          557731 :         assert!(self.is_delta);
     140          557731 :         DeltaFileName {
     141          557731 :             key_range: self.key_range.clone(),
     142          557731 :             lsn_range: self.lsn_range.clone(),
     143          557731 :         }
     144          557731 :     }
     145                 : 
     146                 :     /// Get a delta file name for this layer.
     147                 :     ///
     148                 :     /// Panic: if this is not an image layer, or the lsn range is invalid
     149          420817 :     pub fn image_file_name(&self) -> ImageFileName {
     150          420817 :         assert!(!self.is_delta);
     151          420817 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     152          420817 :         ImageFileName {
     153          420817 :             key_range: self.key_range.clone(),
     154          420817 :             lsn: self.lsn_range.start,
     155          420817 :         }
     156          420817 :     }
     157                 : 
     158          978548 :     pub fn filename(&self) -> LayerFileName {
     159          978548 :         if self.is_delta {
     160          557731 :             self.delta_file_name().into()
     161                 :         } else {
     162          420817 :             self.image_file_name().into()
     163                 :         }
     164          978548 :     }
     165                 : 
     166                 :     // TODO: remove this in the future once we refactor timeline APIs.
     167                 : 
     168        29074365 :     pub fn get_lsn_range(&self) -> Range<Lsn> {
     169        29074365 :         self.lsn_range.clone()
     170        29074365 :     }
     171                 : 
     172         2216596 :     pub fn get_key_range(&self) -> Range<Key> {
     173         2216596 :         self.key_range.clone()
     174         2216596 :     }
     175                 : 
     176 UBC           0 :     pub fn get_timeline_id(&self) -> TimelineId {
     177               0 :         self.timeline_id
     178               0 :     }
     179                 : 
     180                 :     /// Does this layer only contain some data for the key-range (incremental),
     181                 :     /// or does it contain a version of every page? This is important to know
     182                 :     /// for garbage collecting old layers: an incremental layer depends on
     183                 :     /// the previous non-incremental layer.
     184 CBC       83227 :     pub fn is_incremental(&self) -> bool {
     185           83227 :         self.is_delta
     186           83227 :     }
     187                 : 
     188 UBC           0 :     pub fn is_delta(&self) -> bool {
     189               0 :         self.is_delta
     190               0 :     }
     191                 : 
     192 CBC           2 :     pub fn dump(&self) {
     193               2 :         if self.is_delta {
     194               2 :             println!(
     195               2 :                 "----- delta layer for ten {} tli {} keys {}-{} lsn {}-{} is_incremental {} size {} ----",
     196               2 :                 self.tenant_shard_id,
     197               2 :                 self.timeline_id,
     198               2 :                 self.key_range.start,
     199               2 :                 self.key_range.end,
     200               2 :                 self.lsn_range.start,
     201               2 :                 self.lsn_range.end,
     202               2 :                 self.is_incremental(),
     203               2 :                 self.file_size,
     204               2 :             );
     205               2 :         } else {
     206 UBC           0 :             println!(
     207               0 :                 "----- image layer for ten {} tli {} key {}-{} at {} is_incremental {} size {} ----",
     208               0 :                 self.tenant_shard_id,
     209               0 :                 self.timeline_id,
     210               0 :                 self.key_range.start,
     211               0 :                 self.key_range.end,
     212               0 :                 self.image_layer_lsn(),
     213               0 :                 self.is_incremental(),
     214               0 :                 self.file_size
     215               0 :             );
     216               0 :         }
     217 CBC           2 :     }
     218                 : 
     219          366239 :     pub fn file_size(&self) -> u64 {
     220          366239 :         self.file_size
     221          366239 :     }
     222                 : }
        

Generated by: LCOV version 2.1-beta