Working implementation of B-tree name split/lookup with vestigial names

B-trees with names are now working, though this required a number of
changes to the B-tree layout:

1. B-tree no-longer require name entries (LFSR_TAG_MK) on each branch.
   This is a nice optimization to the design, since these name entries
   just waste space in purely weight-based B-trees, which are probably
   going to be most B-trees in the filesystem.

   If a name entry is missing, the struct entry, which is required,
   should have the effective weight of the entry.

   The first entry in every rbyd block is expected to be have no name
   entry, since this is the default path for B-tree lookups.

2. The first entry in every rbyd block _may_ have a name entry, which
   is ignored. I'm calling these "vestigial names" to make them sound
   cooler than they actually are.

   These vestigial names show up in a couple complicated B-tree
   operations:

   - During B-tree split, since pending attributes are calculated before
     the split, we need to play out pending attributes into the rbyd
     before deciding what name becomes the name of entry in the parent.
     This creates a vestigial name which we _could_ immediately remove,
     but the remove adds additional size to the must-fit split operation

   - During B-tree pop/merge, if we remove the leading no-name entry,
     the second, named entry becomes the leading entry. This creates a
     vestigial name that _looks_ easy enough to remove when making the
     pending attributes for pop/merge, but turns out the be surprisingly
     tricky if the parent undergoes a split/merge at the same time.

   It may be possible to remove all these vestigial names proactively,
   but this adds additional rbyd lookups to figure out the exact tag to
   remove, complicates things in a fragile way, and doesn't actually
   reduce storage costs until the rbyd is compacted.

   The main downside is that these B-trees may be a bit more confusing
   to debug.
This commit is contained in:
Christopher Haster
2023-03-20 19:23:15 -05:00
parent 7a0842295c
commit 89d5a5ef80
4 changed files with 161 additions and 68 deletions
+15 -4
View File
@@ -3458,14 +3458,25 @@ code = '''
}
// split btree
lfsr_btree_split(&lfs, &btree, id, name, 3,
LFSR_TAG_INLINED, 1, &nums[i % 10], 1,
LFSR_TAG_INLINED, 1, &nums[i % 10], 1) => 0;
lfs_size_t split_id;
uint8_t split_buf[4];
lfsr_btree_find(&lfs, &btree, name, 3,
NULL, &split_id, NULL, split_buf, 4) => 1;
if (split_id > id) {
lfsr_btree_split(&lfs, &btree,
split_id, sim_names[split_id], 3,
LFSR_TAG_INLINED, 1, &nums[i % 10], 1,
LFSR_TAG_INLINED, 1, split_buf, 1) => 0;
} else {
lfsr_btree_split(&lfs, &btree,
split_id, name, 3,
LFSR_TAG_INLINED, 1, split_buf, 1,
LFSR_TAG_INLINED, 1, &nums[i % 10], 1) => 0;
}
// split sim
memmove(&sim[id+1], &sim[id], sim_size-id);
memmove(&sim_names[id+1], &sim_names[id], (sim_size-id)*3);
sim[id+0] = nums[i % 10];
sim[id+1] = nums[i % 10];
memcpy(&sim_names[id+1], name, 3);
sim_size += 1;