LCOV - differential code coverage report
Current view: top level - pageserver/src - repository.rs (source / functions) Coverage Total Hit UBC CBC
Current: cd44433dd675caa99df17a61b18949c8387e2242.info Lines: 95.8 % 72 69 3 69
Current Date: 2024-01-09 02:06:09 Functions: 65.5 % 29 19 10 19
Baseline: 66c52a629a0f4a503e193045e0df4c77139e344b.info
Baseline Date: 2024-01-08 15:34:46

           TLA  Line data    Source code
       1                 : use crate::walrecord::NeonWalRecord;
       2                 : use anyhow::Result;
       3                 : use bytes::Bytes;
       4                 : use serde::{Deserialize, Serialize};
       5                 : use std::ops::AddAssign;
       6                 : use std::time::Duration;
       7                 : 
       8                 : pub use pageserver_api::key::{Key, KEY_SIZE};
       9                 : 
      10                 : /// A 'value' stored for a one Key.
      11 CBC   243603606 : #[derive(Debug, Clone, Serialize, Deserialize)]
      12               2 : #[cfg_attr(test, derive(PartialEq))]
      13                 : pub enum Value {
      14                 :     /// An Image value contains a full copy of the value
      15                 :     Image(Bytes),
      16                 :     /// A WalRecord value contains a WAL record that needs to be
      17                 :     /// replayed get the full value. Replaying the WAL record
      18                 :     /// might need a previous version of the value (if will_init()
      19                 :     /// returns false), or it may be replayed stand-alone (true).
      20                 :     WalRecord(NeonWalRecord),
      21                 : }
      22                 : 
      23                 : impl Value {
      24 UBC           0 :     pub fn is_image(&self) -> bool {
      25               0 :         matches!(self, Value::Image(_))
      26               0 :     }
      27                 : 
      28 CBC    46500454 :     pub fn will_init(&self) -> bool {
      29        46500454 :         match self {
      30         5473995 :             Value::Image(_) => true,
      31        41026459 :             Value::WalRecord(rec) => rec.will_init(),
      32                 :         }
      33        46500454 :     }
      34                 : }
      35                 : 
      36                 : #[cfg(test)]
      37                 : mod test {
      38                 :     use super::*;
      39                 : 
      40                 :     use bytes::Bytes;
      41                 :     use utils::bin_ser::BeSer;
      42                 : 
      43                 :     macro_rules! roundtrip {
      44                 :         ($orig:expr, $expected:expr) => {{
      45                 :             let orig: Value = $orig;
      46                 : 
      47                 :             let actual = Value::ser(&orig).unwrap();
      48                 :             let expected: &[u8] = &$expected;
      49                 : 
      50                 :             assert_eq!(utils::Hex(&actual), utils::Hex(expected));
      51                 : 
      52                 :             let deser = Value::des(&actual).unwrap();
      53                 : 
      54                 :             assert_eq!(orig, deser);
      55                 :         }};
      56                 :     }
      57                 : 
      58               1 :     #[test]
      59               1 :     fn image_roundtrip() {
      60               1 :         let image = Bytes::from_static(b"foobar");
      61               1 :         let image = Value::Image(image);
      62               1 : 
      63               1 :         #[rustfmt::skip]
      64               1 :         let expected = [
      65               1 :             // top level discriminator of 4 bytes
      66               1 :             0x00, 0x00, 0x00, 0x00,
      67               1 :             // 8 byte length
      68               1 :             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
      69               1 :             // foobar
      70               1 :             0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72
      71               1 :         ];
      72               1 : 
      73               1 :         roundtrip!(image, expected);
      74               1 :     }
      75                 : 
      76               1 :     #[test]
      77               1 :     fn walrecord_postgres_roundtrip() {
      78               1 :         let rec = NeonWalRecord::Postgres {
      79               1 :             will_init: true,
      80               1 :             rec: Bytes::from_static(b"foobar"),
      81               1 :         };
      82               1 :         let rec = Value::WalRecord(rec);
      83               1 : 
      84               1 :         #[rustfmt::skip]
      85               1 :         let expected = [
      86               1 :             // flattened discriminator of total 8 bytes
      87               1 :             0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
      88               1 :             // will_init
      89               1 :             0x01,
      90               1 :             // 8 byte length
      91               1 :             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
      92               1 :             // foobar
      93               1 :             0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72
      94               1 :         ];
      95               1 : 
      96               1 :         roundtrip!(rec, expected);
      97               1 :     }
      98                 : }
      99                 : 
     100                 : ///
     101                 : /// Result of performing GC
     102                 : ///
     103            1012 : #[derive(Default, Serialize, Debug)]
     104                 : pub struct GcResult {
     105                 :     pub layers_total: u64,
     106                 :     pub layers_needed_by_cutoff: u64,
     107                 :     pub layers_needed_by_pitr: u64,
     108                 :     pub layers_needed_by_branches: u64,
     109                 :     pub layers_not_updated: u64,
     110                 :     pub layers_removed: u64, // # of layer files removed because they have been made obsolete by newer ondisk files.
     111                 : 
     112                 :     #[serde(serialize_with = "serialize_duration_as_millis")]
     113                 :     pub elapsed: Duration,
     114                 : 
     115                 :     /// The layers which were garbage collected.
     116                 :     ///
     117                 :     /// Used in `/v1/tenant/:tenant_id/timeline/:timeline_id/do_gc` to wait for the layers to be
     118                 :     /// dropped in tests.
     119                 :     #[cfg(feature = "testing")]
     120                 :     #[serde(skip)]
     121                 :     pub(crate) doomed_layers: Vec<crate::tenant::storage_layer::Layer>,
     122                 : }
     123                 : 
     124                 : // helper function for `GcResult`, serializing a `Duration` as an integer number of milliseconds
     125             320 : fn serialize_duration_as_millis<S>(d: &Duration, serializer: S) -> Result<S::Ok, S::Error>
     126             320 : where
     127             320 :     S: serde::Serializer,
     128             320 : {
     129             320 :     d.as_millis().serialize(serializer)
     130             320 : }
     131                 : 
     132                 : impl AddAssign for GcResult {
     133             491 :     fn add_assign(&mut self, other: Self) {
     134             491 :         self.layers_total += other.layers_total;
     135             491 :         self.layers_needed_by_pitr += other.layers_needed_by_pitr;
     136             491 :         self.layers_needed_by_cutoff += other.layers_needed_by_cutoff;
     137             491 :         self.layers_needed_by_branches += other.layers_needed_by_branches;
     138             491 :         self.layers_not_updated += other.layers_not_updated;
     139             491 :         self.layers_removed += other.layers_removed;
     140             491 : 
     141             491 :         self.elapsed += other.elapsed;
     142             491 : 
     143             491 :         #[cfg(feature = "testing")]
     144             491 :         {
     145             491 :             let mut other = other;
     146             491 :             self.doomed_layers.append(&mut other.doomed_layers);
     147             491 :         }
     148             491 :     }
     149                 : }
        

Generated by: LCOV version 2.1-beta