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