Changed rbyd removes to remove from the tree, similar to deletes
Tag removal is basically a range-delete of one that doesn't change the tree weights. This deduplicates the two methods of deleting tags and completely gets rid of tombstoning. Note we still need a "removed tag" encoding so that we can invalidate tags that may be found during fetch operations. Fortunately this encoding is basically free due to overlap with alt encoding.
This commit is contained in:
@@ -1286,7 +1286,6 @@ static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
tryagain:;
|
||||
// no trunk yet?
|
||||
lfs_off_t branch = rbyd->trunk;
|
||||
if (!branch) {
|
||||
@@ -1329,17 +1328,10 @@ tryagain:;
|
||||
printf("lookup %08x => %08x (raw %08x)\n", tag, tag_, alt);
|
||||
|
||||
// not what we're looking for?
|
||||
if (tag_ < tag) {
|
||||
if (tag_ < tag || lfs_rtag_isrm(tag_)) {
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
// TODO we should make this impossible
|
||||
// was removed? go on to the next tag
|
||||
if (lfs_rtag_isrm(tag_)) {
|
||||
tag = lfs_rtag_inc(tag_);
|
||||
goto tryagain;
|
||||
}
|
||||
|
||||
// save what we found
|
||||
*off = branch + delta;
|
||||
*size = jump;
|
||||
@@ -1831,11 +1823,19 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_,
|
||||
lfs_rtag_t lower_upper = (rbyd_->count+1) << 15;
|
||||
lfs_rtag_t upper_lower = 0;
|
||||
lfs_rtag_t upper_upper = (rbyd_->count+1) << 15;
|
||||
lfs_rtag_t lower_tag__ = tag & ~0x7fff;
|
||||
lfs_rtag_t upper_tag__ = lower_tag__ + 0x8000;
|
||||
lfs_rtag_t lower_tag__; // = tag & ~0x7fff;
|
||||
lfs_rtag_t upper_tag__; // = lower_tag__ + 0x8000;
|
||||
lfs_rtag_t lower_tag_ = 0;
|
||||
lfs_rtag_t upper_tag_ = 0;
|
||||
|
||||
if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) {
|
||||
lower_tag__ = tag & ~0x7fff;
|
||||
upper_tag__ = lower_tag__ + 0x8000;
|
||||
} else {
|
||||
lower_tag__ = tag & ~0x1;
|
||||
upper_tag__ = lower_tag__ + 0x8;
|
||||
}
|
||||
|
||||
// // weights for pruning
|
||||
// lfs_srtag_t lower_lt = lfs_rtag_weight_lt(tag & ~0x7fff, rbyd_->count+1);
|
||||
// lfs_srtag_t lower_gt = lfs_rtag_weight_gt(tag & ~0x7fff, rbyd_->count+1);
|
||||
@@ -2244,42 +2244,83 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_,
|
||||
// }
|
||||
|
||||
// split leaf nodes?
|
||||
if (lower_tag_ != tag // TODO need this check?
|
||||
&& lfs_rtag_weight_(lower_tag_)
|
||||
< lfs_rtag_weight_(tag & ~0x7fff)) {
|
||||
printf("bsplit lower\n");
|
||||
alt = LFS_MKRALT__(B, LT,
|
||||
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
||||
if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) {
|
||||
if (lower_tag_ != tag // TODO need this check?
|
||||
&& lfs_rtag_weight_(lower_tag_)
|
||||
< lfs_rtag_weight_(tag & ~0x7fff)) {
|
||||
printf("bsplit lower\n");
|
||||
alt = LFS_MKRALT__(B, LT,
|
||||
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
||||
|
||||
// TODO can we rededuplicate this?
|
||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
||||
p_alts, p_jumps,
|
||||
alt, lower_branch);
|
||||
if (err) {
|
||||
return err;
|
||||
// TODO can we rededuplicate this?
|
||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
||||
p_alts, p_jumps,
|
||||
alt, lower_branch);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
||||
}
|
||||
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
||||
}
|
||||
if (upper_tag_ != tag // TODO need this check?
|
||||
&& lfs_rtag_weight_(upper_tag_)
|
||||
>= lfs_rtag_weight_(tag & ~0x7fff)+0x8000) {
|
||||
printf("bsplit upper\n");
|
||||
alt = LFS_MKRALT__(B, GT,
|
||||
upper_upper - (lfs_rtag_weight_(lower_tag_)+0x8));
|
||||
// upper_upper - (lfs_rtag_weight_(tag & ~0x7fff)
|
||||
// +0x8000+0x8));
|
||||
|
||||
if (upper_tag_ != tag // TODO need this check?
|
||||
&& lfs_rtag_weight_(upper_tag_)
|
||||
>= lfs_rtag_weight_(tag & ~0x7fff)+0x8000) {
|
||||
printf("bsplit upper\n");
|
||||
alt = LFS_MKRALT__(B, GT,
|
||||
upper_upper - (lfs_rtag_weight_(lower_tag_)+0x8));
|
||||
// upper_upper - (lfs_rtag_weight_(tag & ~0x7fff)
|
||||
// +0x8000+0x8));
|
||||
// TODO can we rededuplicate this?
|
||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
||||
p_alts, p_jumps,
|
||||
alt, upper_branch);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// TODO can we rededuplicate this?
|
||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
||||
p_alts, p_jumps,
|
||||
alt, upper_branch);
|
||||
if (err) {
|
||||
return err;
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
||||
}
|
||||
} else {
|
||||
if (lower_tag_ != tag // TODO need this check?
|
||||
&& lfs_rtag_weight_(lower_tag_)
|
||||
< lfs_rtag_weight_(tag & ~0x1)) {
|
||||
printf("bsplit lower\n");
|
||||
alt = LFS_MKRALT__(B, LT,
|
||||
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
||||
|
||||
// TODO can we rededuplicate this?
|
||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
||||
p_alts, p_jumps,
|
||||
alt, lower_branch);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
||||
}
|
||||
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
||||
if (upper_tag_ != tag // TODO need this check?
|
||||
&& lfs_rtag_weight_(upper_tag_)
|
||||
>= lfs_rtag_weight_(tag & ~0x1)+0x8) {
|
||||
printf("bsplit upper\n");
|
||||
alt = LFS_MKRALT__(B, GT,
|
||||
upper_upper - (lfs_rtag_weight_(lower_tag_)+0x8)
|
||||
+ 0x8);
|
||||
// upper_upper - (lfs_rtag_weight_(tag & ~0x7fff)
|
||||
// +0x8000+0x8));
|
||||
|
||||
// TODO can we rededuplicate this?
|
||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
||||
p_alts, p_jumps,
|
||||
alt, upper_branch);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
||||
}
|
||||
}
|
||||
|
||||
// flush any pending alts
|
||||
@@ -2344,7 +2385,7 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
||||
|
||||
// append each tag to the tree
|
||||
for (const struct lfs_rattr *attr = attrs; attr; attr = attr->next) {
|
||||
if (lfs_rtag_type1(attr->tag) == LFS_TYPE1_DELETE) {
|
||||
if (lfs_rtag_isrm(attr->tag)) {
|
||||
// deletes require range-deletion, this is a bit more complicated
|
||||
// than normal tags
|
||||
int err = lfs_rbyd_delete(lfs, &rbyd_,
|
||||
|
||||
+23
-23
@@ -1876,29 +1876,29 @@ code = '''
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
// commit with two attributes, remove the second one
|
||||
rbyd = init_rbyd;
|
||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||
lfs_rbyd_commit(&lfs, &rbyd,
|
||||
LFS_MKRATTR(UATTR, 1, 0, "\xaa\xaa\xaa\xaa", 4,
|
||||
LFS_MKRATTR(UATTR, 2, 0, "\xbb\xbb\xbb\xbb", 4, NULL))) => 0;
|
||||
lfs_rbyd_commit(&lfs, &rbyd,
|
||||
LFS_MKRRMATTR(UATTR, 2, 0, NULL)) => 0;
|
||||
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
|
||||
=> LFS_MKRTAG(UATTR, 1, 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
|
||||
=> LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
|
||||
=> LFS_MKRTAG(UATTR, 1, 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
|
||||
=> LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
|
||||
=> LFS_ERR_NOENT;
|
||||
// // commit with two attributes, remove the second one
|
||||
// rbyd = init_rbyd;
|
||||
// lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||
// lfs_rbyd_commit(&lfs, &rbyd,
|
||||
// LFS_MKRATTR(UATTR, 1, 0, "\xaa\xaa\xaa\xaa", 4,
|
||||
// LFS_MKRATTR(UATTR, 2, 0, "\xbb\xbb\xbb\xbb", 4, NULL))) => 0;
|
||||
// lfs_rbyd_commit(&lfs, &rbyd,
|
||||
// LFS_MKRRMATTR(UATTR, 2, 0, NULL)) => 0;
|
||||
//
|
||||
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
|
||||
// => LFS_MKRTAG(UATTR, 1, 0);
|
||||
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
|
||||
// => LFS_ERR_NOENT;
|
||||
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
|
||||
// => LFS_ERR_NOENT;
|
||||
//
|
||||
// lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), &off, &size)
|
||||
// => LFS_MKRTAG(UATTR, 1, 0);
|
||||
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), &off, &size)
|
||||
// => LFS_ERR_NOENT;
|
||||
// lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), &off, &size)
|
||||
// => LFS_ERR_NOENT;
|
||||
'''
|
||||
|
||||
[cases.test_rbyd_remove_permutations]
|
||||
|
||||
Reference in New Issue
Block a user