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 = unsafe { 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
}