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 : }
|