RV2L6CZWTMUQ2A52YDAFVHDFGURZL3H4SSCDC347UGN23D3J5KZQC NXMFNPZ7VWJRLC3M5QJJVTICXCMGE24F3HVIZA7A7RLVMLQMLDVQC OP6SVMOD2GTQ7VNJ4E5KYFG4MIYA7HBMXJTADALMZH4PY7OQRMZQC WS4ZQM4RMIHZ6XZKSDQJGHN5SSSWFL4H236USOPUA33S6RC53RFAC OFINGD26ZWCRDVVDI2ZIBLMHXKEMJA6MRNLANJYUHQPIJLPA7J2AC UUUVNC4DWEEL7WV5IRPKPZ6HZMYCPA53XM7LJWICUD4E6GN37IRQC 6DMPXOAT5GQ3BQQOMUZN2GMBQPRA4IB7CCPHTQTIFGO3KWWAKF3QC 6DCQHIFPEH4GZKSRRS32GMKDRPZH4MTCGOUEI7YEUVKWENBF3JWAC W26CFMAQOXMUK4ZOJMAN4SMBXMWFQHO7HCTEVW73FQSRMJZFGJIQC FMN7X4J24EYPOJNBUWM4NKGWSJTRV2DHCIBMPV2AXLZVVAMNOBKQC 6UVFCERMGSGNRWCVC3GWO5HWV6MSWE433DXBJVC7KRPP6LLJLCSQC S4V4QZ5CF5LUDYWNR2UMWH6CHJDJ5FPGAZCQYM5GY7FJMJV4NN4QC 73Z2UB3JGRLFNFORE7D64O4IHIFSZASD4G4FLJ4FJLHANT75MGIAC OTWDDJE7TTE73D6BGF4ZN6BH2NFUFLPME2VJ3CPALH463UGWLEIQC ONES3V466GLO5CXKRF5ENK7VFOQPWM3YXLVRGWB56V5SH3W7XNBQC KMT3MF5NLEQIPZLHCRYDGQ5EA46HJCG3C2ANEPMZGKGHDK77ADPAC EAAYH6BQWDK52EC5RG3BEZQU3FJPN5RRRN4U5KDKDVPKXBVJMNDAC // In both cases (`Ok` and `Split`), we need to walk up the tree// and update each node.// Moreover, since the middle elements of the splits may be on// pages that must be freed at the end of this call, we collect// them in the `free` array below, and free them only at the end// of this function.//// If we didn't hold on to these pages, they could be reallocated// in subsequent splits, and the middle element could be// lost. This is important when the middle element climbs up more// than one level (i.e. the middle element of the split of a leaf// is also the middle element of the split of the leaf's parent,// etc).
incr_descendants::<T, K, V, P>(txn, cursor, free, freed, last_freed)?;last_freed = freed & !1;
// Here, we are copying all children of the freed// page, except possibly the last freed page (which is// a child of the current node, if we aren't at a// leaf). This includes the split key/value, also// incremented in the following call:incr_descendants::<T, K, V, P>(txn, cursor, free, freed, &mut last_freed)?;// Then, insert the split key/value in the relevant page:
// Splitting the root.debug!("split root {:?} {:?}", split_key, split_value);debug!("{:?} {:?}", left, right);
// If we are at the root, the root has// split. Insert the split key/value in a new page// above the entire tree.
incr_descendants::<T, K, V, P>(txn, cursor, free, freed, last_freed)?;last_freed = freed & !1;
// Same as above: increment the relevant reference// counters.incr_descendants::<T, K, V, P>(txn, cursor, free, freed, &mut last_freed)?;// And update the left child of the current cursor,// since the main invariant of cursors is that we're// always visiting the left child (if we're visiting// the last child of a page, the cursor is set to the// position strictly after the entries).
if let Ok(rc) = txn.rc(freed & !1) {debug!("rc = {:?}", rc);}debug!("pointer {:?} {:?}", cursor.pointer(), cursor.first_rc_level);
// Else, the "freed" page is shared with another tree, and// hence we just need to decrement its RC.
let mut c = P::cursor_before(cur.page.as_page());P::move_next(&mut c);
// Start a cursor at the leftmost position and increase the// leftmost child page's RC (if we aren't at a leaf, and if// that child isn't the last freed page).let mut c = P::cursor_first(cur.page.as_page());
// Finally, update the last freed page to be the page we just// freed (the `&!1` is here because `freed` might have its LSB set// to indicate that `freed` was allocated by the current// transaction, but that bit isn't set in references to page// `freed` on the parent page).*last_freed = freed & !1;