pijul nest
guest [sign in]

A few comments

[?]
Feb 12, 2021, 2:18 PM
RV2L6CZWTMUQ2A52YDAFVHDFGURZL3H4SSCDC347UGN23D3J5KZQC

Dependencies

  • [2] NXMFNPZ7 Comments + debugging drop
  • [3] OFINGD26 implementing prev() on cursors (+ some cleanup)
  • [4] OP6SVMOD Resetting history
  • [5] DV4A2LR7 Double-inserts (rebalancing near an internal deletion)
  • [6] 6DMPXOAT More debugging
  • [7] EAAYH6BQ Debugging put
  • [8] S4V4QZ5C Debugging reference-counting for put
  • [9] OTWDDJE7 Trait/type cleanup
  • [10] 6UVFCERM Formatting, debugging, etc.
  • [11] KMT3MF5N Drop a database
  • [12] ONES3V46 reference counting works for put
  • [13] H3FVSQIQ Unsized pages
  • [14] 6DCQHIFP Minor changes after benchmarking
  • [15] W26CFMAQ Improving safety of cursors
  • [16] XEU2QVLC Debugging after plugging this into Pijul
  • [17] 73Z2UB3J Cleanup + comments
  • [18] WS4ZQM4R Debugging, tests, etc.
  • [19] FMN7X4J2 Micro-improvements, now noticeably faster than std::collections::BTreeMap
  • [20] UUUVNC4D Debugging/cleanup around cursors

