Line data Source code
1 : use bytes::BufMut;
2 : use pageserver_api::reltag::RelTag;
3 : use serde::Serialize;
4 : use utils::bin_ser::BeSer;
5 : use utils::lsn::Lsn;
6 :
7 : ///
8 : /// `RelTag` + block number (`blknum`) gives us a unique id of the page in the cluster.
9 : ///
10 : /// In Postgres `BufferTag` structure is used for exactly the same purpose.
11 : /// [See more related comments here](https://github.com/postgres/postgres/blob/99c5852e20a0987eca1c38ba0c09329d4076b6a0/src/include/storage/buf_internals.h#L91).
12 : ///
13 : #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Serialize)]
14 : pub(crate) struct BufferTag {
15 : pub rel: RelTag,
16 : pub blknum: u32,
17 : }
18 :
19 24 : pub(crate) fn build_begin_redo_for_block_msg(tag: BufferTag, buf: &mut Vec<u8>) {
20 24 : let len = 4 + 1 + 4 * 4;
21 24 :
22 24 : buf.put_u8(b'B');
23 24 : buf.put_u32(len as u32);
24 24 :
25 24 : tag.ser_into(buf)
26 24 : .expect("serialize BufferTag should always succeed");
27 24 : }
28 :
29 0 : pub(crate) fn build_push_page_msg(tag: BufferTag, base_img: &[u8], buf: &mut Vec<u8>) {
30 0 : assert!(base_img.len() == 8192);
31 :
32 0 : let len = 4 + 1 + 4 * 4 + base_img.len();
33 0 :
34 0 : buf.put_u8(b'P');
35 0 : buf.put_u32(len as u32);
36 0 : tag.ser_into(buf)
37 0 : .expect("serialize BufferTag should always succeed");
38 0 : buf.put(base_img);
39 0 : }
40 :
41 48 : pub(crate) fn build_apply_record_msg(endlsn: Lsn, rec: &[u8], buf: &mut Vec<u8>) {
42 48 : let len = 4 + 8 + rec.len();
43 48 :
44 48 : buf.put_u8(b'A');
45 48 : buf.put_u32(len as u32);
46 48 : buf.put_u64(endlsn.0);
47 48 : buf.put(rec);
48 48 : }
49 :
50 24 : pub(crate) fn build_get_page_msg(tag: BufferTag, buf: &mut Vec<u8>) {
51 24 : let len = 4 + 1 + 4 * 4;
52 24 :
53 24 : buf.put_u8(b'G');
54 24 : buf.put_u32(len as u32);
55 24 : tag.ser_into(buf)
56 24 : .expect("serialize BufferTag should always succeed");
57 24 : }
58 :
59 6 : pub(crate) fn build_ping_msg(buf: &mut Vec<u8>) {
60 6 : buf.put_u8(b'H');
61 6 : buf.put_u32(4);
62 6 : }
|