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