use core::ptr::NonNull;
use mnemosyne_core::types::Page;
#[inline(always)]
pub(crate) unsafe fn push_page_front_raw(
raw_page: NonNull<Page>,
head_slot: &mut Option<NonNull<Page>>,
list_state: u8,
) {
unsafe {
(*raw_page.as_ptr()).next_page = *head_slot;
(*raw_page.as_ptr()).prev_page = None;
}
if let Some(head) = *head_slot {
unsafe {
(*head.as_ptr()).prev_page = Some(raw_page);
}
}
*head_slot = Some(raw_page);
unsafe { (*raw_page.as_ptr()).list_state = list_state };
let page_index = unsafe { (*raw_page.as_ptr()).page_index };
if page_index > 0 {
let segment = unsafe { Page::parent_segment_of(raw_page.as_ptr()) };
unsafe {
(*segment).page_linked_mask |= 1 << page_index;
}
}
}
#[inline(always)]
pub(crate) unsafe fn unlink_page_from_list_raw(
raw_page: NonNull<Page>,
head_slot: &mut Option<NonNull<Page>>,
) {
let next = unsafe { (*raw_page.as_ptr()).next_page };
let prev = unsafe { (*raw_page.as_ptr()).prev_page };
if let Some(prev_ptr) = prev {
unsafe { (*prev_ptr.as_ptr()).next_page = next };
} else {
*head_slot = next;
}
if let Some(next_ptr) = next {
unsafe { (*next_ptr.as_ptr()).prev_page = prev };
}
unsafe {
(*raw_page.as_ptr()).next_page = None;
(*raw_page.as_ptr()).prev_page = None;
(*raw_page.as_ptr()).list_state = 0;
}
let page_index = unsafe { (*raw_page.as_ptr()).page_index };
if page_index > 0 {
let segment = unsafe { Page::parent_segment_of(raw_page.as_ptr()) };
unsafe { (*segment).page_linked_mask &= !(1 << page_index) };
}
}
#[inline(always)]
pub(crate) unsafe fn move_page_raw(
raw_page: NonNull<Page>,
from_head_slot: &mut Option<NonNull<Page>>,
to_head_slot: &mut Option<NonNull<Page>>,
new_state: u8,
) {
let next = unsafe { (*raw_page.as_ptr()).next_page };
let prev = unsafe { (*raw_page.as_ptr()).prev_page };
if let Some(prev_ptr) = prev {
unsafe { (*prev_ptr.as_ptr()).next_page = next };
} else {
*from_head_slot = next;
}
if let Some(next_ptr) = next {
unsafe { (*next_ptr.as_ptr()).prev_page = prev };
}
let head = *to_head_slot;
unsafe {
(*raw_page.as_ptr()).next_page = head;
(*raw_page.as_ptr()).prev_page = None;
}
if let Some(head_ptr) = head {
unsafe { (*head_ptr.as_ptr()).prev_page = Some(raw_page) };
}
*to_head_slot = Some(raw_page);
unsafe { (*raw_page.as_ptr()).list_state = new_state };
}