LSQ6V7M66TEGLJ7QBLRVDX4E7UKJTDQTEXZOS3KGPGFKVXNLPKBQC
QBDBAQXYIPEJMYZMHQ3URXTNL2D2JHKZQVRG6YSOG36XKHSBFUBQC
SQ7MD7OWKFYNQR525YNOG7APHDNMKB7PPVWLIYFJJQPL3MWNFXLQC
ESUI5EUZUBDPHNN3APU33IFORYPYR6J3WEMEZG57FKF3EH66ZBHAC
OP6SVMOD2GTQ7VNJ4E5KYFG4MIYA7HBMXJTADALMZH4PY7OQRMZQC
HN6Z5DU4WYMAIOOSNVHLIIMNF6Q53TNJ7YC27SLKWNXVYCTACQKQC
XEU2QVLCHPYOOD4TQIPEEVYOVSFMKFPLJYWEJYXYJAZ7S54KWDZAC
UUUVNC4DWEEL7WV5IRPKPZ6HZMYCPA53XM7LJWICUD4E6GN37IRQC
OTWDDJE7TTE73D6BGF4ZN6BH2NFUFLPME2VJ3CPALH463UGWLEIQC
DV4A2LR7Q5LAEGAQHLO34PZCHGJUHPAMRZFGT7GUFNKVQKPJNOYQC
SO25TWFLSRQIVTJTTSN77LO5FZQVQPIZTSBULH7MWBBDEWSK3OCAC
H3FVSQIQGFCFKCPXVOSFHP4OSUOBBURJESCZNGQTNDAAD3WQSBEQC
6UVFCERMGSGNRWCVC3GWO5HWV6MSWE433DXBJVC7KRPP6LLJLCSQC
WS4ZQM4RMIHZ6XZKSDQJGHN5SSSWFL4H236USOPUA33S6RC53RFAC
RV2L6CZWTMUQ2A52YDAFVHDFGURZL3H4SSCDC347UGN23D3J5KZQC
W26CFMAQOXMUK4ZOJMAN4SMBXMWFQHO7HCTEVW73FQSRMJZFGJIQC
73Z2UB3JGRLFNFORE7D64O4IHIFSZASD4G4FLJ4FJLHANT75MGIAC
FMN7X4J24EYPOJNBUWM4NKGWSJTRV2DHCIBMPV2AXLZVVAMNOBKQC
OFINGD26ZWCRDVVDI2ZIBLMHXKEMJA6MRNLANJYUHQPIJLPA7J2AC
S4V4QZ5CF5LUDYWNR2UMWH6CHJDJ5FPGAZCQYM5GY7FJMJV4NN4QC
Q7DRIBBRE4MNG4NP3PVIXAJF5PQYLFWYIVK2O4VVLEO6XY3BOSFQC
KX3WVNZW5KHVEH6EOQTZ4RBEFFJ3SGF5I467X3JWZ74PURRK4HVAC
T73WR2BX2QDQ6APOREBXUKNH52FDLJNBGWPQUYB2TAF2PT7XCL2AC
AOX2XQISHGWNNAFBYRN44Q6AWG7H5DPBK5YMFHK42HQNZ2TMHEJQC
QEUTVAZ4F4EJXRDMWDMYXF6XEDMX7YPVG4IIXEKPIR3K54E5W5OAC
APPY2E7M5NHNC6MFYXSVEKJVAILK7YAZVTVE3W75EK2JNFVS3XBQC
ONES3V466GLO5CXKRF5ENK7VFOQPWM3YXLVRGWB56V5SH3W7XNBQC
LROAI3NBBSCU4T2YA6EHJYKKKL75AU5A7C7WIRCGIQ56S6HPLRXQC
NXMFNPZ7VWJRLC3M5QJJVTICXCMGE24F3HVIZA7A7RLVMLQMLDVQC
X3QVVQIS7B7L3XYZAWL3OOBUXOJ6RMOKQ45YMLLGAHYPEEKZ45ZAC
EAAYH6BQWDK52EC5RG3BEZQU3FJPN5RRRN4U5KDKDVPKXBVJMNDAC
WAKPPBKONQUA3G7HWH52ZKYG5PLZEAG3HFAYGIYLA4NVEPRZUQEAC
PXF3R6SVXJXN2NMLMWNY5OFV5QYVE2VZTLGIZDZVK5ZVLFTVSSWQC
KM3JAFGPFV7MP7M2LJIYRVAUTU646B3IRXADTRZKOU2RF7LUB62QC
MSRWB47YP6L5BVTS53QQPBOHY5SXTSTR5KD6IIF35UWCTEUOCQWQC
UAQX27N4PI4LHEW6LSHJETIE5MV7JTEMPLTJFYUBMYVPC43H7VOAC
T7QB6QEPWBXAU3RL7LE4GRDWWNQ65ZU2YNNTWBYLORJOABAQFEZQC
6DCQHIFPEH4GZKSRRS32GMKDRPZH4MTCGOUEI7YEUVKWENBF3JWAC
/// An iterator over the offsets to pages contained in this
/// value. Only values from this crate can generate non-empty
/// iterators, but combined values (like tuples) must chain the
/// iterators returned by method `page_offsets`.
type PageOffsets: Iterator<Item = u64>;
fn compare<T: LoadPage>(&self, txn: &T, b: &Self) -> core::cmp::Ordering;
/// Some datastructures expect this to be at least the memory size
/// of `Self` (as returned by `core::mem::size_of::<Self>()`). For
/// example, the sized implementation of B trees sometimes
/// allocates an instance of `Self` on the stack, and copy it from
/// the
/// This is required for B trees, not necessarily for other
/// structures. The default implementation panics.
fn compare<T: LoadPage>(&self, _txn: &T, _b: &Self) -> core::cmp::Ordering {
unimplemented!()
}
/// An iterator over the offsets to pages contained in this
/// value. Only values from this crate can generate non-empty
/// iterators, but combined values (like tuples) must chain the
/// iterators returned by method `page_offsets`.
type PageOffsets: Iterator<Item = u64>;
let ref cur = cursor.current();
let p = cursor.len(); // Save the position of the leaf cursor.
let is_owned = p < cursor.first_rc_len;
// Insert the key and value at the leaf, i.e. pop the top level of
// the stack (the leaf) and insert in there.
let cur = cursor.pop().unwrap();
if cursor.pointer() > 0 {
// If we aren't at the root, just pop the cursor
// stack and insert a new entry in the page above.
cursor.pop();
let cur = cursor.current();
let is_owned = cursor.len() < cursor.first_rc_len;
if let Some(cur) = cursor.pop() {
// In this case, there's a page above the page
// that just split (since we can pop the stack),
// so the page that just split isn't the root (but
// `cur` might be).
let mut l = <Page<K, V>>::left_child(unsafe { m.page.as_page() }, &m.c0);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, unsafe { m.page.as_page() }, &mut m.c0) {
let mut l = <Page<K, V>>::left_child(m.page.as_page(), &m.c0);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, m.page.as_page(), &mut m.c0) {
let mut l = <Page<K, V>>::left_child(unsafe { m.other.as_page() }, &rc);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, unsafe { m.other.as_page() }, &mut rc) {
let mut l = <Page<K, V>>::left_child(m.other.as_page(), &rc);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, m.other.as_page(), &mut rc) {
let rl = <Page<K, V>>::left_child(unsafe { m.other.as_page() }, &rc);
let (k, v, r) = <Page<K, V>>::current(txn, unsafe { m.other.as_page() }, &rc).unwrap();
let rl = <Page<K, V>>::left_child(m.other.as_page(), &rc);
let (k, v, r) = <Page<K, V>>::current(txn, m.other.as_page(), &rc).unwrap();
// Extend the lifetimes of k and v.
let (k, v): (&K, &V) = unsafe { (core::mem::transmute(k), core::mem::transmute(v)) };
let lc = PageCursor::after(&m.modified.page);
if let Put::Ok(Ok { page, freed }) = <Page<K, V>>::put(
let lc = PageCursor::after(&new_left.0);
let new_left = if let Put::Ok(Ok { freed, page }) = <Page<K, V>>::put(
let lc = super::PageCursor::last(unsafe { m.other.as_page() });
let (k0, v0, r0) = <Page<K, V>>::current(txn, unsafe { m.other.as_page() }, &lc).unwrap();
let lc = super::PageCursor::last(m.other.as_page());
let (k0, v0, r0) = <Page<K, V>>::current(txn, m.other.as_page(), &lc).unwrap();
let mut l = <Page<K, V>>::left_child(unsafe { m.page.as_page() }, &m.c0);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, unsafe { m.page.as_page() }, &mut m.c0) {
let mut l = <Page<K, V>>::left_child(m.page.as_page(), &m.c0);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, m.page.as_page(), &mut m.c0) {
let mut l = <Page<K, V>>::left_child(unsafe { m.other.as_page() }, &rc);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, unsafe { m.other.as_page() }, &mut rc) {
let mut l = <Page<K, V>>::left_child(m.other.as_page(), &rc);
while let Some((k, v, r)) = <Page<K, V>>::next(txn, m.other.as_page(), &mut rc) {
let rl = <Page<K, V>>::left_child(unsafe { m.other.as_page() }, &rc);
let (k, v, r) = <Page<K, V>>::current(txn, unsafe { m.other.as_page() }, &rc).unwrap();
let rl = <Page<K, V>>::left_child(m.other.as_page(), &rc);
let (k, v, r) = <Page<K, V>>::current(txn, m.other.as_page(), &rc).unwrap();
let lc = PageCursor::after(&m.modified.page);
if let Put::Ok(Ok { page, freed }) = <Page<K, V>>::put(
let lc = PageCursor::after(&new_left.0);
let new_left = if let Put::Ok(Ok { page, freed }) = <Page<K, V>>::put(
if freed > 0 {
let b = if header(unsafe { new_left.0.as_page() }).is_dirty() {
1
} else {
0
};
freed_[0] = freed | b;
}
new_left = page
assert_eq!(freed, 0);
page
let lc = PageCursor::last(unsafe { m.other.as_page() });
let (k0, v0, r0) = <Page<K, V>>::current(txn, unsafe { m.other.as_page() }, &lc).unwrap();
let lc = PageCursor::last(m.other.as_page());
let (k0, v0, r0) = <Page<K, V>>::current(txn, m.other.as_page(), &lc).unwrap();
let hdr = &*header(unsafe { m.other.as_page() });
let b = if hdr.is_dirty() { 1 } else { 0 };
freed_[1] = freed | b
freed_[1] = freed | if is_dirty { 1 } else { 0 }
debug!(
"alloc: {:?}",
header(unsafe { new.0.as_page() }).left_page()
);
clone::<K, V, L>(unsafe { page.as_page() }, &mut new, s1, &mut n);
debug!("alloc: {:?}", header(new.0.as_page()).left_page());
clone::<K, V, L>(page.as_page(), &mut new, s1, &mut n);
// If we are here, u >= k, i.e. the insertion is in the right-hand
// side of the split.
let mut right = txn.alloc_page()?;
<Page<K, V> as BTreeMutPage<K, V>>::init(&mut right);
if u > k as usize {
let mut n = 0;
let kk = u as usize - k as usize - 1;
let (s1a, s1b) = s1.split_at(kk);
L::set_right_child(&mut right, -1, mid_child);
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);
} else {
let mut n = 0;
clone::<K, V, L>(page.as_page(), &mut right, s1, &mut n);
}
// If we are here, u >= k, i.e. the insertion is in the right-hand
// side of the split.
let mut n = 0;
let mut right = txn.alloc_page()?;
<Page<K, V> as BTreeMutPage<K, V>>::init(&mut right);
if u > k as usize {
let kk = u as usize - k as usize - 1;
let (s1a, s1b) = s1.split_at(kk);
L::set_right_child(&mut right, -1, mid_child);
clone::<K, V, L>(unsafe { page.as_page() }, &mut right, s1a, &mut n);
alloc::<K, V, L>(&mut right, k0, v0, l, r, &mut n);
clone::<K, V, L>(unsafe { page.as_page() }, &mut right, s1b, &mut n);
} else {
if u == k as usize {
// Then, climb up the stack, performing the operations lazily.
while cursor.pointer() > 0 {
cursor.pop();
// 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)?;
// Then, climb up the stack, performing the operations lazily. At
// each step, we are one level above the page that we plan to
// modify, since `last_op` is the result of popping the
// stack.
//
// We iterate up to the root. The last iteration builds a modified
// page for the root, but doesn't actually execute it.
while cursor.len() > 0 {
// Prepare a plan for merging the current modified page (which
// is stored in `last_op`) with one of its neighbours.
let concat = concat(txn, cursor, p0, &k0v0, last_op)?;
let mil = concat.mod_is_left;
// Execute the plan, resulting in one of four different
// outcomes. This mutates or clones the children page,
// i.e. the page at level `cursor.pointer + 1`, returning an
// `Op` describing what happened (between update, merge,
// rebalance and split).
let merge = P::merge_or_rebalance(txn, &mut concat)?;
// Execute the modification plan, resulting in one of four
// different outcomes (described in the big match in
// `handle_merge`). This mutates or clones the current
// modified page, returning an `Op` describing what happened
// (between update, merge, rebalance and split).
let merge = P::merge_or_rebalance(txn, concat)?;
// Prepare a description (`last_op`) of the page modification
// to be performed at level `p` (i.e. at level
// `cursor.pointer`), without mutating/cloning that page.
let mil = concat.mod_is_left;
// Prepare a description (`last_op`) of the next page
// modification, without mutating nor cloning that page.
// The last operation was on the root (i.e. at level 1), and that
// operation still needs to be executed.
let root_is_shared = cursor.first_rc_level == 0;
// The last modification plan was on the root, and still needs to
// be executed.
let root_is_shared = cursor.first_rc_len == 1;
let is_rc = cursor.pointer() >= cursor.first_rc_level;
let del_at_internal = p0 < cursor.pointer();
let ref mut curs0 = cursor.last();
let is_rc = cursor.len() >= cursor.first_rc_len;
let del_at_internal = p0 < cursor.len();
let curs0 = cursor.pop().unwrap();
let ((k, v, r), mod_is_left) = if let Some(x) =
P::current(txn, unsafe { curs.page.as_page() }, &curs.cursor)
{
// Not the last element of the page.
(x, true)
} else {
// Last element of the page.
let (k, v, _) = P::prev(txn, unsafe { curs.page.as_page() }, &mut curs.cursor).unwrap();
let l = P::left_child(unsafe { curs.page.as_page() }, &curs.cursor);
((k, v, l), false)
};
let ((k, v, r), mod_is_left) =
if let Some(x) = P::current(txn, curs.page.as_page(), &curs.cursor) {
// Not the last element of the page.
(x, true)
} else {
// Last element of the page.
let (k, v, _) = P::prev(txn, curs.page.as_page(), &mut curs.cursor).unwrap();
let l = P::left_child(curs.page.as_page(), &curs.cursor);
((k, v, l), false)
};
let mut left = P::left_child(unsafe { m.page.as_page() }, &c0);
while let Some((k, v, r)) = P::next(txn, unsafe { m.page.as_page() }, &mut c0) {
let mut left = P::left_child(m.page.as_page(), &c0);
while let Some((k, v, r)) = P::next(txn, m.page.as_page(), &mut c0) {
// of a B tree below the root has at least 4 elements, the arity is at
// least 5, except for the root. Since 5^23 is the smallest power of 5
// larger than 2^52, the maximum depth is 24.
pub(crate) const N_CURSORS: usize = 24;
// of a B tree below the root has at least 2 elements (because each
// page is at least half-full, and elements are at most 1/4th of a
// page), the arity is at least 3, except for the root. Since 3^33 is
// the smallest power of 3 larger than 2^52, the maximum depth is 33.
pub(crate) const N_CURSORS: usize = 33;
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
core::mem::MaybeUninit::uninit(),
pub(super) fn pop(&mut self) {
assert!(self.pointer > 0);
self.pointer -= 1
pub(super) fn pop(&mut self) -> Option<PageCursor<K, V, P>> {
if self.len > 0 {
self.len -= 1;
let result = core::mem::replace(&mut self.stack[self.len], MaybeUninit::uninit());
Some(unsafe { result.assume_init() })
} else {
None
}
while self.pointer < N_CURSORS {
debug!("set cursor {:?}", self.pointer);
let current = unsafe { &mut *self.stack.get_unchecked_mut(self.pointer).as_mut_ptr() };
// let page = current.page;
if self.first_rc_level >= N_CURSORS && txn.rc(current.page.offset)? >= 2 {
self.first_rc_level = self.pointer
while self.len < N_CURSORS {
debug!("set cursor {:?}", self.len);
let current = unsafe { &mut *self.stack.get_unchecked_mut(self.len - 1).as_mut_ptr() };
if self.first_rc_len >= N_CURSORS && txn.rc(current.page.offset)? >= 2 {
self.first_rc_len = self.len
let current = unsafe { &mut *self.stack[self.pointer].as_mut_ptr() };
debug!("{:?}", current.page);
if self.first_rc_level >= N_CURSORS && txn.rc(current.page.offset)? >= 2 {
self.first_rc_level = self.pointer
let current = unsafe { &mut *self.stack[self.len - 1].as_mut_ptr() };
if self.first_rc_len >= N_CURSORS && txn.rc(current.page.offset)? >= 2 {
self.first_rc_len = self.len
debug!("cursor = {:?}", current.cursor);
let (k, v, r) =
P::current(txn, unsafe { current.page.as_page() }, &mut current.cursor).unwrap();
let (k, v, r) = P::current(txn, current.page.as_page(), &mut current.cursor).unwrap();
debug!("next: {:?}", self.pointer);
let current = unsafe { &mut *self.stack[self.pointer].as_mut_ptr() };
debug!("next: {:?}", self.len);
let current = unsafe { &mut *self.stack[self.len - 1].as_mut_ptr() };