btree: Dropped reliance on leaf cache during traversals
Brings back lfs3_btrv_t, but keeps some of the btree internal changes.
I think the biggest one is dropping the internal branch pointer, now
instead of internally pointing to the root rbyd, we just unconditionally
sync the rbyd state anytime the rbyd matches the root's weight. This is
necessary to avoid out-of-sync state when traversing bshrubs under
mutation.
Also after refactoring I think the current btree traversal logic is
easier to read.
---
This is in preparation for removing the leaf cache, or at least making
it opt-in.
It adds a chunk of stack, but in theory we can reclaim this by allowing
leaf caches to be disabled:
code stack ctx
before: 37160 2352 688
after: 37088 (-0.2%) 2384 (+1.4%) 688 (+0.0%)
This commit is contained in:
+40
-20
@@ -183,15 +183,17 @@ code = '''
|
||||
lfs3_size_t fragments = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -329,15 +331,17 @@ code = '''
|
||||
lfs3_block_t blocks = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -593,15 +597,17 @@ code = '''
|
||||
lfs3_size_t fragments = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -754,15 +760,17 @@ code = '''
|
||||
lfs3_block_t blocks = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -2080,15 +2088,17 @@ code = '''
|
||||
lfs3_size_t fragments = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -2230,15 +2240,17 @@ code = '''
|
||||
lfs3_size_t fragments = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -2527,15 +2539,17 @@ code = '''
|
||||
lfs3_size_t fragments = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -2692,15 +2706,17 @@ code = '''
|
||||
lfs3_block_t blocks = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -2983,15 +2999,17 @@ code = '''
|
||||
lfs3_size_t fragments = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
@@ -3152,15 +3170,17 @@ code = '''
|
||||
lfs3_block_t blocks = 0;
|
||||
|
||||
lfs3_file_open(&lfs3, &file, "hello", LFS3_O_RDONLY) => 0;
|
||||
lfs3_sbid_t bid = -2;
|
||||
lfs3_btrv_t btrv;
|
||||
lfs3_btrv_init(&btrv);
|
||||
for (lfs3_block_t i = 0;; i++) {
|
||||
// a bit hacky, but this catches infinite loops
|
||||
assert(i < 2*BLOCK_COUNT);
|
||||
|
||||
lfs3_stag_t tag;
|
||||
lfs3_sbid_t bid;
|
||||
lfs3_bid_t weight;
|
||||
lfs3_data_t data;
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, bid+1,
|
||||
tag = lfs3_bshrub_traverse(&lfs3, &file.b, &btrv,
|
||||
&bid, &weight, &data);
|
||||
assert(tag >= 0 || tag == LFS3_ERR_NOENT);
|
||||
if (tag == LFS3_ERR_NOENT) {
|
||||
|
||||
Reference in New Issue
Block a user