LCOV - code coverage report
Current view: top level - pageserver/src/tenant/storage_layer - layer_desc.rs (source / functions) Coverage Total Hit
Test: ccf45ed1c149555259baec52d6229a81013dcd6a.info Lines: 97.4 % 153 149
Test Date: 2024-08-21 17:32:46 Functions: 66.7 % 27 18

            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::{DeltaLayerName, ImageLayerName, LayerName};
       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            0 : #[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash)]
      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              : #[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 std::fmt::Display for PersistentLayerKey {
      45           32 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      46           32 :         write!(
      47           32 :             f,
      48           32 :             "{}..{} {}..{} is_delta={}",
      49           32 :             self.key_range.start,
      50           32 :             self.key_range.end,
      51           32 :             self.lsn_range.start,
      52           32 :             self.lsn_range.end,
      53           32 :             self.is_delta
      54           32 :         )
      55           32 :     }
      56              : }
      57              : 
      58              : impl PersistentLayerDesc {
      59       563478 :     pub fn key(&self) -> PersistentLayerKey {
      60       563478 :         PersistentLayerKey {
      61       563478 :             key_range: self.key_range.clone(),
      62       563478 :             lsn_range: self.lsn_range.clone(),
      63       563478 :             is_delta: self.is_delta,
      64       563478 :         }
      65       563478 :     }
      66              : 
      67         1956 :     pub fn short_id(&self) -> impl Display {
      68         1956 :         self.layer_name()
      69         1956 :     }
      70              : 
      71              :     #[cfg(test)]
      72           10 :     pub fn new_test(key_range: Range<Key>, lsn_range: Range<Lsn>, is_delta: bool) -> Self {
      73           10 :         Self {
      74           10 :             tenant_shard_id: TenantShardId::unsharded(TenantId::generate()),
      75           10 :             timeline_id: TimelineId::generate(),
      76           10 :             key_range,
      77           10 :             lsn_range,
      78           10 :             is_delta,
      79           10 :             file_size: 0,
      80           10 :         }
      81           10 :     }
      82              : 
      83          300 :     pub fn new_img(
      84          300 :         tenant_shard_id: TenantShardId,
      85          300 :         timeline_id: TimelineId,
      86          300 :         key_range: Range<Key>,
      87          300 :         lsn: Lsn,
      88          300 :         file_size: u64,
      89          300 :     ) -> Self {
      90          300 :         Self {
      91          300 :             tenant_shard_id,
      92          300 :             timeline_id,
      93          300 :             key_range,
      94          300 :             lsn_range: Self::image_layer_lsn_range(lsn),
      95          300 :             is_delta: false,
      96          300 :             file_size,
      97          300 :         }
      98          300 :     }
      99              : 
     100         1432 :     pub fn new_delta(
     101         1432 :         tenant_shard_id: TenantShardId,
     102         1432 :         timeline_id: TimelineId,
     103         1432 :         key_range: Range<Key>,
     104         1432 :         lsn_range: Range<Lsn>,
     105         1432 :         file_size: u64,
     106         1432 :     ) -> Self {
     107         1432 :         Self {
     108         1432 :             tenant_shard_id,
     109         1432 :             timeline_id,
     110         1432 :             key_range,
     111         1432 :             lsn_range,
     112         1432 :             is_delta: true,
     113         1432 :             file_size,
     114         1432 :         }
     115         1432 :     }
     116              : 
     117           24 :     pub fn from_filename(
     118           24 :         tenant_shard_id: TenantShardId,
     119           24 :         timeline_id: TimelineId,
     120           24 :         filename: LayerName,
     121           24 :         file_size: u64,
     122           24 :     ) -> Self {
     123           24 :         match filename {
     124            4 :             LayerName::Image(i) => {
     125            4 :                 Self::new_img(tenant_shard_id, timeline_id, i.key_range, i.lsn, file_size)
     126              :             }
     127           20 :             LayerName::Delta(d) => Self::new_delta(
     128           20 :                 tenant_shard_id,
     129           20 :                 timeline_id,
     130           20 :                 d.key_range,
     131           20 :                 d.lsn_range,
     132           20 :                 file_size,
     133           20 :             ),
     134              :         }
     135           24 :     }
     136              : 
     137              :     /// Get the LSN that the image layer covers.
     138      2521836 :     pub fn image_layer_lsn(&self) -> Lsn {
     139      2521836 :         assert!(!self.is_delta);
     140      2521836 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     141      2521836 :         self.lsn_range.start
     142      2521836 :     }
     143              : 
     144              :     /// Get the LSN range corresponding to a single image layer LSN.
     145         1938 :     pub fn image_layer_lsn_range(lsn: Lsn) -> Range<Lsn> {
     146         1938 :         lsn..(lsn + 1)
     147         1938 :     }
     148              : 
     149              :     /// Get a delta layer name for this layer.
     150              :     ///
     151              :     /// Panic: if this is not a delta layer.
     152         6453 :     pub fn delta_layer_name(&self) -> DeltaLayerName {
     153         6453 :         assert!(self.is_delta);
     154         6453 :         DeltaLayerName {
     155         6453 :             key_range: self.key_range.clone(),
     156         6453 :             lsn_range: self.lsn_range.clone(),
     157         6453 :         }
     158         6453 :     }
     159              : 
     160              :     /// Get a image layer name for this layer.
     161              :     ///
     162              :     /// Panic: if this is not an image layer, or the lsn range is invalid
     163         1018 :     pub fn image_layer_name(&self) -> ImageLayerName {
     164         1018 :         assert!(!self.is_delta);
     165         1018 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     166         1018 :         ImageLayerName {
     167         1018 :             key_range: self.key_range.clone(),
     168         1018 :             lsn: self.lsn_range.start,
     169         1018 :         }
     170         1018 :     }
     171              : 
     172         7471 :     pub fn layer_name(&self) -> LayerName {
     173         7471 :         if self.is_delta {
     174         6453 :             self.delta_layer_name().into()
     175              :         } else {
     176         1018 :             self.image_layer_name().into()
     177              :         }
     178         7471 :     }
     179              : 
     180              :     // TODO: remove this in the future once we refactor timeline APIs.
     181              : 
     182      3747044 :     pub fn get_lsn_range(&self) -> Range<Lsn> {
     183      3747044 :         self.lsn_range.clone()
     184      3747044 :     }
     185              : 
     186       108256 :     pub fn get_key_range(&self) -> Range<Key> {
     187       108256 :         self.key_range.clone()
     188       108256 :     }
     189              : 
     190            0 :     pub fn get_timeline_id(&self) -> TimelineId {
     191            0 :         self.timeline_id
     192            0 :     }
     193              : 
     194              :     /// Does this layer only contain some data for the key-range (incremental),
     195              :     /// or does it contain a version of every page? This is important to know
     196              :     /// for garbage collecting old layers: an incremental layer depends on
     197              :     /// the previous non-incremental layer.
     198         5266 :     pub fn is_incremental(&self) -> bool {
     199         5266 :         self.is_delta
     200         5266 :     }
     201              : 
     202      5729927 :     pub fn is_delta(&self) -> bool {
     203      5729927 :         self.is_delta
     204      5729927 :     }
     205              : 
     206           16 :     pub fn dump(&self) {
     207           16 :         if self.is_delta {
     208           14 :             println!(
     209           14 :                 "----- delta layer for ten {} tli {} keys {}-{} lsn {}-{} is_incremental {} size {} ----",
     210           14 :                 self.tenant_shard_id,
     211           14 :                 self.timeline_id,
     212           14 :                 self.key_range.start,
     213           14 :                 self.key_range.end,
     214           14 :                 self.lsn_range.start,
     215           14 :                 self.lsn_range.end,
     216           14 :                 self.is_incremental(),
     217           14 :                 self.file_size,
     218           14 :             );
     219           14 :         } else {
     220            2 :             println!(
     221            2 :                 "----- image layer for ten {} tli {} key {}-{} at {} is_incremental {} size {} ----",
     222            2 :                 self.tenant_shard_id,
     223            2 :                 self.timeline_id,
     224            2 :                 self.key_range.start,
     225            2 :                 self.key_range.end,
     226            2 :                 self.image_layer_lsn(),
     227            2 :                 self.is_incremental(),
     228            2 :                 self.file_size
     229            2 :             );
     230            2 :         }
     231           16 :     }
     232              : 
     233           80 :     pub fn file_size(&self) -> u64 {
     234           80 :         self.file_size
     235           80 :     }
     236              : }
        

Generated by: LCOV version 2.1-beta