use std::ptr as StdPtr;
use seize::LocalGuard;
use crate::internode::InternodeNode;
use crate::ksearch::upper_bound_internode_generic;
use crate::leaf15::LeafNode15;
use crate::nodeversion::NodeVersion;
use crate::policy::LeafPolicy;
use crate::prefetch::prefetch_read;
use super::cursor_key::CursorKey;
#[inline]
pub fn reach_leaf_for_scan<P>(
start: *const u8,
cursor_key: &CursorKey,
_guard: &LocalGuard<'_>,
) -> *mut LeafNode15<P>
where
P: LeafPolicy,
{
if start.is_null() {
return StdPtr::null_mut();
}
let target_ikey: u64 = cursor_key.current_ikey();
let mut node: *const u8 = start;
loop {
#[expect(clippy::cast_ptr_alignment, reason = "proper alignment")]
let version: &NodeVersion = unsafe { &*(node.cast::<NodeVersion>()) };
let v: u32 = version.stable();
if version.is_leaf() {
return node.cast_mut().cast::<LeafNode15<P>>();
}
let inode: &InternodeNode = unsafe { &*(node.cast::<InternodeNode>()) };
let child_idx: usize = upper_bound_internode_generic::<InternodeNode>(target_ikey, inode);
let child: *mut u8 = unsafe { inode.child_unguarded(child_idx) };
prefetch_read(child);
if child.is_null() {
node = start;
continue;
}
if inode.version().has_changed(v) {
if inode.version().has_split(v) {
node = start;
continue;
}
continue;
}
node = child;
}
}