OTWDDJE7TTE73D6BGF4ZN6BH2NFUFLPME2VJ3CPALH463UGWLEIQC
S4V4QZ5CF5LUDYWNR2UMWH6CHJDJ5FPGAZCQYM5GY7FJMJV4NN4QC
OP6SVMOD2GTQ7VNJ4E5KYFG4MIYA7HBMXJTADALMZH4PY7OQRMZQC
DV4A2LR7Q5LAEGAQHLO34PZCHGJUHPAMRZFGT7GUFNKVQKPJNOYQC
WS4ZQM4RMIHZ6XZKSDQJGHN5SSSWFL4H236USOPUA33S6RC53RFAC
6DMPXOAT5GQ3BQQOMUZN2GMBQPRA4IB7CCPHTQTIFGO3KWWAKF3QC
YWFYZNLZ5JHLIFVBRKZK4TSWVPROUPRG77ZB5M7UHT2OKPL4ZSRQC
X3QVVQIS7B7L3XYZAWL3OOBUXOJ6RMOKQ45YMLLGAHYPEEKZ45ZAC
ONES3V466GLO5CXKRF5ENK7VFOQPWM3YXLVRGWB56V5SH3W7XNBQC
EAAYH6BQWDK52EC5RG3BEZQU3FJPN5RRRN4U5KDKDVPKXBVJMNDAC
QEUTVAZ4F4EJXRDMWDMYXF6XEDMX7YPVG4IIXEKPIR3K54E5W5OAC
PXF3R6SVXJXN2NMLMWNY5OFV5QYVE2VZTLGIZDZVK5ZVLFTVSSWQC
UAQX27N4PI4LHEW6LSHJETIE5MV7JTEMPLTJFYUBMYVPC43H7VOAC
unsafe fn read<T, K: Representable<T>, V: Representable<T>>(p: *const u8) -> (*const K, *const V) {
let k = p as *const K;
let s = K::size(&*k);
unsafe fn read<T, K: Representable, V: Representable>(txn: &T, k: *const u8) -> (*const u8, *const u8) {
let s = K::size(K::from_raw_ptr(txn, k));
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>
K: Representable + core::fmt::Debug,
V: Representable + core::fmt::Debug,
> super::BTreeMutPage<K, V> for Page<K, V>
let (k, v) = read::<T, K, V>(page.data.as_ptr().add((off & 0xfff) as usize));
(&*k, &*v, off & !0xfff)
let (k, v) = read::<T, K, V>(txn, page.data.as_ptr().add((off & 0xfff) as usize));
(K::from_raw_ptr(txn, k as *const u8), V::from_raw_ptr(txn, v as *const u8), off & !0xfff)
let (k, v) = read::<T, K, V>(page.data.as_ptr().offset(off as isize));
match (&*k).compare(txn, k0) {
Ordering::Equal => (&*v).compare(txn, v0),
let (k, v) = read::<T, K, V>(txn, page.data.as_ptr().offset(off as isize));
let k = K::from_raw_ptr(txn, k as *const u8);
match k.compare(txn, k0) {
Ordering::Equal => {
let v = V::from_raw_ptr(txn, v as *const u8);
v.compare(txn, v0)
},
let (k, _) = read::<T, K, V>(page.data.as_ptr().offset(off as isize));
(&*k).compare(txn, k0)
let (k, _) = read::<T, K, V>(txn, page.data.as_ptr().offset(off as isize));
let k = K::from_raw_ptr(txn, k);
k.compare(txn, k0)
let (k, v) = read::<T, K, V>(page.data.as_ptr().offset(off as isize & 0xfff));
match (&*k).compare(txn, k0) {
Ordering::Equal => (&*v).compare(txn, v0),
let (k, v) = read::<T, K, V>(txn, page.data.as_ptr().offset(off as isize & 0xfff));
let k = K::from_raw_ptr(txn, k);
match k.compare(txn, k0) {
Ordering::Equal => {
let v = V::from_raw_ptr(txn, v);
v.compare(txn, v0)
},
let (k, _) = read::<T, K, V>(page.data.as_ptr().offset(off as isize & 0xfff));
(&*k).compare(txn, k0)
let (k, _) = read::<T, K, V>(txn, page.data.as_ptr().offset(off as isize & 0xfff));
let k = K::from_raw_ptr(txn, k);
k.compare(txn, k0)
alloc::<_, _, _, L>(new, &*m.mid.0, &*m.mid.1, 0, l, &mut n);
while let Some((k, v, r)) = <Page<K, V>>::next(m.other.as_page(), &mut rc) {
alloc::<_, _, _, L>(new, k, v, 0, r, &mut n);
alloc::<_, _, L>(new, m.mid.0, m.mid.1, 0, l, &mut n);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, m.other.as_page(), &mut rc) {
alloc::<_, _, L>(new, k, v, 0, r, &mut n);
clone::<T, K, V, L>(page.as_page(), &mut right, s1a, &mut n);
alloc::<T, K, V, L>(&mut right, k0, v0, l, r, &mut n);
clone::<T, K, V, L>(page.as_page(), &mut right, s1b, &mut n);
clone::<K, V, L>(page.as_page(), &mut right, s1a, &mut n);
alloc::<K, V, L>(&mut right, k0, v0, l, r, &mut n);
clone::<K, V, L>(page.as_page(), &mut right, s1b, &mut n);
clone::<T, K, V, L>(page.as_page(), &mut left, s0a, &mut n);
alloc::<T, K, V, L>(&mut left, k0, v0, l, r, &mut n);
clone::<T, K, V, L>(page.as_page(), &mut left, s0b, &mut n);
clone::<K, V, L>(page.as_page(), &mut left, s0a, &mut n);
alloc::<K, V, L>(&mut left, k0, v0, l, r, &mut n);
clone::<K, V, L>(page.as_page(), &mut left, s0b, &mut n);
T: AllocPage + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
T: AllocPage,
K: Representable + core::fmt::Debug,
V: Representable + core::fmt::Debug,
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 extra_size<T, K: Representable, V: Representable>() -> usize;
fn can_alloc<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool;
fn can_compact<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool;
fn can_alloc<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool {
if let Some(f) = fixed_size::<T, K, V>() {
fn can_alloc<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
if let Some(f) = fixed_size::<K, V>() {
fn can_compact<T, K: Representable<T>, V: Representable<T>>(hdr: &Header, size: usize) -> bool {
if fixed_size::<T, K, V>().is_some() {
fn can_compact<T, K: Representable, V: Representable>(hdr: &Header, size: usize) -> bool {
if fixed_size::<K, V>().is_some() {
fn next<'b>(p: Page<'b>, c: &mut Self::Cursor) -> Option<(&'b K, &'b V, u64)> {
if let Some((k, v, r)) = Self::current(p, c) {
fn next<'b, T: LoadPage>(txn: &T, p: Page<'b>, c: &mut Self::Cursor) -> Option<(&'b K, &'b V, u64)> {
if let Some((k, v, r)) = Self::current(txn, p, c) {
unsafe fn unchecked_current<'a>(p: Page<'a>, c: &Self::Cursor) -> (&'a K, &'a V, u64);
fn current<'a>(p: Page<'a>, c: &Self::Cursor) -> Option<(&'a K, &'a V, u64)> {
unsafe fn unchecked_current<'a, T: LoadPage>(txn: &T, p: Page<'a>, c: &Self::Cursor) -> (&'a K, &'a V, u64);
fn current<'a, T: LoadPage>(txn: &T, p: Page<'a>, c: &Self::Cursor) -> Option<(&'a K, &'a V, u64)> {
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
P: BTreeMutPage<T, K, V> + core::fmt::Debug,
K: Representable + core::fmt::Debug,
V: Representable + core::fmt::Debug,
P: BTreeMutPage<K, V> + core::fmt::Debug,
K: Representable<T> + core::fmt::Debug,
V: Representable<T> + core::fmt::Debug,
P: BTreeMutPage<T, K, V> + core::fmt::Debug,
K: Representable + core::fmt::Debug,
V: Representable + core::fmt::Debug,
P: BTreeMutPage<K, V> + core::fmt::Debug,
// If p0 < cursor.first_rc_level, the page containing the deleted
// element is not shared with another table. Therefore, the RC of
// the pages referenced by the deleted element needs to be
// decreased.
if p0 < cursor.first_rc_level {
unsafe {
let cur = cursor.current();
let (delk, delv, _) =
P::unchecked_current(txn, cur.page.as_page(), cur.cursor.as_ref().unwrap());
for o in delk.page_offsets().chain(delv.page_offsets()) {
txn.incr_rc(o)?;
}
}
}
// (k0, v0) if we're in an internal node.
let (mut last_op, k0, v0) = leaf_delete(txn, cursor, p0)?;
// (k0, v0) if the deletion happens in an internal node (`(k0,
// v0)` is uninitialized else).
let mut k0 = MaybeUninit::uninit();
let mut v0 = MaybeUninit::uninit();
let (mut last_op, k0v0) = leaf_delete(txn, cursor, p0, &mut k0, &mut v0)?;
// Compute the need for merge/rebalancing
let mut concat = concat(txn, cursor, p0, &k0, &v0, last_op)?;
// Prepare a plan for merging the current modified page (that
// page is at level cursor.pointer + 1) with one of its
// neighbours.
//
// This is a little bit convoluted, but we do have to get up
// one level in order to fetch the right or left sibling of
// the modified page.
let mut concat = concat(txn, cursor, p0, k0v0, last_op)?;
// The root was merged or rebalanced.
if let Some(d) = last_op.single_child() {
debug!("single child {:?}", d);
if P::is_dirty(last_op.page.as_page()) {
txn.decr_rc_owned(last_op.page.offset)?
} else {
txn.decr_rc(last_op.page.offset)?
}
db.db = txn.load_page(d)?
} else {
update_root(txn, db, last_op, &k0, cursor.first_rc_level <= 1, &mut free)?
}
// The last operation was on the root (i.e. at level 1), and that
// operation still needs to be executed.
update_root(txn, db, last_op, k0v0, cursor.first_rc_level <= 1, &mut free)?;
// Finally, free all the freed pages, now that we don't need to
// read them anymore.
) -> Result<(ModifiedPage<'a, T, K, V, P>, MaybeUninit<K>, MaybeUninit<V>), T::Error> {
let ref mut curs0 = unsafe { cursor.stack[cursor.pointer].assume_init() };
k0: &'a mut MaybeUninit<K>,
v0: &'a mut MaybeUninit<V>,
) -> Result<(ModifiedPage<'a, K, V, P>, Option<(&'a K, &'a V)>), T::Error> {
let curs0 = unsafe { &mut *cursor.stack[cursor.pointer].as_mut_ptr() };
while let Some((k, v, _)) = P::next(curs0.page.as_page(), &mut c0)
.or_else(|| P::next(curs0.page.as_page(), &mut c1))
while let Some((k, v, _)) = P::next(txn, curs0.page.as_page(), &mut c0)
.or_else(|| P::next(txn, curs0.page.as_page(), &mut c1))
core::ptr::copy_nonoverlapping(k, k0.as_mut_ptr(), 1);
core::ptr::copy_nonoverlapping(v, v0.as_mut_ptr(), 1);
if K::SIZE.is_some() && V::SIZE.is_some() {
core::ptr::copy_nonoverlapping(k, k0.as_mut_ptr(), 1);
core::ptr::copy_nonoverlapping(v, v0.as_mut_ptr(), 1);
deleted = Some((&*k0.as_ptr(), &*v0.as_ptr()))
} else {
deleted = Some((k, v))
}
k0: &MaybeUninit<K>,
v0: &MaybeUninit<V>,
last_op: ModifiedPage<'a, T, K, V, P>,
) -> Result<Concat<'a, T, K, V, P>, T::Error> {
k0v0: Option<(&'a K, &'a V)>,
last_op: ModifiedPage<'a, K, V, P>,
) -> Result<Concat<'a, K, V, P>, T::Error> {
let other = txn.load_page(P::left_child(curs.page.as_page(), c))?;
Ok(Concat {
modified: last_op,
mid: unsafe { (&*k0.as_ptr(), &*v0.as_ptr()) },
other,
mod_is_left: false,
})
if let Some((k0, v0)) = k0v0 {
let other = txn.load_page(P::left_child(curs.page.as_page(), c))?;
Ok(Concat {
modified: last_op,
mid: (k0, v0),
other,
mod_is_left: false,
})
} else {
unreachable!()
}
if cursor.pointer + 1 >= cursor.first_rc_level && (split_key as *const K) != k0.as_ptr()
let split_key_is_k0 = if let Some((k0, _)) = k0v0 {
(k0 as *const K) == (split_key as *const K)
} else {
false
};
if cursor.pointer + 1 >= cursor.first_rc_level && !split_key_is_k0
while let Some((k, v, r)) = P::next(m.page.as_page(), &mut c0) {
for o in k.page_offsets().chain(v.page_offsets()) {
txn.incr_rc(o)?;
assert_ne!(left, 0);
if p >= first_rc_level {
while let Some((k, v, r)) = P::next(txn, m.page.as_page(), &mut c0) {
for o in k.page_offsets().chain(v.page_offsets()) {
txn.incr_rc(o)?;
}
assert_ne!(left, 0);
txn.incr_rc(left)?;
left = r;
if m.skip_first {
P::move_next(m.page.as_page(), &mut c1);
} else {
txn.incr_rc(left)?;
// The insertions come from pages strictly below the page at
// cursor.pointer, so if `incr_ins`, we increment them here,
// except the replacement, already incremented in `leaf_delete`
// above
if p + 1 >= first_rc_level {
if let Some((k, v)) = m.ins {
// If this is the replacement, it has already been
// incremented in `leaf_delete`, so we don't need to
// increment it again.
if m.skip_first {
for o in k.page_offsets().chain(v.page_offsets()) {
txn.incr_rc(o)?;
}
}
if let Some((k, v)) = m.ins2 {
for o in k.page_offsets().chain(v.page_offsets()) {
txn.incr_rc(o)?;
}
}
}
while let Some((k, v, r)) = P::next(m.page.as_page(), &mut c1) {
for o in k.page_offsets().chain(v.page_offsets()) {
txn.incr_rc(o)?;
if p >= first_rc_level {
if m.skip_first {
P::move_next(m.page.as_page(), &mut c1);
}
// If we are not updating the left child of c1's first
// element, increment that left child.
if m.l == 0 {
assert_ne!(left, 0);
txn.incr_rc(left)?;
}
// Moving on to the first non-deleted element of `c1`: if we
// are not updating the right child of the first element,
// increment that right child's RC.
if let Some((k, v, r)) = P::next(txn, m.page.as_page(), &mut c1) {
for o in k.page_offsets().chain(v.page_offsets()) {
txn.incr_rc(o)?;
}
if m.r == 0 {
assert_ne!(r, 0);
txn.incr_rc(r)?;
}
}
// Finally, increment the RCs of all other elements in `c1`.
while let Some((k, v, r)) = P::next(txn, m.page.as_page(), &mut c1) {
for o in k.page_offsets().chain(v.page_offsets()) {
txn.incr_rc(o)?;
}
if r != 0 {
assert_ne!(r, 0);
txn.incr_rc(r)?;
}
if let Some(d) = last_op.single_child() {
// If the root had only one element, and the last operation
// was a merge, this decreases the depth of the tree.
debug!("single child {:?}", d);
if P::is_dirty(last_op.page.as_page()) {
txn.decr_rc_owned(last_op.page.offset)?
} else {
txn.decr_rc(last_op.page.offset)?
}
db.db = txn.load_page(d)?;
return Ok(())
}
// Else, we execute the last operation
pub struct Cursor<T: LoadPage, K: Representable<T>, V: Representable<T>, P: BTreePage<T, K, V>> {
pub stack: [core::mem::MaybeUninit<PageCursor<T, K, V, P>>; N_CURSORS],
pub struct Cursor<K: Representable, V: Representable, P: BTreePage<K, V>> {
pub stack: [core::mem::MaybeUninit<PageCursor<K, V, P>>; N_CURSORS],
impl<T> Representable<T> for A<T> {
type PageOffsets = core::iter::Empty<u64>;
fn page_offsets(&self) -> Self::PageOffsets {
core::iter::empty()
}
const ALIGN: usize = core::mem::align_of::<Self>();
const SIZE: Option<usize> = Some(core::mem::size_of::<Self>());
fn compare(&self, _: &T, b: &Self) -> std::cmp::Ordering {
self.0.cmp(&b.0)
}
fn size(&self) -> usize {
core::mem::size_of::<Self>()
}
}
direct_repr!(A);
unimplemented!();
del(&mut txn, &mut db, &1019, None).unwrap();
debug!("==============");
del(&mut txn, &mut db, &11, None).unwrap();
debug!("free_owned_pages = {:?}", txn.free_owned_pages);
crate::debug::debug(&txn, &[&db, &db2], "debug1", true);
/*for i in 1530..1531 {
del(&mut txn, &mut db, &i, None).unwrap();
}*/
// for i in 1530..1531 {
// del(&mut txn, &mut db, &i, None).unwrap();
// }