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 8 : pub(crate) fn build_begin_redo_for_block_msg(tag: BufferTag, buf: &mut Vec<u8>) {
20 8 : let len = 4 + 1 + 4 * 4;
21 8 :
22 8 : buf.put_u8(b'B');
23 8 : buf.put_u32(len as u32);
24 8 :
25 8 : tag.ser_into(buf)
26 8 : .expect("serialize BufferTag should always succeed");
27 8 : }
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 16 : pub(crate) fn build_apply_record_msg(endlsn: Lsn, rec: &[u8], buf: &mut Vec<u8>) {
42 16 : let len = 4 + 8 + rec.len();
43 16 :
44 16 : buf.put_u8(b'A');
45 16 : buf.put_u32(len as u32);
46 16 : buf.put_u64(endlsn.0);
47 16 : buf.put(rec);
48 16 : }
49 :
50 8 : pub(crate) fn build_get_page_msg(tag: BufferTag, buf: &mut Vec<u8>) {
51 8 : let len = 4 + 1 + 4 * 4;
52 8 :
53 8 : buf.put_u8(b'G');
54 8 : buf.put_u32(len as u32);
55 8 : tag.ser_into(buf)
56 8 : .expect("serialize BufferTag should always succeed");
57 8 : }
58 :
59 2 : pub(crate) fn build_ping_msg(buf: &mut Vec<u8>) {
60 2 : buf.put_u8(b'H');
61 2 : buf.put_u32(4);
62 2 : }
|