LCOV - differential code coverage report
Current view: top level - pageserver/src - repository.rs (source / functions) Coverage Total Hit UBC CBC
Current: f6946e90941b557c917ac98cd5a7e9506d180f3e.info Lines: 84.6 % 136 115 21 115
Current Date: 2023-10-19 02:04:12 Functions: 64.7 % 51 33 18 33
Baseline: c8637f37369098875162f194f92736355783b050.info
Baseline Date: 2023-10-18 20:25:20

           TLA  Line data    Source code
       1                 : use crate::walrecord::NeonWalRecord;
       2                 : use anyhow::{bail, Result};
       3                 : use byteorder::{ByteOrder, BE};
       4                 : use bytes::Bytes;
       5                 : use serde::{Deserialize, Serialize};
       6                 : use std::fmt;
       7                 : use std::ops::{AddAssign, Range};
       8                 : use std::time::Duration;
       9                 : 
      10                 : /// Key used in the Repository kv-store.
      11                 : ///
      12                 : /// The Repository treats this as an opaque struct, but see the code in pgdatadir_mapping.rs
      13                 : /// for what we actually store in these fields.
      14 CBC   269522787 : #[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, Ord, PartialOrd, Serialize, Deserialize)]
      15                 : pub struct Key {
      16                 :     pub field1: u8,
      17                 :     pub field2: u32,
      18                 :     pub field3: u32,
      19                 :     pub field4: u32,
      20                 :     pub field5: u8,
      21                 :     pub field6: u32,
      22                 : }
      23                 : 
      24                 : pub const KEY_SIZE: usize = 18;
      25                 : 
      26                 : impl Key {
      27                 :     /// 'field2' is used to store tablespaceid for relations and small enum numbers for other relish.
      28                 :     /// As long as Neon does not support tablespace (because of lack of access to local file system),
      29                 :     /// we can assume that only some predefined namespace OIDs are used which can fit in u16
      30       127229284 :     pub fn to_i128(&self) -> i128 {
      31       127229284 :         assert!(self.field2 < 0xFFFF || self.field2 == 0xFFFFFFFF || self.field2 == 0x22222222);
      32       127229284 :         (((self.field1 & 0xf) as i128) << 120)
      33       127229284 :             | (((self.field2 & 0xFFFF) as i128) << 104)
      34       127229284 :             | ((self.field3 as i128) << 72)
      35       127229284 :             | ((self.field4 as i128) << 40)
      36       127229284 :             | ((self.field5 as i128) << 32)
      37       127229284 :             | self.field6 as i128
      38       127229284 :     }
      39                 : 
      40        18071000 :     pub const fn from_i128(x: i128) -> Self {
      41        18071000 :         Key {
      42        18071000 :             field1: ((x >> 120) & 0xf) as u8,
      43        18071000 :             field2: ((x >> 104) & 0xFFFF) as u32,
      44        18071000 :             field3: (x >> 72) as u32,
      45        18071000 :             field4: (x >> 40) as u32,
      46        18071000 :             field5: (x >> 32) as u8,
      47        18071000 :             field6: x as u32,
      48        18071000 :         }
      49        18071000 :     }
      50                 : 
      51        31537951 :     pub fn next(&self) -> Key {
      52        31537951 :         self.add(1)
      53        31537951 :     }
      54                 : 
      55        31542614 :     pub fn add(&self, x: u32) -> Key {
      56        31542614 :         let mut key = *self;
      57        31542614 : 
      58        31542614 :         let r = key.field6.overflowing_add(x);
      59        31542614 :         key.field6 = r.0;
      60        31542614 :         if r.1 {
      61         1248656 :             let r = key.field5.overflowing_add(1);
      62         1248656 :             key.field5 = r.0;
      63         1248656 :             if r.1 {
      64 UBC           0 :                 let r = key.field4.overflowing_add(1);
      65               0 :                 key.field4 = r.0;
      66               0 :                 if r.1 {
      67               0 :                     let r = key.field3.overflowing_add(1);
      68               0 :                     key.field3 = r.0;
      69               0 :                     if r.1 {
      70               0 :                         let r = key.field2.overflowing_add(1);
      71               0 :                         key.field2 = r.0;
      72               0 :                         if r.1 {
      73               0 :                             let r = key.field1.overflowing_add(1);
      74               0 :                             key.field1 = r.0;
      75               0 :                             assert!(!r.1);
      76               0 :                         }
      77               0 :                     }
      78               0 :                 }
      79 CBC     1248656 :             }
      80        30293958 :         }
      81        31542614 :         key
      82        31542614 :     }
      83                 : 
      84        30235447 :     pub fn from_slice(b: &[u8]) -> Self {
      85        30235447 :         Key {
      86        30235447 :             field1: b[0],
      87        30235447 :             field2: u32::from_be_bytes(b[1..5].try_into().unwrap()),
      88        30235447 :             field3: u32::from_be_bytes(b[5..9].try_into().unwrap()),
      89        30235447 :             field4: u32::from_be_bytes(b[9..13].try_into().unwrap()),
      90        30235447 :             field5: b[13],
      91        30235447 :             field6: u32::from_be_bytes(b[14..18].try_into().unwrap()),
      92        30235447 :         }
      93        30235447 :     }
      94                 : 
      95       106804563 :     pub fn write_to_byte_slice(&self, buf: &mut [u8]) {
      96       106804563 :         buf[0] = self.field1;
      97       106804563 :         BE::write_u32(&mut buf[1..5], self.field2);
      98       106804563 :         BE::write_u32(&mut buf[5..9], self.field3);
      99       106804563 :         BE::write_u32(&mut buf[9..13], self.field4);
     100       106804563 :         buf[13] = self.field5;
     101       106804563 :         BE::write_u32(&mut buf[14..18], self.field6);
     102       106804563 :     }
     103                 : }
     104                 : 
     105          965489 : pub fn key_range_size(key_range: &Range<Key>) -> u32 {
     106          965489 :     let start = key_range.start;
     107          965489 :     let end = key_range.end;
     108          965489 : 
     109          965489 :     if end.field1 != start.field1
     110          965489 :         || end.field2 != start.field2
     111          965489 :         || end.field3 != start.field3
     112          965489 :         || end.field4 != start.field4
     113                 :     {
     114 UBC           0 :         return u32::MAX;
     115 CBC      965489 :     }
     116          965489 : 
     117          965489 :     let start = (start.field5 as u64) << 32 | start.field6 as u64;
     118          965489 :     let end = (end.field5 as u64) << 32 | end.field6 as u64;
     119          965489 : 
     120          965489 :     let diff = end - start;
     121          965489 :     if diff > u32::MAX as u64 {
     122 UBC           0 :         u32::MAX
     123                 :     } else {
     124 CBC      965489 :         diff as u32
     125                 :     }
     126          965489 : }
     127                 : 
     128         1067974 : pub fn singleton_range(key: Key) -> Range<Key> {
     129         1067974 :     key..key.next()
     130         1067974 : }
     131                 : 
     132                 : impl fmt::Display for Key {
     133         1272239 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     134         1272239 :         write!(
     135         1272239 :             f,
     136         1272239 :             "{:02X}{:08X}{:08X}{:08X}{:02X}{:08X}",
     137         1272239 :             self.field1, self.field2, self.field3, self.field4, self.field5, self.field6
     138         1272239 :         )
     139         1272239 :     }
     140                 : }
     141                 : 
     142                 : impl Key {
     143                 :     pub const MIN: Key = Key {
     144                 :         field1: u8::MIN,
     145                 :         field2: u32::MIN,
     146                 :         field3: u32::MIN,
     147                 :         field4: u32::MIN,
     148                 :         field5: u8::MIN,
     149                 :         field6: u32::MIN,
     150                 :     };
     151                 :     pub const MAX: Key = Key {
     152                 :         field1: u8::MAX,
     153                 :         field2: u32::MAX,
     154                 :         field3: u32::MAX,
     155                 :         field4: u32::MAX,
     156                 :         field5: u8::MAX,
     157                 :         field6: u32::MAX,
     158                 :     };
     159                 : 
     160           43192 :     pub fn from_hex(s: &str) -> Result<Self> {
     161           43192 :         if s.len() != 36 {
     162 UBC           0 :             bail!("parse error");
     163 CBC       43192 :         }
     164           43192 :         Ok(Key {
     165           43192 :             field1: u8::from_str_radix(&s[0..2], 16)?,
     166           43192 :             field2: u32::from_str_radix(&s[2..10], 16)?,
     167           43192 :             field3: u32::from_str_radix(&s[10..18], 16)?,
     168           43192 :             field4: u32::from_str_radix(&s[18..26], 16)?,
     169           43192 :             field5: u8::from_str_radix(&s[26..28], 16)?,
     170           43192 :             field6: u32::from_str_radix(&s[28..36], 16)?,
     171                 :         })
     172           43192 :     }
     173                 : }
     174                 : 
     175                 : /// A 'value' stored for a one Key.
     176       490870890 : #[derive(Debug, Clone, Serialize, Deserialize)]
     177                 : pub enum Value {
     178                 :     /// An Image value contains a full copy of the value
     179                 :     Image(Bytes),
     180                 :     /// A WalRecord value contains a WAL record that needs to be
     181                 :     /// replayed get the full value. Replaying the WAL record
     182                 :     /// might need a previous version of the value (if will_init()
     183                 :     /// returns false), or it may be replayed stand-alone (true).
     184                 :     WalRecord(NeonWalRecord),
     185                 : }
     186                 : 
     187                 : impl Value {
     188 UBC           0 :     pub fn is_image(&self) -> bool {
     189               0 :         matches!(self, Value::Image(_))
     190               0 :     }
     191                 : 
     192 CBC    82730202 :     pub fn will_init(&self) -> bool {
     193        82730202 :         match self {
     194         5869204 :             Value::Image(_) => true,
     195        76860998 :             Value::WalRecord(rec) => rec.will_init(),
     196                 :         }
     197        82730202 :     }
     198                 : }
     199                 : 
     200                 : ///
     201                 : /// Result of performing GC
     202                 : ///
     203            1101 : #[derive(Default, Serialize, Debug)]
     204                 : pub struct GcResult {
     205                 :     pub layers_total: u64,
     206                 :     pub layers_needed_by_cutoff: u64,
     207                 :     pub layers_needed_by_pitr: u64,
     208                 :     pub layers_needed_by_branches: u64,
     209                 :     pub layers_not_updated: u64,
     210                 :     pub layers_removed: u64, // # of layer files removed because they have been made obsolete by newer ondisk files.
     211                 : 
     212                 :     #[serde(serialize_with = "serialize_duration_as_millis")]
     213                 :     pub elapsed: Duration,
     214                 : }
     215                 : 
     216                 : // helper function for `GcResult`, serializing a `Duration` as an integer number of milliseconds
     217             369 : fn serialize_duration_as_millis<S>(d: &Duration, serializer: S) -> Result<S::Ok, S::Error>
     218             369 : where
     219             369 :     S: serde::Serializer,
     220             369 : {
     221             369 :     d.as_millis().serialize(serializer)
     222             369 : }
     223                 : 
     224                 : impl AddAssign for GcResult {
     225             540 :     fn add_assign(&mut self, other: Self) {
     226             540 :         self.layers_total += other.layers_total;
     227             540 :         self.layers_needed_by_pitr += other.layers_needed_by_pitr;
     228             540 :         self.layers_needed_by_cutoff += other.layers_needed_by_cutoff;
     229             540 :         self.layers_needed_by_branches += other.layers_needed_by_branches;
     230             540 :         self.layers_not_updated += other.layers_not_updated;
     231             540 :         self.layers_removed += other.layers_removed;
     232             540 : 
     233             540 :         self.elapsed += other.elapsed;
     234             540 :     }
     235                 : }
        

Generated by: LCOV version 2.1-beta