Added big vestigial-name-split comment
This is the _nth_ time I've tried to force arbitrary btree name inserts
to work, so _clearly_ I need a bigger comment.
Hopefully this will prevent me from trying to delete the LFSR_RATTR_NOOP
in test_btree_find_general_fuzz _again_.
---
The gist is that insert-before-bid+1 is fundamentally different from
insert-after-bid when named btrees are involved:
.-----f-----. insert-after-d .-------f-----.
.-b--. .--j-. => .-b---. .--j-.
| .-. .-. | | .---. .-. |
a c d h i k a c d e h i k
^
insert-before-h
=> .-----f-------.
.-b--. .---j-.
| .-. .---. |
a c d g h i k
^
The problem is that lfsr_btree_commit_ needs to find the same leaf
rbyd as lfsr_btree_namelookup, and potentially insert-before the
first rid or insert-after the last rid.
Instead of separate insert-before/after flags, we make the first tag
in a commit insert-before, and all following non-grow tags
insert-after (splits).
This info is now captured in the above mentioned comment.
This commit is contained in:
@@ -5436,6 +5436,36 @@ static inline uint32_t lfsr_rev_btree(lfs_t *lfs);
|
|||||||
// 1. we need a new root
|
// 1. we need a new root
|
||||||
// 2. we have a shrub root
|
// 2. we have a shrub root
|
||||||
//
|
//
|
||||||
|
// ---
|
||||||
|
//
|
||||||
|
// note! all non-bid-0 name updates must be via splits!
|
||||||
|
//
|
||||||
|
// This is because our btrees contain vestigial names, i.e. our inner
|
||||||
|
// nodes may contain names no longer in the tree. This simplifies
|
||||||
|
// lfsr_btree_commit_, but means insert-before-bid+1 is _not_ the same
|
||||||
|
// as insert-after-bid when named btrees are involved. If you try this
|
||||||
|
// it _will not_ work and if try to make it work you _will_ cry:
|
||||||
|
//
|
||||||
|
// .-----f-----. insert-after-d .-------f-----.
|
||||||
|
// .-b--. .--j-. => .-b---. .--j-.
|
||||||
|
// | .-. .-. | | .---. .-. |
|
||||||
|
// a c d h i k a c d e h i k
|
||||||
|
// ^
|
||||||
|
// insert-before-h
|
||||||
|
// => .-----f-------.
|
||||||
|
// .-b--. .---j-.
|
||||||
|
// | .-. .---. |
|
||||||
|
// a c d g h i k
|
||||||
|
// ^
|
||||||
|
//
|
||||||
|
// The problem is that lfsr_btree_commit_ needs to find the same leaf
|
||||||
|
// rbyd as lfsr_btree_namelookup, and potentially insert-before the
|
||||||
|
// first rid or insert-after the last rid.
|
||||||
|
//
|
||||||
|
// Instead of separate insert-before/after flags, we make the first tag
|
||||||
|
// in a commit insert-before, and all following non-grow tags
|
||||||
|
// insert-after (splits).
|
||||||
|
//
|
||||||
static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
|
static int lfsr_btree_commit_(lfs_t *lfs, lfsr_btree_t *btree,
|
||||||
lfsr_bctx_t *bctx,
|
lfsr_bctx_t *bctx,
|
||||||
lfsr_bid_t *bid,
|
lfsr_bid_t *bid,
|
||||||
|
|||||||
+47
-6
@@ -3866,6 +3866,28 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// split btree
|
// split btree
|
||||||
|
//
|
||||||
|
// note! all name updates _must_ be via splits (except for
|
||||||
|
// the first one)
|
||||||
|
//
|
||||||
|
// This is because our btrees contain vestigial names, i.e.
|
||||||
|
// our inner nodes may contain names no longer in the tree.
|
||||||
|
// This simplifies lfsr_btree_commit_, but means
|
||||||
|
// insert-before-bid+1 is _not_ the same as insert-after-bid
|
||||||
|
// when named btrees are involved. If you try this it _will
|
||||||
|
// not_ work and if try to make it work you _will_ cry:
|
||||||
|
//
|
||||||
|
// .-----f-----. insert-after-d .-------f-----.
|
||||||
|
// .-b--. .--j-. => .-b---. .--j-.
|
||||||
|
// | .-. .-. | | .---. .-. |
|
||||||
|
// a c d h i k a c d e h i k
|
||||||
|
// ^
|
||||||
|
// insert-before-h
|
||||||
|
// => .-----f-------.
|
||||||
|
// .-b--. .---j-.
|
||||||
|
// | .-. .---. |
|
||||||
|
// a c d g h i k
|
||||||
|
// ^
|
||||||
lfsr_bid_t split_bid;
|
lfsr_bid_t split_bid;
|
||||||
lfs_scmp_t cmp = lfsr_btree_namelookupleaf(&lfs, &btree,
|
lfs_scmp_t cmp = lfsr_btree_namelookupleaf(&lfs, &btree,
|
||||||
0, name, 3,
|
0, name, 3,
|
||||||
@@ -3882,9 +3904,7 @@ code = '''
|
|||||||
&(uint8_t){'0'+(i % 10)}, 1))) => 0;
|
&(uint8_t){'0'+(i % 10)}, 1))) => 0;
|
||||||
} else {
|
} else {
|
||||||
lfsr_btree_commit(&lfs, &btree, split_bid, LFSR_RATTRS(
|
lfsr_btree_commit(&lfs, &btree, split_bid, LFSR_RATTRS(
|
||||||
// TODO can we avoid this noop? the problem is we need
|
// yes, we need this noop, see above
|
||||||
// some way to differentiate inserting before vs after
|
|
||||||
// the requested bid
|
|
||||||
LFSR_RATTR_NOOP(),
|
LFSR_RATTR_NOOP(),
|
||||||
LFSR_RATTR_NAME(
|
LFSR_RATTR_NAME(
|
||||||
LFSR_TAG_REG, +1,
|
LFSR_TAG_REG, +1,
|
||||||
@@ -4038,6 +4058,29 @@ code = '''
|
|||||||
}
|
}
|
||||||
|
|
||||||
// split btree
|
// split btree
|
||||||
|
//
|
||||||
|
// note! all name updates _must_ be via splits (except for
|
||||||
|
// the first one)
|
||||||
|
//
|
||||||
|
// This is because our btrees contain vestigial names, i.e.
|
||||||
|
// our inner nodes may contain names no longer in the tree.
|
||||||
|
// This simplifies lfsr_btree_commit_, but means
|
||||||
|
// insert-before-bid+1 is _not_ the same as insert-after-bid
|
||||||
|
// when named btrees are involved. If you try this it _will
|
||||||
|
// not_ work and if try to make it work you _will_ cry:
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// .-----f-----. insert-after-d .-------f-----.
|
||||||
|
// .-b--. .--j-. => .-b---. .--j-.
|
||||||
|
// | .-. .-. | | .---. .-. |
|
||||||
|
// a c d h i k a c d e h i k
|
||||||
|
// ^
|
||||||
|
// insert-before-h
|
||||||
|
// => .-----f-------.
|
||||||
|
// .-b--. .---j-.
|
||||||
|
// | .-. .---. |
|
||||||
|
// a c d g h i k
|
||||||
|
// ^
|
||||||
lfsr_bid_t split_bid;
|
lfsr_bid_t split_bid;
|
||||||
lfsr_bid_t split_weight;
|
lfsr_bid_t split_weight;
|
||||||
lfs_scmp_t cmp = lfsr_btree_namelookupleaf(&lfs, &btree,
|
lfs_scmp_t cmp = lfsr_btree_namelookupleaf(&lfs, &btree,
|
||||||
@@ -4056,9 +4099,7 @@ code = '''
|
|||||||
&(uint8_t){'0'+(i % 10)}, 1))) => 0;
|
&(uint8_t){'0'+(i % 10)}, 1))) => 0;
|
||||||
} else {
|
} else {
|
||||||
lfsr_btree_commit(&lfs, &btree, split_bid, LFSR_RATTRS(
|
lfsr_btree_commit(&lfs, &btree, split_bid, LFSR_RATTRS(
|
||||||
// TODO can we avoid this noop? the problem is we need
|
// yes, we need this noop, see above
|
||||||
// some way to differentiate inserting before vs after
|
|
||||||
// the requested bid
|
|
||||||
LFSR_RATTR_NOOP(),
|
LFSR_RATTR_NOOP(),
|
||||||
LFSR_RATTR_NAME(
|
LFSR_RATTR_NAME(
|
||||||
LFSR_TAG_REG, +weight,
|
LFSR_TAG_REG, +weight,
|
||||||
|
|||||||
Reference in New Issue
Block a user