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: f6946e90941b557c917ac98cd5a7e9506d180f3e.info Lines: 70.6 % 119 84 35 84
Current Date: 2023-10-19 02:04:12 Functions: 48.6 % 35 17 18 17
Baseline: c8637f37369098875162f194f92736355783b050.info
Baseline Date: 2023-10-18 20:25:20

           TLA  Line data    Source code
       1                 : use anyhow::Result;
       2                 : use core::fmt::Display;
       3                 : use std::ops::Range;
       4                 : use utils::{
       5                 :     id::{TenantId, TimelineId},
       6                 :     lsn::Lsn,
       7                 : };
       8                 : 
       9                 : use crate::{context::RequestContext, repository::Key};
      10                 : 
      11                 : use super::{DeltaFileName, ImageFileName, LayerFileName};
      12                 : 
      13                 : use serde::{Deserialize, Serialize};
      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       37174 : #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
      19                 : pub struct PersistentLayerDesc {
      20                 :     pub tenant_id: TenantId,
      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        24179132 : #[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        23992150 :     pub fn key(&self) -> PersistentLayerKey {
      46        23992150 :         PersistentLayerKey {
      47        23992150 :             key_range: self.key_range.clone(),
      48        23992150 :             lsn_range: self.lsn_range.clone(),
      49        23992150 :             is_delta: self.is_delta,
      50        23992150 :         }
      51        23992150 :     }
      52                 : 
      53            9199 :     pub fn short_id(&self) -> impl Display {
      54            9199 :         self.filename()
      55            9199 :     }
      56                 : 
      57                 :     #[cfg(test)]
      58 UBC           0 :     pub fn new_test(key_range: Range<Key>) -> Self {
      59               0 :         Self {
      60               0 :             tenant_id: 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        8010 :     pub fn new_img(
      70            8010 :         tenant_id: TenantId,
      71            8010 :         timeline_id: TimelineId,
      72            8010 :         key_range: Range<Key>,
      73            8010 :         lsn: Lsn,
      74            8010 :         file_size: u64,
      75            8010 :     ) -> Self {
      76            8010 :         Self {
      77            8010 :             tenant_id,
      78            8010 :             timeline_id,
      79            8010 :             key_range,
      80            8010 :             lsn_range: Self::image_layer_lsn_range(lsn),
      81            8010 :             is_delta: false,
      82            8010 :             file_size,
      83            8010 :         }
      84            8010 :     }
      85                 : 
      86           21156 :     pub fn new_delta(
      87           21156 :         tenant_id: TenantId,
      88           21156 :         timeline_id: TimelineId,
      89           21156 :         key_range: Range<Key>,
      90           21156 :         lsn_range: Range<Lsn>,
      91           21156 :         file_size: u64,
      92           21156 :     ) -> Self {
      93           21156 :         Self {
      94           21156 :             tenant_id,
      95           21156 :             timeline_id,
      96           21156 :             key_range,
      97           21156 :             lsn_range,
      98           21156 :             is_delta: true,
      99           21156 :             file_size,
     100           21156 :         }
     101           21156 :     }
     102                 : 
     103                 :     /// Get the LSN that the image layer covers.
     104            4010 :     pub fn image_layer_lsn(&self) -> Lsn {
     105            4010 :         assert!(!self.is_delta);
     106            4010 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     107            4010 :         self.lsn_range.start
     108            4010 :     }
     109                 : 
     110                 :     /// Get the LSN range corresponding to a single image layer LSN.
     111            8010 :     pub fn image_layer_lsn_range(lsn: Lsn) -> Range<Lsn> {
     112            8010 :         lsn..(lsn + 1)
     113            8010 :     }
     114                 : 
     115                 :     /// Get a delta file name for this layer.
     116                 :     ///
     117                 :     /// Panic: if this is not a delta layer.
     118           76183 :     pub fn delta_file_name(&self) -> DeltaFileName {
     119           76183 :         assert!(self.is_delta);
     120           76183 :         DeltaFileName {
     121           76183 :             key_range: self.key_range.clone(),
     122           76183 :             lsn_range: self.lsn_range.clone(),
     123           76183 :         }
     124           76183 :     }
     125                 : 
     126                 :     /// Get a delta file name for this layer.
     127                 :     ///
     128                 :     /// Panic: if this is not an image layer, or the lsn range is invalid
     129           71116 :     pub fn image_file_name(&self) -> ImageFileName {
     130           71116 :         assert!(!self.is_delta);
     131           71116 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     132           71116 :         ImageFileName {
     133           71116 :             key_range: self.key_range.clone(),
     134           71116 :             lsn: self.lsn_range.start,
     135           71116 :         }
     136           71116 :     }
     137                 : 
     138           94070 :     pub fn filename(&self) -> LayerFileName {
     139           94070 :         if self.is_delta {
     140           32233 :             self.delta_file_name().into()
     141                 :         } else {
     142           61837 :             self.image_file_name().into()
     143                 :         }
     144           94070 :     }
     145                 : 
     146                 :     // TODO: remove this in the future once we refactor timeline APIs.
     147                 : 
     148        51786066 :     pub fn get_lsn_range(&self) -> Range<Lsn> {
     149        51786066 :         self.lsn_range.clone()
     150        51786066 :     }
     151                 : 
     152         7243122 :     pub fn get_key_range(&self) -> Range<Key> {
     153         7243122 :         self.key_range.clone()
     154         7243122 :     }
     155                 : 
     156 UBC           0 :     pub fn get_timeline_id(&self) -> TimelineId {
     157               0 :         self.timeline_id
     158               0 :     }
     159                 : 
     160               0 :     pub fn get_tenant_id(&self) -> TenantId {
     161               0 :         self.tenant_id
     162               0 :     }
     163                 : 
     164                 :     /// Does this layer only contain some data for the key-range (incremental),
     165                 :     /// or does it contain a version of every page? This is important to know
     166                 :     /// for garbage collecting old layers: an incremental layer depends on
     167                 :     /// the previous non-incremental layer.
     168 CBC       34205 :     pub fn is_incremental(&self) -> bool {
     169           34205 :         self.is_delta
     170           34205 :     }
     171                 : 
     172 UBC           0 :     pub fn is_delta(&self) -> bool {
     173               0 :         self.is_delta
     174               0 :     }
     175                 : 
     176               0 :     pub fn dump(&self, _verbose: bool, _ctx: &RequestContext) -> Result<()> {
     177               0 :         println!(
     178               0 :             "----- layer for ten {} tli {} keys {}-{} lsn {}-{} is_delta {} is_incremental {} size {} ----",
     179               0 :             self.tenant_id,
     180               0 :             self.timeline_id,
     181               0 :             self.key_range.start,
     182               0 :             self.key_range.end,
     183               0 :             self.lsn_range.start,
     184               0 :             self.lsn_range.end,
     185               0 :             self.is_delta,
     186               0 :             self.is_incremental(),
     187               0 :             self.file_size,
     188               0 :         );
     189               0 : 
     190               0 :         Ok(())
     191               0 :     }
     192                 : 
     193 CBC       94899 :     pub fn file_size(&self) -> u64 {
     194           94899 :         self.file_size
     195           94899 :     }
     196                 : }
        

Generated by: LCOV version 2.1-beta