LCOV - code coverage report
Current view: top level - pageserver/src/tenant/storage_layer - layer_desc.rs (source / functions) Coverage Total Hit
Test: 8ac049b474321fdc72ddcb56d7165153a1a900e8.info Lines: 70.6 % 119 84
Test Date: 2023-09-06 10:18:01 Functions: 48.6 % 35 17

            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        37504 : #[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     46065740 : #[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     45837672 :     pub fn key(&self) -> PersistentLayerKey {
      46     45837672 :         PersistentLayerKey {
      47     45837672 :             key_range: self.key_range.clone(),
      48     45837672 :             lsn_range: self.lsn_range.clone(),
      49     45837672 :             is_delta: self.is_delta,
      50     45837672 :         }
      51     45837672 :     }
      52              : 
      53         8263 :     pub fn short_id(&self) -> impl Display {
      54         8263 :         self.filename()
      55         8263 :     }
      56              : 
      57              :     #[cfg(test)]
      58            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         2810 :     pub fn new_img(
      70         2810 :         tenant_id: TenantId,
      71         2810 :         timeline_id: TimelineId,
      72         2810 :         key_range: Range<Key>,
      73         2810 :         lsn: Lsn,
      74         2810 :         file_size: u64,
      75         2810 :     ) -> Self {
      76         2810 :         Self {
      77         2810 :             tenant_id,
      78         2810 :             timeline_id,
      79         2810 :             key_range,
      80         2810 :             lsn_range: Self::image_layer_lsn_range(lsn),
      81         2810 :             is_delta: false,
      82         2810 :             file_size,
      83         2810 :         }
      84         2810 :     }
      85              : 
      86        21371 :     pub fn new_delta(
      87        21371 :         tenant_id: TenantId,
      88        21371 :         timeline_id: TimelineId,
      89        21371 :         key_range: Range<Key>,
      90        21371 :         lsn_range: Range<Lsn>,
      91        21371 :         file_size: u64,
      92        21371 :     ) -> Self {
      93        21371 :         Self {
      94        21371 :             tenant_id,
      95        21371 :             timeline_id,
      96        21371 :             key_range,
      97        21371 :             lsn_range,
      98        21371 :             is_delta: true,
      99        21371 :             file_size,
     100        21371 :         }
     101        21371 :     }
     102              : 
     103              :     /// Get the LSN that the image layer covers.
     104         1570 :     pub fn image_layer_lsn(&self) -> Lsn {
     105         1570 :         assert!(!self.is_delta);
     106         1570 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     107         1570 :         self.lsn_range.start
     108         1570 :     }
     109              : 
     110              :     /// Get the LSN range corresponding to a single image layer LSN.
     111         2810 :     pub fn image_layer_lsn_range(lsn: Lsn) -> Range<Lsn> {
     112         2810 :         lsn..(lsn + 1)
     113         2810 :     }
     114              : 
     115              :     /// Get a delta file name for this layer.
     116              :     ///
     117              :     /// Panic: if this is not a delta layer.
     118        70323 :     pub fn delta_file_name(&self) -> DeltaFileName {
     119        70323 :         assert!(self.is_delta);
     120        70323 :         DeltaFileName {
     121        70323 :             key_range: self.key_range.clone(),
     122        70323 :             lsn_range: self.lsn_range.clone(),
     123        70323 :         }
     124        70323 :     }
     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         7603 :     pub fn image_file_name(&self) -> ImageFileName {
     130         7603 :         assert!(!self.is_delta);
     131         7603 :         assert!(self.lsn_range.start + 1 == self.lsn_range.end);
     132         7603 :         ImageFileName {
     133         7603 :             key_range: self.key_range.clone(),
     134         7603 :             lsn: self.lsn_range.start,
     135         7603 :         }
     136         7603 :     }
     137              : 
     138        31853 :     pub fn filename(&self) -> LayerFileName {
     139        31853 :         if self.is_delta {
     140        27736 :             self.delta_file_name().into()
     141              :         } else {
     142         4117 :             self.image_file_name().into()
     143              :         }
     144        31853 :     }
     145              : 
     146              :     // TODO: remove this in the future once we refactor timeline APIs.
     147              : 
     148     84594080 :     pub fn get_lsn_range(&self) -> Range<Lsn> {
     149     84594080 :         self.lsn_range.clone()
     150     84594080 :     }
     151              : 
     152     11769714 :     pub fn get_key_range(&self) -> Range<Key> {
     153     11769714 :         self.key_range.clone()
     154     11769714 :     }
     155              : 
     156            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        27265 :     pub fn is_incremental(&self) -> bool {
     169        27265 :         self.is_delta
     170        27265 :     }
     171              : 
     172            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        64825 :     pub fn file_size(&self) -> u64 {
     194        64825 :         self.file_size
     195        64825 :     }
     196              : }
        

Generated by: LCOV version 2.1-beta