Change contents

  • edit in sanakirja-core/src/btree/put.rs at line 13
    [3.3963][3.624:636]()
    use log::*;
  • edit in sanakirja-core/src/btree/put.rs at line 28
    [3.4317]
    [3.0]
    // Set the cursor to the first element larger than or equal to
    // `(key, value)`. We will insert at that position (where "insert"
    // is meant in the sense of Rust's `Vec::insert`.
  • edit in sanakirja-core/src/btree/put.rs at line 33
    [3.4417]
    [3.4417]
    // If `(key, value)` already exists in the tree, return.
  • edit in sanakirja-core/src/btree/put.rs at line 36
    [3.4449]
    [3.4449]
    // Else, we are at a leaf, since cursors that don't find an
    // element go all the way to the leaves.
    //
    // We put on the leaf page, resulting in a `Put`, i.e. either
    // `Put::Ok` or `Put::Split`.
  • edit in sanakirja-core/src/btree/put.rs at line 54
    [3.4683]
    [3.4683]
    // 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).
  • edit in sanakirja-core/src/btree/put.rs at line 70
    [3.4718]
    [3.67]
    let p = cursor.pointer(); // Save the position of cursor at the leaf.
  • replacement in sanakirja-core/src/btree/put.rs at line 72
    [3.78][3.4780:4807](),[3.4780][3.4780:4807]()
    for f in free.iter() {
    [3.136]
    [3.4807]
    for f in &free[..p] {
  • replacement in sanakirja-core/src/btree/put.rs at line 94
    [3.175][3.0:28]()
    for _ in 0..N_CURSORS {
    [3.175]
    [3.5216]
    loop {
  • replacement in sanakirja-core/src/btree/put.rs at line 103
    [3.5404][3.176:304]()
    incr_descendants::<T, K, V, P>(txn, cursor, free, freed, last_freed)?;
    last_freed = freed & !1;
    [3.5404]
    [3.81]
    // 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:
  • edit in sanakirja-core/src/btree/put.rs at line 112
    [3.123]
    [3.79]
    // If we aren't at the root, just pop the cursor
    // stack and insert a new entry in the page above.
  • replacement in sanakirja-core/src/btree/put.rs at line 129
    [3.532][3.5641:5684](),[3.5641][3.5641:5684](),[3.5684][3.656:786]()
    // Splitting the root.
    debug!("split root {:?} {:?}", split_key, split_value);
    debug!("{:?} {:?}", left, right);
    [3.532]
    [3.832]
    // If we are at the root, the root has
    // split. Insert the split key/value in a new page
    // above the entire tree.
  • edit in sanakirja-core/src/btree/put.rs at line 146
    [3.6102]
    [3.6102]
    // Return the new root.
  • replacement in sanakirja-core/src/btree/put.rs at line 151
    [3.7298][3.342:470]()
    incr_descendants::<T, K, V, P>(txn, cursor, free, freed, last_freed)?;
    last_freed = freed & !1;
    [3.7298]
    [3.221]
    // 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).
  • edit in sanakirja-core/src/btree/put.rs at line 161
    [3.263]
    [3.114]
    // If we aren't at the root, just update the child.
  • edit in sanakirja-core/src/btree/put.rs at line 172
    [3.953]
    [3.953]
    // If we are at the root, `page` is the updated root.
  • edit in sanakirja-core/src/btree/put.rs at line 178
    [3.7436][3.29:48]()
    unreachable!()
  • edit in sanakirja-core/src/btree/put.rs at line 180
    [3.7439]
    [3.7439]
    /// This function does all the memory management for `put`.
  • replacement in sanakirja-core/src/btree/put.rs at line 191
    [3.7672][3.508:529]()
    last_freed: u64,
    [3.7672]
    [3.7672]
    last_freed: &mut u64,
  • edit in sanakirja-core/src/btree/put.rs at line 193
    [3.7700][3.850:956](),[3.956][3.331:357](),[3.357][3.980:1017](),[3.980][3.980:1017]()
    debug!(
    "incr_descendants {:?} {:?} {:?} {:?}",
    cursor.current().page,
    freed,
    cursor.pointer(),
    cursor.first_rc_level
    );
  • replacement in sanakirja-core/src/btree/put.rs at line 194
    [3.408][3.7748:7814](),[3.7748][3.7748:7814]()
    // This also includes the case where cursor.pointer == 0.
    [3.408]
    [3.409]
    // If a page has split or was immutable (allocated by a
    // previous transaction) and has been updated, we need to free
    // the old page.
  • replacement in sanakirja-core/src/btree/put.rs at line 199
    [3.7865][3.0:92](),[3.92][3.149:227]()
    if let Ok(rc) = txn.rc(freed & !1) {
    debug!("rc = {:?}", rc);
    }
    debug!("pointer {:?} {:?}", cursor.pointer(), cursor.first_rc_level);
    [3.7865]
    [3.450]
    // Else, the "freed" page is shared with another tree, and
    // hence we just need to decrement its RC.
  • replacement in sanakirja-core/src/btree/put.rs at line 205
    [3.8123][3.749:798]()
    debug!("free child: {:?}", last_freed);
    [3.8123]
    [3.8123]
    // This means that the new version of the page (either split
    // or not) contains references to all the children of the
    // freed page, except the last freed page (because the new
    // version of that page isn't shared).
  • replacement in sanakirja-core/src/btree/put.rs at line 210
    [3.8159][3.272:330](),[3.330][3.80:110]()
    let mut c = P::cursor_before(cur.page.as_page());
    P::move_next(&mut c);
    [3.8159]
    [3.1067]
    // 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());
  • replacement in sanakirja-core/src/btree/put.rs at line 216
    [3.1125][3.799:883]()
    if left != 0 && left != last_freed {
    debug!("incr {:?}", left);
    [3.1125]
    [3.8290]
    if left != 0 && left != *last_freed {
  • edit in sanakirja-core/src/btree/put.rs at line 219
    [3.8332]
    [3.1136]
    // Then, for each entry of the page, increase the RCs of
    // references contained in the keys and values, and increase
    // the RC of the right child.
  • replacement in sanakirja-core/src/btree/put.rs at line 226
    [3.8508][3.884:967]()
    if r != 0 && r != last_freed {
    debug!("incr {:?}", r);
    [3.8508]
    [3.8536]
    if r != 0 && r != *last_freed {
  • edit in sanakirja-core/src/btree/put.rs at line 231
    [3.8599]
    [3.8599]
    // 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;
  • replacement in sanakirja-core/src/btree/mod.rs at line 100
    [3.10049][3.10049:10103]()
    /// cursor isn't at the end of the page already).
    [3.10049]
    [3.10103]
    /// cursor isn't already after the last element).
  • edit in sanakirja-core/src/btree/mod.rs at line 390
    [3.9368]
    [3.797]
    // This is a for loop, to allow the compiler to unroll (maybe).
  • edit in sanakirja-core/src/btree/mod.rs at line 399
    [3.15846]
    [3.10180]
    // Here, Rust says that `k` and `v` have the same lifetime
    // as `page`, but we actually know that they're alive for
    // as long as `txn` doesn't change, so we can safely
    // extend their lifetimes:
  • edit in sanakirja-core/src/btree/mod.rs at line 405
    [3.1335]
    [3.1335]
    // The cursor is set to the first element greater than or
    // equal to the (k, v) we're looking for, so we need to
    // explore the left subtree.
  • edit in sanakirja-core/src/btree/mod.rs at line 429
    [3.837]
    [2.1744]
    // In order to make this function tail-recursive, we simulate a
    // stack with the following:
  • edit in sanakirja-core/src/btree/mod.rs at line 432
    [2.1776][3.518:519](),[3.4201][3.518:519]()
  • edit in sanakirja-core/src/btree/mod.rs at line 434
    [2.1912]
    [2.1912]
    let mut ptr = 0;
    // Push the root page of `db` onto the stack.
  • replacement in sanakirja-core/src/btree/mod.rs at line 442
    [2.2075][2.2075:2096]()
    let mut ptr = 0;
    [2.2075]
    [2.2096]
    // Then perform a DFS:
  • edit in sanakirja-core/src/btree/mod.rs at line 445
    [2.2107]
    [2.2107]
    // Look at the top element of the stack.
  • edit in sanakirja-core/src/btree/mod.rs at line 447
    [2.2167]
    [2.2167]
    // If it needs to be dropped (i.e. if its RC is <= 1), iterate
    // its cursor and drop all its referenced pages.
  • edit in sanakirja-core/src/btree/mod.rs at line 451
    [2.2231]
    [2.2231]
    // if there's a current element in the cursor (i.e. we
    // aren't before or after the elements), decrease its RC.
  • edit in sanakirja-core/src/btree/mod.rs at line 458
    [3.1208]
    [2.2443]
    // In all cases, move next and push the left child onto
    // the stack. This works because pushed cursors are
    // initially set to before the page's elements.
  • edit in sanakirja-core/src/btree/mod.rs at line 474
    [3.1286]
    [2.2917]
    // Here, either rc > 1, or else `P::move_next` returned
    // `false`, meaning that the cursor is after the last element.
  • edit in sanakirja-core/src/btree/mod.rs at line 481
    [2.3081]
    [2.3081]
    // If this was the bottom element of the stack, stop, else, pop.