LCOV - code coverage report
Current view: top level - pageserver/src - repository.rs (source / functions) Coverage Total Hit
Test: 8ac049b474321fdc72ddcb56d7165153a1a900e8.info Lines: 84.6 % 136 115
Test Date: 2023-09-06 10:18:01 Functions: 62.7 % 51 32

            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    445812416 : #[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    201501448 :     pub fn to_i128(&self) -> i128 {
      31    201501448 :         assert!(self.field2 < 0xFFFF || self.field2 == 0xFFFFFFFF || self.field2 == 0x22222222);
      32    201501448 :         (((self.field1 & 0xf) as i128) << 120)
      33    201501448 :             | (((self.field2 & 0xFFFF) as i128) << 104)
      34    201501448 :             | ((self.field3 as i128) << 72)
      35    201501448 :             | ((self.field4 as i128) << 40)
      36    201501448 :             | ((self.field5 as i128) << 32)
      37    201501448 :             | self.field6 as i128
      38    201501448 :     }
      39              : 
      40     27658756 :     pub fn from_i128(x: i128) -> Self {
      41     27658756 :         Key {
      42     27658756 :             field1: ((x >> 120) & 0xf) as u8,
      43     27658756 :             field2: ((x >> 104) & 0xFFFF) as u32,
      44     27658756 :             field3: (x >> 72) as u32,
      45     27658756 :             field4: (x >> 40) as u32,
      46     27658756 :             field5: (x >> 32) as u8,
      47     27658756 :             field6: x as u32,
      48     27658756 :         }
      49     27658756 :     }
      50              : 
      51     41868897 :     pub fn next(&self) -> Key {
      52     41868897 :         self.add(1)
      53     41868897 :     }
      54              : 
      55     41871847 :     pub fn add(&self, x: u32) -> Key {
      56     41871847 :         let mut key = *self;
      57     41871847 : 
      58     41871847 :         let r = key.field6.overflowing_add(x);
      59     41871847 :         key.field6 = r.0;
      60     41871847 :         if r.1 {
      61      1238468 :             let r = key.field5.overflowing_add(1);
      62      1238468 :             key.field5 = r.0;
      63      1238468 :             if r.1 {
      64            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      1238468 :             }
      80     40633379 :         }
      81     41871847 :         key
      82     41871847 :     }
      83              : 
      84     46455423 :     pub fn from_slice(b: &[u8]) -> Self {
      85     46455423 :         Key {
      86     46455423 :             field1: b[0],
      87     46455423 :             field2: u32::from_be_bytes(b[1..5].try_into().unwrap()),
      88     46455423 :             field3: u32::from_be_bytes(b[5..9].try_into().unwrap()),
      89     46455423 :             field4: u32::from_be_bytes(b[9..13].try_into().unwrap()),
      90     46455423 :             field5: b[13],
      91     46455423 :             field6: u32::from_be_bytes(b[14..18].try_into().unwrap()),
      92     46455423 :         }
      93     46455423 :     }
      94              : 
      95    137416216 :     pub fn write_to_byte_slice(&self, buf: &mut [u8]) {
      96    137416216 :         buf[0] = self.field1;
      97    137416216 :         BE::write_u32(&mut buf[1..5], self.field2);
      98    137416216 :         BE::write_u32(&mut buf[5..9], self.field3);
      99    137416216 :         BE::write_u32(&mut buf[9..13], self.field4);
     100    137416216 :         buf[13] = self.field5;
     101    137416216 :         BE::write_u32(&mut buf[14..18], self.field6);
     102    137416216 :     }
     103              : }
     104              : 
     105       960744 : pub fn key_range_size(key_range: &Range<Key>) -> u32 {
     106       960744 :     let start = key_range.start;
     107       960744 :     let end = key_range.end;
     108       960744 : 
     109       960744 :     if end.field1 != start.field1
     110       960744 :         || end.field2 != start.field2
     111       960744 :         || end.field3 != start.field3
     112       960744 :         || end.field4 != start.field4
     113              :     {
     114            0 :         return u32::MAX;
     115       960744 :     }
     116       960744 : 
     117       960744 :     let start = (start.field5 as u64) << 32 | start.field6 as u64;
     118       960744 :     let end = (end.field5 as u64) << 32 | end.field6 as u64;
     119       960744 : 
     120       960744 :     let diff = end - start;
     121       960744 :     if diff > u32::MAX as u64 {
     122            0 :         u32::MAX
     123              :     } else {
     124       960744 :         diff as u32
     125              :     }
     126       960744 : }
     127              : 
     128      1064920 : pub fn singleton_range(key: Key) -> Range<Key> {
     129      1064920 :     key..key.next()
     130      1064920 : }
     131              : 
     132              : impl fmt::Display for Key {
     133       965106 :     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     134       965106 :         write!(
     135       965106 :             f,
     136       965106 :             "{:02X}{:08X}{:08X}{:08X}{:02X}{:08X}",
     137       965106 :             self.field1, self.field2, self.field3, self.field4, self.field5, self.field6
     138       965106 :         )
     139       965106 :     }
     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        38704 :     pub fn from_hex(s: &str) -> Result<Self> {
     161        38704 :         if s.len() != 36 {
     162            0 :             bail!("parse error");
     163        38704 :         }
     164        38704 :         Ok(Key {
     165        38704 :             field1: u8::from_str_radix(&s[0..2], 16)?,
     166        38704 :             field2: u32::from_str_radix(&s[2..10], 16)?,
     167        38704 :             field3: u32::from_str_radix(&s[10..18], 16)?,
     168        38704 :             field4: u32::from_str_radix(&s[18..26], 16)?,
     169        38704 :             field5: u8::from_str_radix(&s[26..28], 16)?,
     170        38704 :             field6: u32::from_str_radix(&s[28..36], 16)?,
     171              :         })
     172        38704 :     }
     173              : }
     174              : 
     175              : /// A 'value' stored for a one Key.
     176    604188972 : #[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            0 :     pub fn is_image(&self) -> bool {
     189            0 :         matches!(self, Value::Image(_))
     190            0 :     }
     191              : 
     192     91515745 :     pub fn will_init(&self) -> bool {
     193     91515745 :         match self {
     194      6102639 :             Value::Image(_) => true,
     195     85413106 :             Value::WalRecord(rec) => rec.will_init(),
     196              :         }
     197     91515745 :     }
     198              : }
     199              : 
     200              : ///
     201              : /// Result of performing GC
     202              : ///
     203         1380 : #[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          503 : fn serialize_duration_as_millis<S>(d: &Duration, serializer: S) -> Result<S::Ok, S::Error>
     218          503 : where
     219          503 :     S: serde::Serializer,
     220          503 : {
     221          503 :     d.as_millis().serialize(serializer)
     222          503 : }
     223              : 
     224              : impl AddAssign for GcResult {
     225          681 :     fn add_assign(&mut self, other: Self) {
     226          681 :         self.layers_total += other.layers_total;
     227          681 :         self.layers_needed_by_pitr += other.layers_needed_by_pitr;
     228          681 :         self.layers_needed_by_cutoff += other.layers_needed_by_cutoff;
     229          681 :         self.layers_needed_by_branches += other.layers_needed_by_branches;
     230          681 :         self.layers_not_updated += other.layers_not_updated;
     231          681 :         self.layers_removed += other.layers_removed;
     232          681 : 
     233          681 :         self.elapsed += other.elapsed;
     234          681 :     }
     235              : }
        

Generated by: LCOV version 2.1-beta