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
use crate::{pg_sys, 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,
) {
use std::convert::TryInto;
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 fn item_pointer_is_valid(ctid: *const pg_sys::ItemPointerData) -> bool {
if ctid.is_null() {
false
} else {
unsafe { *ctid }.ip_posid != pg_sys::InvalidOffsetNumber
}
}
#[inline]
pub fn new_item_pointer(
blockno: pg_sys::BlockNumber,
offno: pg_sys::OffsetNumber,
) -> PgBox<pg_sys::ItemPointerData> {
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
}