DV4A2LR7Q5LAEGAQHLO34PZCHGJUHPAMRZFGT7GUFNKVQKPJNOYQC
X3QVVQIS7B7L3XYZAWL3OOBUXOJ6RMOKQ45YMLLGAHYPEEKZ45ZAC
OP6SVMOD2GTQ7VNJ4E5KYFG4MIYA7HBMXJTADALMZH4PY7OQRMZQC
FMN7X4J24EYPOJNBUWM4NKGWSJTRV2DHCIBMPV2AXLZVVAMNOBKQC
EHJFNMB2R4MYG6ZSHHEENRFCSPFVWKVHLD5DXAE5HXUGXP5ZVHKQC
EAAYH6BQWDK52EC5RG3BEZQU3FJPN5RRRN4U5KDKDVPKXBVJMNDAC
WS4ZQM4RMIHZ6XZKSDQJGHN5SSSWFL4H236USOPUA33S6RC53RFAC
impl<T: AllocPage + core::fmt::Debug, K: Representable<T> + core::fmt::Debug, V: Representable<T> + core::fmt::Debug> super::BTreeMutPage<T, K, V>
for Page<K, V>
impl<
T: AllocPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
> super::BTreeMutPage<T, K, V> for Page<K, V>
fn replace<'a>(
txn: &mut T,
page: CowPage,
mutable: bool,
c: &Self::Cursor,
k0: &'a K,
v0: &'a V,
k1v1: Option<(&'a K, &'a V)>,
l: u64,
r: u64,
) -> Result<Put<'a, K, V>, T::Error> {
// We're never in a leaf if we're doing this.
assert!(l > 0);
let new = Self::del(txn, page, c, l)?;
Self::put(txn, new.0, mutable, c, k0, v0, k1v1, l, r)
}
unsafe { if c.is_leaf {
let n = hdr.n() as usize;
if let Some(f) = fixed_size::<T, K, V>() {
let al = K::ALIGN.max(V::ALIGN);
let hdr_size = (HDR + al - 1) & !(al - 1);
let off = c.cur * f;
let kv_ptr = p.add(hdr_size + off);
core::ptr::copy(kv_ptr.add(f), kv_ptr, f * (n - c.cur - 1));
hdr.decr(f);
} else {
let ptr = p.add(HDR + c.cur * 2) as *mut u16;
let kv_ptr = p.add((*ptr) as usize);
let size = entry_size::<T, K, V>(kv_ptr);
core::ptr::copy(ptr.offset(1), ptr, n - c.cur);
hdr.decr(size);
}
} else {
let ptr = p.add(HDR + c.cur * 8) as *mut u64;
let off = (u64::from_le(*ptr) & 0xfff) as usize;
let kv_ptr = p.add(off);
let size = entry_size::<T, K, V>(kv_ptr);
core::ptr::copy(ptr.offset(1), ptr, (&*hdr).n() as usize - c.cur);
(&mut *hdr).decr(size);
}};
unsafe {
if c.is_leaf {
let n = hdr.n() as usize;
if let Some(f) = fixed_size::<T, K, V>() {
let al = K::ALIGN.max(V::ALIGN);
let hdr_size = (HDR + al - 1) & !(al - 1);
let off = c.cur * f;
let kv_ptr = p.add(hdr_size + off);
core::ptr::copy(kv_ptr.add(f), kv_ptr, f * (n - c.cur - 1));
hdr.decr(f);
} else {
let ptr = p.add(HDR + c.cur * 2) as *mut u16;
let kv_ptr = p.add((*ptr) as usize);
let size = entry_size::<T, K, V>(kv_ptr);
core::ptr::copy(ptr.offset(1), ptr, n - c.cur);
hdr.decr(size);
}
} else {
let ptr = p.add(HDR + c.cur * 8) as *mut u64;
let off = (u64::from_le(*ptr) & 0xfff) as usize;
let kv_ptr = p.add(off);
let size = entry_size::<T, K, V>(kv_ptr);
core::ptr::copy(ptr.offset(1), ptr, (&*hdr).n() as usize - c.cur);
(&mut *hdr).decr(size);
}
};
let size = left_size + mid_size + occupied - hdr_size;
debug!("size = {:?} {:?} {:?} {:?} {:?}", left_size, mid_size, occupied, hdr_size, size);
let size = mod_size + mid_size + occupied - hdr_size;
debug!(
"size = {:?} {:?} {:?} {:?} {:?}",
mod_size, mid_size, occupied, hdr_size, size
);
// If we can't rebalance, return.
if left_size >= PAGE_SIZE / 2 || occupied - first_size < PAGE_SIZE / 2 {
return Ok(Op::Put(if let Some((k, v)) = m.modified.ins {
Self::replace(
// If we can't rebalance, modify and return.
if mod_size >= PAGE_SIZE / 2 || occupied - first_size < PAGE_SIZE / 2 {
if let Some((k, v)) = m.modified.ins {
return Ok(Op::Put(Self::replace(
2 + entry_size::<T, K, V>(
page.data
.as_ptr()
.add(u16::from_le(*(page.data.as_ptr().add(HDR) as *const u16).add(c.cur))
as usize),
2 + entry_size::<T, K, V>(page.data.as_ptr().add(u16::from_le(
*(page.data.as_ptr().add(HDR) as *const u16).add(c.cur),
fn can_alloc<T, K: Representable<T>, V: Representable<T>>(
hdr: &Header,
size: usize,
) -> bool;
fn can_compact<T, K: Representable<T>, V: Representable<T>>(
hdr: &Header,
size: usize,
) -> bool;
fn extra_size<T, K: Representable<T>, V: Representable<T>>() -> usize;
fn can_alloc<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool;
fn can_compact<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool;
fn can_alloc<T, K: Representable<T>, V: Representable<T>>(
hdr: &Header,
size: usize,
) -> bool {
fn extra_size<T, K: Representable<T>, V: Representable<T>>() -> usize {
if fixed_size::<T, K, V>().is_some() {
0
} else {
2
}
}
fn can_alloc<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool {
fn can_compact<T, K: Representable<T>, V: Representable<T>>(
hdr: &Header,
size: usize,
) -> bool {
fn can_compact<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool {
fn truncate_left<T, K: Representable<T>, V: Representable<T>>(page: &mut MutPage, n: usize) -> Option<(*const K, *const V)> {
fn truncate_left<T, K: Representable<T>, V: Representable<T>>(
page: &mut MutPage,
n: usize,
) -> Option<(*const K, *const V)> {
let deleted_size: u64 = deleted_offsets.iter().map(|&off| {
2 + unsafe { entry_size::<T, K, V>(page.0.data.add(off as usize)) } as u64
}).sum();
let deleted_size: u64 = deleted_offsets
.iter()
.map(|&off| {
2 + unsafe { entry_size::<T, K, V>(page.0.data.add(off as usize)) } as u64
})
.sum();
fn can_alloc<T, K: Representable<T>, V: Representable<T>>(
hdr: &Header,
size: usize,
) -> bool {
fn extra_size<T, K: Representable<T>, V: Representable<T>>() -> usize {
8
}
fn can_alloc<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool {
fn can_compact<T, K: Representable<T>, V: Representable<T>>(
hdr: &Header,
size: usize,
) -> bool {
fn can_compact<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool {
fn truncate_left<T, K: Representable<T>, V: Representable<T>>(page: &mut MutPage, n: usize) -> Option<(*const K, *const V)> {
fn truncate_left<T, K: Representable<T>, V: Representable<T>>(
page: &mut MutPage,
n: usize,
) -> Option<(*const K, *const V)> {
unsafe fn modify<T: LoadPage + core::fmt::Debug, K: Representable<T> + core::fmt::Debug, V: Representable<T> + core::fmt::Debug, L: Alloc>(
unsafe fn modify<
T: LoadPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
L: Alloc,
>(
unsafe fn merge<T: LoadPage + core::fmt::Debug, K: Representable<T> + core::fmt::Debug, V: Representable<T> + core::fmt::Debug, L: Alloc>(
unsafe fn merge<
T: LoadPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
L: Alloc,
>(
fn rebalance_left<'a, T: AllocPage + core::fmt::Debug, K: Representable<T> + core::fmt::Debug, V: Representable<T> + core::fmt::Debug, L: Alloc>(
fn rebalance_left<
'a,
T: AllocPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
L: Alloc,
>(
fn rebalance_right<'a, T: AllocPage + core::fmt::Debug, K: Representable<T> + core::fmt::Debug, V: Representable<T> + core::fmt::Debug, L: Alloc>(
fn rebalance_right<
'a,
T: AllocPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
L: Alloc,
>(
fn put<'a, T: AllocPage + core::fmt::Debug, K: Representable<T> + core::fmt::Debug, V: Representable<T> + core::fmt::Debug, L: Alloc>(
fn put<
'a,
T: AllocPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
L: Alloc,
>(
alloc::<_, _, _, L>(&mut page, k0, v0, l, r, &mut n);
if let Some((k1, v1)) = k1v1 {
alloc::<_, _, _, L>(&mut page, k0, v0, 0, 0, &mut n);
alloc::<_, _, _, L>(&mut page, k1, v1, l, r, &mut n);
} else {
alloc::<_, _, _, L>(&mut page, k0, v0, l, r, &mut n);
}
alloc::<T, K, V, L>(&mut new, k0, v0, l, r, &mut n);
if let Some((k1, v1)) = k1v1 {
alloc::<_, _, _, L>(&mut new, k0, v0, 0, 0, &mut n);
alloc::<_, _, _, L>(&mut new, k1, v1, l, r, &mut n);
} else {
alloc::<_, _, _, L>(&mut new, k0, v0, l, r, &mut n);
}
fn split<'a, T: AllocPage + core::fmt::Debug, K: Representable<T> + core::fmt::Debug, V: Representable<T> + core::fmt::Debug, L: Alloc>(
fn split<
'a,
T: AllocPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
L: Alloc,
>(
fn split_unsized<'a, T: AllocPage, K: Representable<T>, V: Representable<T>, L: Alloc>(
_txn: &mut T,
_page: crate::Page,
_mutable: bool,
_u: usize,
_k0: &'a K,
_v0: &'a V,
_l: u64,
_r: u64,
fn split_unsized<
'a,
T: AllocPage+ core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
L: Alloc,
>(
txn: &mut T,
page: crate::Page,
u: usize,
k0: &'a K,
v0: &'a V,
k1v1: Option<(&'a K, &'a V)>,
l0: u64,
r0: u64,
unimplemented!()
let hdr = header(page);
let n0 = hdr.n();
let mut left = txn.alloc_page()?;
<Page<K, V> as BTreeMutPage<T, K, V>>::init(&mut left);
let mut right = txn.alloc_page()?;
<Page<K, V> as BTreeMutPage<T, K, V>>::init(&mut left);
let left_child = header(page).left_page() & !0xfff;
L::set_right_child(&mut left, -1, left_child);
let mut split = core::ptr::null();
let mut current_page = &mut left;
let mut n = 0;
let s = unsafe {core::slice::from_raw_parts(
page.data.as_ptr().add(HDR) as *const LeafOffset,
n0 as usize,
)};
let mut total = HDR;
let mut is_left = true;
for off in s.iter() {
let (r, off): (u64, u16) = (*off).into();
unsafe {
let ptr = page.data.as_ptr().add(off as usize);
let size = entry_size::<T, K, V>(ptr) + L::extra_size::<T, K, V>();
total += size;
if is_left && total >= PAGE_SIZE / 2 {
is_left = false;
split = ptr as *const Tuple<K, V>;
L::set_right_child(&mut right, -1, r);
current_page = &mut right;
} else {
let off_new = L::alloc(header_mut(current_page), size, K::ALIGN.max(V::ALIGN));
core::ptr::copy_nonoverlapping(ptr, current_page.0.data.offset(off_new as isize), size);
L::set_offset(current_page, n, r, off_new);
}
}
n += 1;
if n == u as isize {
if let Some((k1, v1)) = k1v1 {
alloc::<T, K, V, L>(current_page, k0, v0, 0, l0, &mut n);
total += alloc_size(k0, v0) + L::extra_size::<T, K, V>();
alloc::<T, K, V, L>(current_page, k1, v1, 0, r0, &mut n);
total += alloc_size(k1, v1) + L::extra_size::<T, K, V>();
n += 2;
} else {
alloc::<T, K, V, L>(current_page, k0, v0, l0, r0, &mut n);
total += alloc_size(k0, v0) + L::extra_size::<T, K, V>();
n += 1;
}
}
}
assert!(!split.is_null());
let split = unsafe { &*split };
Ok(Put::Split {
split_key: &split.k,
split_value: &split.v,
left,
right,
freed: page.offset,
})
) -> Result<Put<'a, K, V>, T::Error> {
// TODO: optimise this for page::Page<K, V>, since this moves
// all the offsets twice in this case.
let new = Self::del(txn, page, c, l)?;
Self::put(txn, new.0, mutable, c, k0, v0, l, r)
}
) -> Result<Put<'a, K, V>, T::Error>;
// Here, if we are at cursor.pointer == p0, the
// replacement has been either inserted into one of
// {left, right}, or is the split key/value
// itself. Therefore, we just have to delete the
// key/value selected for deletion in page p0 (the
// current page).
let (ins, ins2, skip_first) = if cursor.pointer == p0 {
let k = unsafe { &*k0.as_ptr() };
let v = unsafe { &*v0.as_ptr() };
(Some((k, v)), Some((split_key, split_value)), true)
} else {
(Some((split_key, split_value)), None, false)
};