LCOV - code coverage report
Current view: top level - libs/pageserver_api/src - reltag.rs (source / functions) Coverage Total Hit
Test: 691a4c28fe7169edd60b367c52d448a0a6605f1f.info Lines: 0.0 % 49 0
Test Date: 2024-05-10 13:18:37 Functions: 0.0 % 22 0

            Line data    Source code
       1              : use serde::{Deserialize, Serialize};
       2              : use std::cmp::Ordering;
       3              : use std::fmt;
       4              : 
       5              : use postgres_ffi::pg_constants::GLOBALTABLESPACE_OID;
       6              : use postgres_ffi::relfile_utils::forknumber_to_name;
       7              : use postgres_ffi::Oid;
       8              : 
       9              : ///
      10              : /// Relation data file segment id throughout the Postgres cluster.
      11              : ///
      12              : /// Every data file in Postgres is uniquely identified by 4 numbers:
      13              : /// - relation id / node (`relnode`)
      14              : /// - database id (`dbnode`)
      15              : /// - tablespace id (`spcnode`), in short this is a unique id of a separate
      16              : ///   directory to store data files.
      17              : /// - forknumber (`forknum`) is used to split different kinds of data of the same relation
      18              : ///   between some set of files (`relnode`, `relnode_fsm`, `relnode_vm`).
      19              : ///
      20              : /// In native Postgres code `RelFileNode` structure and individual `ForkNumber` value
      21              : /// are used for the same purpose.
      22              : /// [See more related comments here](https:///github.com/postgres/postgres/blob/99c5852e20a0987eca1c38ba0c09329d4076b6a0/src/include/storage/relfilenode.h#L57).
      23              : ///
      24              : // FIXME: should move 'forknum' as last field to keep this consistent with Postgres.
      25              : // Then we could replace the custom Ord and PartialOrd implementations below with
      26              : // deriving them. This will require changes in walredoproc.c.
      27              : #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy, Serialize)]
      28              : pub struct RelTag {
      29              :     pub forknum: u8,
      30              :     pub spcnode: Oid,
      31              :     pub dbnode: Oid,
      32              :     pub relnode: Oid,
      33              : }
      34              : 
      35              : /// Block number within a relation or SLRU. This matches PostgreSQL's BlockNumber type.
      36              : pub type BlockNumber = u32;
      37              : 
      38              : impl PartialOrd for RelTag {
      39            0 :     fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
      40            0 :         Some(self.cmp(other))
      41            0 :     }
      42              : }
      43              : 
      44              : impl Ord for RelTag {
      45            0 :     fn cmp(&self, other: &Self) -> Ordering {
      46            0 :         // Custom ordering where we put forknum to the end of the list
      47            0 :         let other_tup = (other.spcnode, other.dbnode, other.relnode, other.forknum);
      48            0 :         (self.spcnode, self.dbnode, self.relnode, self.forknum).cmp(&other_tup)
      49            0 :     }
      50              : }
      51              : 
      52              : /// Display RelTag in the same format that's used in most PostgreSQL debug messages:
      53              : ///
      54              : /// ```text
      55              : /// <spcnode>/<dbnode>/<relnode>[_fsm|_vm|_init]
      56              : /// ```
      57              : impl fmt::Display for RelTag {
      58            0 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
      59            0 :         if let Some(forkname) = forknumber_to_name(self.forknum) {
      60            0 :             write!(
      61            0 :                 f,
      62            0 :                 "{}/{}/{}_{}",
      63            0 :                 self.spcnode, self.dbnode, self.relnode, forkname
      64            0 :             )
      65              :         } else {
      66            0 :             write!(f, "{}/{}/{}", self.spcnode, self.dbnode, self.relnode)
      67              :         }
      68            0 :     }
      69              : }
      70              : 
      71              : impl RelTag {
      72            0 :     pub fn to_segfile_name(&self, segno: u32) -> String {
      73            0 :         let mut name = if self.spcnode == GLOBALTABLESPACE_OID {
      74            0 :             "global/".to_string()
      75              :         } else {
      76            0 :             format!("base/{}/", self.dbnode)
      77              :         };
      78              : 
      79            0 :         name += &self.relnode.to_string();
      80              : 
      81            0 :         if let Some(fork_name) = forknumber_to_name(self.forknum) {
      82            0 :             name += "_";
      83            0 :             name += fork_name;
      84            0 :         }
      85              : 
      86            0 :         if segno != 0 {
      87            0 :             name += ".";
      88            0 :             name += &segno.to_string();
      89            0 :         }
      90              : 
      91            0 :         name
      92            0 :     }
      93              : 
      94            0 :     pub fn with_forknum(&self, forknum: u8) -> Self {
      95            0 :         RelTag {
      96            0 :             forknum,
      97            0 :             spcnode: self.spcnode,
      98            0 :             dbnode: self.dbnode,
      99            0 :             relnode: self.relnode,
     100            0 :         }
     101            0 :     }
     102              : }
     103              : 
     104              : ///
     105              : /// Non-relation transaction status files (clog (a.k.a. pg_xact) and
     106              : /// pg_multixact) in Postgres are handled by SLRU (Simple LRU) buffer,
     107              : /// hence the name.
     108              : ///
     109              : /// These files are global for a postgres instance.
     110              : ///
     111              : /// These files are divided into segments, which are divided into
     112              : /// pages of the same BLCKSZ as used for relation files.
     113              : ///
     114              : #[derive(
     115              :     Debug,
     116              :     Clone,
     117              :     Copy,
     118              :     Hash,
     119              :     Serialize,
     120            0 :     Deserialize,
     121              :     PartialEq,
     122              :     Eq,
     123              :     PartialOrd,
     124              :     Ord,
     125            0 :     strum_macros::EnumIter,
     126            0 :     strum_macros::FromRepr,
     127              :     enum_map::Enum,
     128              : )]
     129              : #[repr(u8)]
     130              : pub enum SlruKind {
     131              :     Clog = 0,
     132              :     MultiXactMembers,
     133              :     MultiXactOffsets,
     134              : }
     135              : 
     136              : impl SlruKind {
     137            0 :     pub fn to_str(&self) -> &'static str {
     138            0 :         match self {
     139            0 :             Self::Clog => "pg_xact",
     140            0 :             Self::MultiXactMembers => "pg_multixact/members",
     141            0 :             Self::MultiXactOffsets => "pg_multixact/offsets",
     142              :         }
     143            0 :     }
     144              : }
        

Generated by: LCOV version 2.1-beta