Merged lfs_rbyd_append and lfs_rbyd_delete

Now we have one massive chimera of a function that does everything. This
is good software design, trust me.
This commit is contained in:
Christopher Haster
2023-01-05 11:32:54 -06:00
parent 179a1df3d3
commit 17a043f4b8
+373 -305
View File
@@ -1517,304 +1517,303 @@ static void lfs_rbyd_p_red(
} }
} }
static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_, //static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
lfs_rtag_t tag, const void *buffer, lfs_size_t size) { // lfs_rtag_t tag, const void *buffer, lfs_size_t size) {
printf("- append() -\n"); // printf("- append() -\n");
LFS_ASSERT(lfs_rtag_id(tag) <= rbyd_->count+1); // LFS_ASSERT(lfs_rtag_id(tag) <= rbyd_->count+1);
//
// assume we'll update our trunk // // assume we'll update our trunk
lfs_off_t branch = rbyd_->trunk; // lfs_off_t branch = rbyd_->trunk;
rbyd_->trunk = rbyd_->off; // rbyd_->trunk = rbyd_->off;
//
// no trunk yet? // // no trunk yet?
if (!branch) { // if (!branch) {
goto leaf; // goto leaf;
}
// keep track of bounds as we descend down the tree
lfs_rtag_t lower = 0;
lfs_rtag_t upper = (rbyd_->count+1) << 15;
lfs_rtag_t tag__;
if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
tag__ = tag & ~0x7fff;
} else {
tag__ = tag;
}
// // weights for pruning
// lfs_srtag_t lt;
// lfs_srtag_t gt;
// if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
// // inserting a new id? align down
// // TODO special function for this?
//// if (lfs_rtag_id(attr->tag) == count+1) {
//// lt = (count+1) << 12;
//// gt = 0;
//// } else {
//// lt = lfs_rtag_weight_lt(attr->tag & ~0x7fff, count+1);
//// gt = lfs_rtag_weight_gt(attr->tag & ~0x7fff, count+1);
//// }
// lt = lfs_rtag_weight_lt(tag & ~0x7fff, rbyd_->count+1) - 1;
// gt = lfs_rtag_weight_gt(tag & ~0x7fff, rbyd_->count+1) + 1;
// } else {
// lt = lfs_rtag_weight_lt(tag, rbyd_->count+1);
// gt = lfs_rtag_weight_gt(tag, rbyd_->count+1);
// } // }
// //
// printf("lt, gt = (%x, %x)\n", lt, gt); // // keep track of bounds as we descend down the tree
// lfs_rtag_t lower = 0;
// queue of pending alts we can emulate rotations with // lfs_rtag_t upper = (rbyd_->count+1) << 15;
lfs_rtag_t p_alts[3] = {0, 0, 0}; // lfs_rtag_t tag__;
lfs_off_t p_jumps[3] = {0, 0, 0}; // if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
lfs_off_t graft = 0; // tag__ = tag & ~0x7fff;
// } else {
// descend down tree, building alt pointers // tag__ = tag;
while (true) { // }
lfs_rtag_t alt; //
lfs_off_t jump; //// // weights for pruning
lfs_ssize_t delta = lfs_rbyd_readtag(lfs, //// lfs_srtag_t lt;
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size, //// lfs_srtag_t gt;
rbyd_->block, branch, &alt, &jump, NULL); //// if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
if (delta < 0) { //// // inserting a new id? align down
return delta; //// // TODO special function for this?
} ////// if (lfs_rtag_id(attr->tag) == count+1) {
////// lt = (count+1) << 12;
// found an alt? ////// gt = 0;
if (lfs_rtag_isalt(alt)) { ////// } else {
// make jump absolute ////// lt = lfs_rtag_weight_lt(attr->tag & ~0x7fff, count+1);
jump = branch - jump; ////// gt = lfs_rtag_weight_gt(attr->tag & ~0x7fff, count+1);
lfs_rtag_t branch_ = branch + delta; ////// }
//// lt = lfs_rtag_weight_lt(tag & ~0x7fff, rbyd_->count+1) - 1;
// prune? //// gt = lfs_rtag_weight_gt(tag & ~0x7fff, rbyd_->count+1) + 1;
if (lfs_rtag_weight_(alt) >= (upper-lower)) { //// } else {
if (p_alts[0] && lfs_rtag_isred(p_alts[0])) { //// lt = lfs_rtag_weight_lt(tag, rbyd_->count+1);
printf("prune red!\n"); //// gt = lfs_rtag_weight_gt(tag, rbyd_->count+1);
//// }
alt = lfs_rtag_black(p_alts[0]); ////
branch_ = jump; //// printf("lt, gt = (%x, %x)\n", lt, gt);
jump = p_jumps[0]; //
lfs_rbyd_p_pop(p_alts, p_jumps); // // queue of pending alts we can emulate rotations with
// lfs_rtag_t p_alts[3] = {0, 0, 0};
lfs_rtag_untrim_(alt, &lower, &upper); // lfs_off_t p_jumps[3] = {0, 0, 0};
} else { // lfs_off_t graft = 0;
printf("prune!\n"); //
// // descend down tree, building alt pointers
graft = 0; // TODO? // while (true) {
branch = jump; // lfs_rtag_t alt;
continue; // lfs_off_t jump;
} // lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
} // &lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
// rbyd_->block, branch, &alt, &jump, NULL);
// two reds makes a yellow, split? // if (delta < 0) {
if (lfs_rtag_isred(alt) // return delta;
&& p_alts[0] // }
&& lfs_rtag_isred(p_alts[0])) { //
LFS_ASSERT(lfs_rtag_isparallel(alt, p_alts[0])); // // found an alt?
// if (lfs_rtag_isalt(alt)) {
// if we take the red or yellow alt we can just point // // make jump absolute
// to the black alt, otherwise we need to point to the // jump = branch - jump;
// yellow alt and prune later // lfs_rtag_t branch_ = branch + delta;
if (lfs_rtag_follow_(alt, lower, upper, tag__)) { //
printf("ysplit follow\n"); // // prune?
lfs_rtag_t alt_ = p_alts[0]; // if (lfs_rtag_weight_(alt) >= (upper-lower)) {
lfs_off_t jump_ = p_jumps[0]; // if (p_alts[0] && lfs_rtag_isred(p_alts[0])) {
p_alts[0] = lfs_rtag_black( // printf("prune red!\n");
lfs_rtag_flip_(alt, lower, upper)); //
p_jumps[0] = branch_; // alt = lfs_rtag_black(p_alts[0]);
alt = lfs_rtag_black(alt_); // branch_ = jump;
branch_ = jump; // jump = p_jumps[0];
jump = jump_; // lfs_rbyd_p_pop(p_alts, p_jumps);
//
lfs_rtag_untrim_(alt, &lower, &upper); // lfs_rtag_untrim_(alt, &lower, &upper);
lfs_rtag_trim_(p_alts[0], &lower, &upper); // } else {
lfs_rbyd_p_red(p_alts, p_jumps); // printf("prune!\n");
//
} else { // graft = 0; // TODO?
printf("ysplit nofollow\n"); // branch = jump;
LFS_ASSERT(graft != 0); // continue;
p_alts[0] = lfs_rtag_black( // }
lfs_rtag_merge(alt, p_alts[0]));
p_jumps[0] = graft;
lfs_rtag_trim_(alt, &lower, &upper);
lfs_rbyd_p_red(p_alts, p_jumps);
graft = 0; // TODO
branch = branch_;
continue;
}
}
// should've taken red alt? needs a flip
//
// note we need a check for a valid red alt due to creates
// TODO note we can get rid of this if we create at the upper
// boundary of the previous id
if (p_alts[0]
&& ((lfs_rtag_islt(p_alts[0]) && tag__ < lower)
|| (lfs_rtag_isgt(p_alts[0]) && tag__ >= upper))) {
LFS_ASSERT(lfs_rtag_isred(p_alts[0]));
LFS_ASSERT(lfs_rtag_isblack(alt));
printf("rflip %s\n",
lfs_rtag_isparallel(alt, p_alts[0]) ? "parallel" : "perpendicular");
// if black alt would've been taken, it also needs a flip
if (lfs_rtag_isparallel(alt, p_alts[0])) {
alt = lfs_rtag_flip_(alt, lower, upper);
lfs_off_t jump_ = jump;
jump = branch_;
branch_ = jump_;
}
lfs_rtag_t alt_ = p_alts[0];
lfs_off_t jump_ = p_jumps[0];
p_alts[0] = lfs_rtag_red(alt);
p_jumps[0] = jump;
alt = lfs_rtag_black(alt_);
jump = jump_;
lfs_rtag_untrim_(alt, &lower, &upper);
lfs_rtag_trim_(p_alts[0], &lower, &upper);
}
// take black alt? needs a flip
if (lfs_rtag_isblack(alt) && lfs_rtag_follow_(alt, lower, upper, tag__)) {
printf("bflip\n");
alt = lfs_rtag_flip_(alt, lower, upper);
lfs_off_t jump_ = jump;
jump = branch_;
branch_ = jump_;
}
// push alt onto queue
int err = lfs_rbyd_p_push(lfs, rbyd_,
p_alts, p_jumps,
alt, jump);
if (err) {
return err;
}
// continue to next alt
lfs_rtag_trim_(alt, &lower, &upper);
graft = branch;
branch = branch_;
// found end of tree?
} else {
// update the tag id
// TODO should this be a function? maybe see what create/delete need
// TODO alternatively can we do this a bit more directly here
// lfs_rtag_t tag_ = lfs_rtag_setid(alt,
// lfs_min(lfs_rtag_id(attr->tag), count));
//lfs_rtag_t tag_ = lfs_rtag_setid(alt, lfs_rtag_id(tag));
// TODO I don't really know why this works
// if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE && gt == 0) {
// tag_ = lfs_rtag_decid(tag_);
// } // }
lfs_rtag_t tag_ = lfs_rtag_setid(alt, lfs_rtag_id(upper-1)); //
// // two reds makes a yellow, split?
// if (lfs_rtag_isred(alt)
// && p_alts[0]
// && lfs_rtag_isred(p_alts[0])) {
// LFS_ASSERT(lfs_rtag_isparallel(alt, p_alts[0]));
//
// // if we take the red or yellow alt we can just point
// // to the black alt, otherwise we need to point to the
// // yellow alt and prune later
// if (lfs_rtag_follow_(alt, lower, upper, tag__)) {
// printf("ysplit follow\n");
// lfs_rtag_t alt_ = p_alts[0];
// lfs_off_t jump_ = p_jumps[0];
// p_alts[0] = lfs_rtag_black(
// lfs_rtag_flip_(alt, lower, upper));
// p_jumps[0] = branch_;
// alt = lfs_rtag_black(alt_);
// branch_ = jump;
// jump = jump_;
//
// lfs_rtag_untrim_(alt, &lower, &upper);
// lfs_rtag_trim_(p_alts[0], &lower, &upper);
// lfs_rbyd_p_red(p_alts, p_jumps);
//
// } else {
// printf("ysplit nofollow\n");
// LFS_ASSERT(graft != 0);
// p_alts[0] = lfs_rtag_black(
// lfs_rtag_merge(alt, p_alts[0]));
// p_jumps[0] = graft;
//
// lfs_rtag_trim_(alt, &lower, &upper);
// lfs_rbyd_p_red(p_alts, p_jumps);
//
// graft = 0; // TODO
// branch = branch_;
// continue;
// }
// }
//
// // should've taken red alt? needs a flip
// //
// // note we need a check for a valid red alt due to creates
// // TODO note we can get rid of this if we create at the upper
// // boundary of the previous id
// if (p_alts[0]
// && ((lfs_rtag_islt(p_alts[0]) && tag__ < lower)
// || (lfs_rtag_isgt(p_alts[0]) && tag__ >= upper))) {
// LFS_ASSERT(lfs_rtag_isred(p_alts[0]));
// LFS_ASSERT(lfs_rtag_isblack(alt));
//
// printf("rflip %s\n",
// lfs_rtag_isparallel(alt, p_alts[0]) ? "parallel" : "perpendicular");
//
// // if black alt would've been taken, it also needs a flip
// if (lfs_rtag_isparallel(alt, p_alts[0])) {
// alt = lfs_rtag_flip_(alt, lower, upper);
// lfs_off_t jump_ = jump;
// jump = branch_;
// branch_ = jump_;
// }
//
// lfs_rtag_t alt_ = p_alts[0];
// lfs_off_t jump_ = p_jumps[0];
// p_alts[0] = lfs_rtag_red(alt);
// p_jumps[0] = jump;
// alt = lfs_rtag_black(alt_);
// jump = jump_;
//
// lfs_rtag_untrim_(alt, &lower, &upper);
// lfs_rtag_trim_(p_alts[0], &lower, &upper);
// }
//
// // take black alt? needs a flip
// if (lfs_rtag_isblack(alt) && lfs_rtag_follow_(alt, lower, upper, tag__)) {
// printf("bflip\n");
// alt = lfs_rtag_flip_(alt, lower, upper);
// lfs_off_t jump_ = jump;
// jump = branch_;
// branch_ = jump_;
// }
//
// // push alt onto queue
// int err = lfs_rbyd_p_push(lfs, rbyd_,
// p_alts, p_jumps,
// alt, jump);
// if (err) {
// return err;
// }
//
// // continue to next alt
// lfs_rtag_trim_(alt, &lower, &upper);
// graft = branch;
// branch = branch_;
//
// // found end of tree?
// } else {
// // update the tag id
// // TODO should this be a function? maybe see what create/delete need
// // TODO alternatively can we do this a bit more directly here
//// lfs_rtag_t tag_ = lfs_rtag_setid(alt,
//// lfs_min(lfs_rtag_id(attr->tag), count));
// //lfs_rtag_t tag_ = lfs_rtag_setid(alt, lfs_rtag_id(tag));
// // TODO I don't really know why this works
//// if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE && gt == 0) {
//// tag_ = lfs_rtag_decid(tag_);
//// }
// lfs_rtag_t tag_ = lfs_rtag_setid(alt, lfs_rtag_id(upper-1));
//
// //gt == 0 ? lfs_rtag_id(attr->tag)-1 : lfs_rtag_id(attr->tag));
// printf("found %x (%x, %x)\n", tag_, lower, upper);
//
// // split leaf?
// // TODO we might be able to rearrange this a bit better
// if ((lfs_rtag_type1(tag) == LFS_TYPE1_CREATE
// || tag_ != tag)
// && !lfs_rtag_isrm(tag_)) {
// // inserting a new id?
// if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
// // note we bias the weights here so that lfs_rbyd_lookup
// // always finds the next biggest tag
// if (lfs_rtag_weight(tag_)
// < lfs_rtag_weight(tag & ~0x7fff)) {
// printf("bsplit lt create\n");
// alt = LFS_MKRALT__(B, LT,
// (lfs_rtag_weight_(tag_)+0x8) - lower);
// } else {
// printf("bsplit gt create\n");
// alt = LFS_MKRALT__(B, GT,
// (upper+0x8000) - (lfs_rtag_weight_(tag)+0x8));
//// // TODO hm, can this be done differently?
//// lfs_rtag_weight_(lfs_rtag_incid(tag_))
//// - lfs_rtag_weight_(tag));
// }
// } else {
// // note we bias the weights here so that lfs_rbyd_lookup
// // always finds the next biggest tag
// if (lfs_rtag_weight_(tag_) < lfs_rtag_weight_(tag)) {
// printf("bsplit lt\n");
// alt = LFS_MKRALT__(B, LT,
// (lfs_rtag_weight_(tag_)+0x8) - lower);
// } else {
// printf("bsplit gt\n");
// alt = LFS_MKRALT__(B, GT,
// upper - (lfs_rtag_weight_(tag)+0x8));
// }
// }
//
// int err = lfs_rbyd_p_push(lfs, rbyd_,
// p_alts, p_jumps,
// alt, branch);
// if (err) {
// return err;
// }
//
// lfs_rbyd_p_red(p_alts, p_jumps);
// }
//
// // flush any pending alts
// int err = lfs_rbyd_p_flush(lfs, rbyd_,
// p_alts, p_jumps, 3);
// if (err) {
// return err;
// }
//
// // done! lets get out of here
// goto leaf;
// }
// }
//
//leaf:;
// // write the tag
// int err = lfs_rbyd_progtag(lfs, rbyd_, tag, size, &rbyd_->crc);
// if (err) {
// return err;
// }
//
// // don't forget the actual data!
// err = lfs_rbyd_prog(lfs, rbyd_, buffer, size, &rbyd_->crc);
// if (err) {
// return err;
// }
//
// // if we're inserting, increase the id count, indirectly shifting
// // all ids >= over one
// //
// // note we do this here since it is possible to insert into an
// // empty tree
// if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
// rbyd_->count += 1;
// }
//
// return 0;
//}
//gt == 0 ? lfs_rtag_id(attr->tag)-1 : lfs_rtag_id(attr->tag)); static int lfs_rbyd_append(lfs_t *lfs, lfs_rbyd_t *rbyd_,
printf("found %x (%x, %x)\n", tag_, lower, upper);
// split leaf?
// TODO we might be able to rearrange this a bit better
if ((lfs_rtag_type1(tag) == LFS_TYPE1_CREATE
|| tag_ != tag)
&& !lfs_rtag_isrm(tag_)) {
// inserting a new id?
if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
// note we bias the weights here so that lfs_rbyd_lookup
// always finds the next biggest tag
if (lfs_rtag_weight(tag_)
< lfs_rtag_weight(tag & ~0x7fff)) {
printf("bsplit lt create\n");
alt = LFS_MKRALT__(B, LT,
(lfs_rtag_weight_(tag_)+0x8) - lower);
} else {
printf("bsplit gt create\n");
alt = LFS_MKRALT__(B, GT,
(upper+0x8000) - (lfs_rtag_weight_(tag)+0x8));
// // TODO hm, can this be done differently?
// lfs_rtag_weight_(lfs_rtag_incid(tag_))
// - lfs_rtag_weight_(tag));
}
} else {
// note we bias the weights here so that lfs_rbyd_lookup
// always finds the next biggest tag
if (lfs_rtag_weight_(tag_) < lfs_rtag_weight_(tag)) {
printf("bsplit lt\n");
alt = LFS_MKRALT__(B, LT,
(lfs_rtag_weight_(tag_)+0x8) - lower);
} else {
printf("bsplit gt\n");
alt = LFS_MKRALT__(B, GT,
upper - (lfs_rtag_weight_(tag)+0x8));
}
}
int err = lfs_rbyd_p_push(lfs, rbyd_,
p_alts, p_jumps,
alt, branch);
if (err) {
return err;
}
lfs_rbyd_p_red(p_alts, p_jumps);
}
// flush any pending alts
int err = lfs_rbyd_p_flush(lfs, rbyd_,
p_alts, p_jumps, 3);
if (err) {
return err;
}
// done! lets get out of here
goto leaf;
}
}
leaf:;
// write the tag
int err = lfs_rbyd_progtag(lfs, rbyd_, tag, size, &rbyd_->crc);
if (err) {
return err;
}
// don't forget the actual data!
err = lfs_rbyd_prog(lfs, rbyd_, buffer, size, &rbyd_->crc);
if (err) {
return err;
}
// if we're inserting, increase the id count, indirectly shifting
// all ids >= over one
//
// note we do this here since it is possible to insert into an
// empty tree
if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
rbyd_->count += 1;
}
return 0;
}
static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_,
lfs_rtag_t tag, const void *buffer, lfs_size_t size) { lfs_rtag_t tag, const void *buffer, lfs_size_t size) {
printf("- delete() -\n");
LFS_ASSERT(lfs_rtag_id(tag) <= rbyd_->count+1); LFS_ASSERT(lfs_rtag_id(tag) <= rbyd_->count+1);
// no trunk yet?
if (!rbyd_->trunk) {
goto leaf;
}
// assume we'll update our trunk // assume we'll update our trunk
lfs_off_t lower_branch = rbyd_->trunk; lfs_off_t lower_branch = rbyd_->trunk;
lfs_off_t upper_branch = rbyd_->trunk; lfs_off_t upper_branch = rbyd_->trunk;
rbyd_->trunk = rbyd_->off; rbyd_->trunk = rbyd_->off;
// no trunk yet?
if (!lower_branch) {
goto leaf;
}
// keep track of bounds as we descend down the tree // keep track of bounds as we descend down the tree
bool is_lower = true; bool is_lower = true;
bool is_cut = false; bool is_cut = false;
@@ -1831,9 +1830,15 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_,
if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) { if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) {
lower_tag__ = tag & ~0x7fff; lower_tag__ = tag & ~0x7fff;
upper_tag__ = lower_tag__ + 0x8000; upper_tag__ = lower_tag__ + 0x8000;
} else { } else if (lfs_rtag_isrm(tag)) {
lower_tag__ = tag & ~0x1; lower_tag__ = tag & ~0x1;
upper_tag__ = lower_tag__ + 0x8; upper_tag__ = lower_tag__ + 0x8;
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
lower_tag__ = tag & ~0x7fff;
upper_tag__ = lower_tag__;
} else {
lower_tag__ = tag;
upper_tag__ = lower_tag__;
} }
// // weights for pruning // // weights for pruning
@@ -2226,8 +2231,8 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_,
continue; continue;
} }
LFS_ASSERT(lower_tag_); //LFS_ASSERT(lower_tag_);
LFS_ASSERT(upper_tag_); //LFS_ASSERT(upper_tag_);
// // make sure to fill out the rest of the weight if we're // // make sure to fill out the rest of the weight if we're
// // deleting the last tag in the tree // // deleting the last tag in the tree
@@ -2282,7 +2287,7 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_,
// 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
} }
} else { } else if (lfs_rtag_isrm(tag)) {
if (lower_tag_ != tag // TODO need this check? if (lower_tag_ != tag // TODO need this check?
&& lfs_rtag_weight_(lower_tag_) && lfs_rtag_weight_(lower_tag_)
< lfs_rtag_weight_(tag & ~0x1)) { < lfs_rtag_weight_(tag & ~0x1)) {
@@ -2321,6 +2326,60 @@ static int lfs_rbyd_delete(lfs_t *lfs, lfs_rbyd_t *rbyd_,
// 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
} }
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
// inserting a new id?
LFS_ASSERT(!is_cut);
// TODO rm should probably be handled generally
if (!lfs_rtag_isrm(tag_)) {
// note we bias the weights here so that lfs_rbyd_lookup
// always finds the next biggest tag
if (lfs_rtag_weight(tag_)
< lfs_rtag_weight(tag & ~0x7fff)) {
printf("bsplit lt create\n");
alt = LFS_MKRALT__(B, LT,
(lfs_rtag_weight_(tag_)+0x8) - lower);
} else {
printf("bsplit gt create\n");
alt = LFS_MKRALT__(B, GT,
(upper+0x8000) - (lfs_rtag_weight_(tag)+0x8));
// // TODO hm, can this be done differently?
// lfs_rtag_weight_(lfs_rtag_incid(tag_))
// - lfs_rtag_weight_(tag));
}
int err = lfs_rbyd_p_push(lfs, rbyd_,
p_alts, p_jumps,
alt, branch);
if (err) {
return err;
}
lfs_rbyd_p_red(p_alts, p_jumps);
}
} else {
LFS_ASSERT(!is_cut);
if (tag_ != tag) {
// note we bias the weights here so that lfs_rbyd_lookup
// always finds the next biggest tag
if (lfs_rtag_weight_(tag_) < lfs_rtag_weight_(tag)) {
printf("bsplit lt\n");
alt = LFS_MKRALT__(B, LT,
(lfs_rtag_weight_(tag_)+0x8) - lower);
} else {
printf("bsplit gt\n");
alt = LFS_MKRALT__(B, GT,
upper - (lfs_rtag_weight_(tag)+0x8));
}
int err = lfs_rbyd_p_push(lfs, rbyd_,
p_alts, p_jumps,
alt, branch);
if (err) {
return err;
}
lfs_rbyd_p_red(p_alts, p_jumps);
}
} }
// flush any pending alts // flush any pending alts
@@ -2353,9 +2412,17 @@ leaf:;
// //
// TODO handle an empty tree // TODO handle an empty tree
if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) { if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) {
// TODO this assert should be earlier // TODO this assert should be earlier?
LFS_ASSERT(rbyd_->count > 0); LFS_ASSERT(rbyd_->count > 0);
rbyd_->count -= 1; rbyd_->count -= 1;
// if we're inserting, increase the id count, indirectly shifting
// all ids >= over one
//
// note we do this here since it is possible to insert into an
// empty tree
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
rbyd_->count += 1;
} }
return 0; return 0;
@@ -2385,20 +2452,21 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
// append each tag to the tree // append each tag to the tree
for (const struct lfs_rattr *attr = attrs; attr; attr = attr->next) { for (const struct lfs_rattr *attr = attrs; attr; attr = attr->next) {
if (lfs_rtag_isrm(attr->tag)) { // //if (lfs_rtag_isrm(attr->tag)) {
// deletes require range-deletion, this is a bit more complicated // if (lfs_rtag_type1(attr->tag) != LFS_TYPE1_CREATE) {
// than normal tags // // deletes require range-deletion, this is a bit more complicated
int err = lfs_rbyd_delete(lfs, &rbyd_, // // than normal tags
attr->tag, attr->buffer, attr->size); // int err = lfs_rbyd_delete(lfs, &rbyd_,
if (err) { // attr->tag, attr->buffer, attr->size);
return err; // if (err) {
} // return err;
} else { // }
int err = lfs_rbyd_append(lfs, &rbyd_, // } else {
attr->tag, attr->buffer, attr->size);
if (err) { int err = lfs_rbyd_append(lfs, &rbyd_,
return err; attr->tag, attr->buffer, attr->size);
} if (err) {
return err;
} }
} }