1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
use crate::{pg_sys, AllocatedByRust, PgBox};
#[inline]
pub unsafe fn item_pointer_get_block_number(
ctid: *const pg_sys::ItemPointerData,
) -> pg_sys::BlockNumber {
assert!(item_pointer_is_valid(ctid));
item_pointer_get_block_number_no_check(*ctid)
}
#[inline]
pub unsafe fn item_pointer_get_offset_number(
ctid: *const pg_sys::ItemPointerData,
) -> pg_sys::OffsetNumber {
assert!(item_pointer_is_valid(ctid));
item_pointer_get_offset_number_no_check(*ctid)
}
#[inline]
pub unsafe fn item_pointer_get_block_number_no_check(
ctid: pg_sys::ItemPointerData,
) -> pg_sys::BlockNumber {
let block_id = ctid.ip_blkid;
(((block_id.bi_hi as u32) << 16) | (block_id.bi_lo as u32)) as pg_sys::BlockNumber
}
#[inline]
pub unsafe fn item_pointer_get_offset_number_no_check(
ctid: pg_sys::ItemPointerData,
) -> pg_sys::OffsetNumber {
ctid.ip_posid
}
#[inline]
pub fn item_pointer_get_both(
ctid: pg_sys::ItemPointerData,
) -> (pg_sys::BlockNumber, pg_sys::OffsetNumber) {
unsafe {
(
item_pointer_get_block_number_no_check(ctid),
item_pointer_get_offset_number_no_check(ctid),
)
}
}
#[inline]
pub fn item_pointer_set_all(
tid: &mut pg_sys::ItemPointerData,
blockno: pg_sys::BlockNumber,
offno: pg_sys::OffsetNumber,
) {
tid.ip_posid = offno;
tid.ip_blkid.bi_hi = (blockno >> 16).try_into().unwrap();
tid.ip_blkid.bi_lo = (blockno & 0xffff).try_into().unwrap();
}
#[inline]
pub fn item_pointer_to_u64(ctid: pg_sys::ItemPointerData) -> u64 {
let (blockno, offno) = item_pointer_get_both(ctid);
let blockno = blockno as u64;
let offno = offno as u64;
(blockno << 32) | offno
}
#[inline]
pub fn u64_to_item_pointer(value: u64, tid: &mut pg_sys::ItemPointerData) {
let blockno = (value >> 32) as pg_sys::BlockNumber;
let offno = value as pg_sys::OffsetNumber;
item_pointer_set_all(tid, blockno, offno);
}
#[inline]
pub fn u64_to_item_pointer_parts(value: u64) -> (pg_sys::BlockNumber, pg_sys::OffsetNumber) {
let blockno = (value >> 32) as pg_sys::BlockNumber;
let offno = value as pg_sys::OffsetNumber;
(blockno, offno)
}
#[allow(clippy::not_unsafe_ptr_arg_deref)] #[inline]
pub unsafe fn item_pointer_is_valid(ctid: *const pg_sys::ItemPointerData) -> bool {
if ctid.is_null() {
false
} else {
(*ctid).ip_posid != pg_sys::InvalidOffsetNumber
}
}
#[inline]
pub fn new_item_pointer(
blockno: pg_sys::BlockNumber,
offno: pg_sys::OffsetNumber,
) -> PgBox<pg_sys::ItemPointerData, AllocatedByRust> {
let mut tid = PgBox::<pg_sys::ItemPointerData>::alloc();
tid.ip_blkid.bi_hi = (blockno >> 16) as u16;
tid.ip_blkid.bi_lo = (blockno & 0xffff) as u16;
tid.ip_posid = offno;
tid
}