Got rbyd yellow splitting working

This commit is contained in:
Christopher Haster
2022-12-26 21:57:24 -06:00
parent b48f7fcfb0
commit b03420ccfc
2 changed files with 419 additions and 375 deletions
+83 -57
View File
@@ -394,6 +394,10 @@ static inline lfs_size_t lfs_tag_dsize(lfs_tag_t tag) {
return sizeof(tag) + lfs_tag_size(tag + lfs_tag_isdelete(tag)); return sizeof(tag) + lfs_tag_size(tag + lfs_tag_isdelete(tag));
} }
// 32-bit metadata tags
//
// in-device, these are effectively 31-bit unsigned integers
// on-disk, these are encoded as leb128, so smaller constants are prefered
typedef uint32_t lfs_rtag_t; typedef uint32_t lfs_rtag_t;
typedef int32_t lfs_srtag_t; typedef int32_t lfs_srtag_t;
@@ -416,15 +420,11 @@ enum lfs_rtag_type1 {
LFS_TYPE1_ALTRGT = 0x07, LFS_TYPE1_ALTRGT = 0x07,
}; };
enum lfs_rtag_color { #define LFS_ALT_B false
LFS_COLOR_B = 0, #define LFS_ALT_R true
LFS_COLOR_R = 1,
};
enum lfs_rtag_dir { #define LFS_ALT_LT false
LFS_DIR_LT = 0, #define LFS_ALT_GT true
LFS_DIR_GT = 1,
};
#define LFS_MKRTAG_(type1, type2, id) \ #define LFS_MKRTAG_(type1, type2, id) \
(((0x7f & (lfs_rtag_t)(type1)) << 0) \ (((0x7f & (lfs_rtag_t)(type1)) << 0) \
@@ -441,8 +441,9 @@ enum lfs_rtag_dir {
| ((0xfffffff & (lfs_rtag_t)(weight)) << 3)) | ((0xfffffff & (lfs_rtag_t)(weight)) << 3))
#define LFS_MKRALT(color, dir, weight) \ #define LFS_MKRALT(color, dir, weight) \
LFS_MKRALT_(LFS_COLOR_##color, LFS_DIR_##dir, weight) LFS_MKRALT_(LFS_ALT_##color, LFS_ALT_##dir, weight)
// tag operations
static inline bool lfs_rtag_isvalid(lfs_rtag_t tag) { static inline bool lfs_rtag_isvalid(lfs_rtag_t tag) {
return !(tag & 0x80000000); return !(tag & 0x80000000);
} }
@@ -471,6 +472,15 @@ static inline uint16_t lfs_rtag_id(lfs_rtag_t tag) {
return tag >> 15; return tag >> 15;
} }
static inline lfs_rtag_t lfs_rtag_setid(lfs_rtag_t tag, uint16_t id) {
return (tag & 0x7fff) | ((lfs_rtag_t)id << 15);
}
static inline lfs_rtag_t lfs_rtag_inc(lfs_rtag_t tag) {
return tag + 0x8;
}
// alt operations
static inline bool lfs_rtag_isblack(lfs_rtag_t tag) { static inline bool lfs_rtag_isblack(lfs_rtag_t tag) {
return !(tag & 0x1); return !(tag & 0x1);
} }
@@ -479,6 +489,14 @@ static inline bool lfs_rtag_isred(lfs_rtag_t tag) {
return tag & 0x1; return tag & 0x1;
} }
static inline lfs_rtag_t lfs_rtag_red(lfs_rtag_t tag) {
return tag | 0x1;
}
static inline lfs_rtag_t lfs_rtag_black(lfs_rtag_t tag) {
return tag & ~0x1;
}
static inline bool lfs_rtag_islt(lfs_rtag_t tag) { static inline bool lfs_rtag_islt(lfs_rtag_t tag) {
return !(tag & 0x2); return !(tag & 0x2);
} }
@@ -495,6 +513,10 @@ static inline lfs_srtag_t lfs_rtag_weight(lfs_rtag_t tag) {
return tag >> 3; return tag >> 3;
} }
static inline lfs_rtag_t lfs_rtag_merge(lfs_rtag_t a, lfs_rtag_t b) {
return a + (b & ~0x7);
}
//static inline lfs_srtag_t lfs_rtag_weight2(lfs_rtag_t tag, lfs_rtag_t tag2) { //static inline lfs_srtag_t lfs_rtag_weight2(lfs_rtag_t tag, lfs_rtag_t tag2) {
// return lfs_rtag_weight(tag) + lfs_rtag_weight(tag2); // return lfs_rtag_weight(tag) + lfs_rtag_weight(tag2);
//} //}
@@ -543,22 +565,6 @@ static inline void lfs_rtag_untrim(lfs_rtag_t alt,
} }
} }
static inline lfs_rtag_t lfs_rtag_inc(lfs_rtag_t tag) {
return tag + 0x8;
}
static inline lfs_rtag_t lfs_rtag_red(lfs_rtag_t tag) {
return tag | 0x1;
}
static inline lfs_rtag_t lfs_rtag_black(lfs_rtag_t tag) {
return tag & ~0x1;
}
static inline lfs_rtag_t lfs_rtag_setid(lfs_rtag_t tag, uint16_t id) {
return (tag & 0x7fff) | ((lfs_rtag_t)id << 15);
}
// operations on attribute lists // operations on attribute lists
struct lfs_mattr { struct lfs_mattr {
lfs_tag_t tag; lfs_tag_t tag;
@@ -1417,6 +1423,7 @@ 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) {
printf("append()\n");
// assume we'll update our trunk // assume we'll update our trunk
lfs_off_t branch = trunk; lfs_off_t branch = trunk;
trunk = off; trunk = off;
@@ -1453,6 +1460,19 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
jump = branch - jump; jump = branch - jump;
lfs_rtag_t branch_ = branch + delta; lfs_rtag_t branch_ = branch + delta;
// // prune?
// printf("prune? %x >= %x (%x+%x+1)\n", lfs_rtag_weight(alt), lt+gt+1, lt, gt);
// if (lfs_rtag_weight(alt) >= lt+gt+1) {
// printf("prune!\n");
// LFS_ASSERT(p_alts[0]);
//
// branch = jump;
// branch_ = 0; // TODO is this needed?
// alt = lfs_rtag_black(p_alts[0]);
// jump = p_jumps[0];
// lfs_rbyd_p_pop(p_alts, p_jumps);
// }
// // prune? // // prune?
// // TODO ugh, just clean this up later // // TODO ugh, just clean this up later
// if (p_alts[0] // if (p_alts[0]
@@ -1476,38 +1496,44 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
// lfs_rbyd_p_pop(p_alts, p_jumps); // lfs_rbyd_p_pop(p_alts, p_jumps);
// } // }
// //
// // two reds makes a yellow, split?
// // split? if (p_alts[0]
// if (lfs_rtag_isred(alt) && lfs_rtag_isred(p_alts[0])
// && p_alts[0] && lfs_rtag_isred(alt)) {
// && lfs_rtag_isred(p_alts[0])) { LFS_ASSERT(lfs_rtag_isparallel(alt, p_alts[0]));
// LFS_ASSERT(lfs_rtag_isparallel(alt, p_alts[0]));
// // if we take the red or yellow alt we can just point
// if (lfs_rtag_follow2(alt, p_alts[0], lt, gt)) { // to the black alt, otherwise we need to point to the
// lfs_rtag_t alt_ = p_alts[0]; // yellow alt and prune later
// lfs_off_t jump_ = p_jumps[0]; if (lfs_rtag_follow(alt, lt, gt)) {
// p_alts[0] = lfs_rtag_black( printf("ysplit follow\n");
// lfs_rtag_flip2(alt, alt_, lt, gt)); lfs_rtag_t alt_ = p_alts[0];
// p_jumps[0] = jump; lfs_off_t jump_ = p_jumps[0];
// alt = lfs_rtag_black(alt_); p_alts[0] = lfs_rtag_black(
// jump = jump_; lfs_rtag_flip(alt, lt, gt));
// p_jumps[0] = branch_;
// lfs_rtag_trim(alt_, &lt, &gt);
// lfs_rtag_trim(alt, &lt, &gt); alt = lfs_rtag_black(alt_);
// lfs_rbyd_p_red(p_alts, p_jumps); branch_ = jump;
// jump = jump_;
// } else {
// lfs_rtag_t alt_ = p_alts[0]; lfs_rtag_untrim(alt, &lt, &gt);
// p_alts[0] = lfs_rtag_black(alt); lfs_rtag_trim(p_alts[0], &lt, &gt);
// p_jumps[0] = xylem; lfs_rbyd_p_red(p_alts, p_jumps);
//
// lfs_rtag_trim(alt_, &lt, &gt); } else {
// lfs_rtag_trim(alt, &lt, &gt); printf("ysplit nofollow\n");
// lfs_rbyd_p_red(p_alts, p_jumps); p_alts[0] = lfs_rtag_black(
// lfs_rtag_merge(alt, p_alts[0]));
// continue; p_jumps[0] = xylem;
// }
// } lfs_rtag_trim(alt, &lt, &gt);
lfs_rbyd_p_red(p_alts, p_jumps);
//xylem = branch;
branch = branch_;
continue;
}
}
// should've taken red alt? needs a flip // should've taken red alt? needs a flip
printf("lt,gt = (%x,%x)\n", lt, gt); printf("lt,gt = (%x,%x)\n", lt, gt);
+336 -318
View File
@@ -19,9 +19,10 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
// try an empty commit // try an empty commit
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0; lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
@@ -57,9 +58,10 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
// try an empty commit // try an empty commit
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0; lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
@@ -100,15 +102,16 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// try an empty commit // try an empty commit
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0; lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
// TODO test in-between lookups for consistently finding the next >= tag? // TODO test in-between lookups for consistently finding the next >= tag?
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
=> LFS_ERR_NOENT; => LFS_ERR_NOENT;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
@@ -183,14 +186,15 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// try an empty commit // try an empty commit
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0; lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
=> LFS_ERR_NOENT; => LFS_ERR_NOENT;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
@@ -267,22 +271,23 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
lfs_srtag_t tag;
// traverse requires correct biasing of the weights in the rbyd tree // traverse requires correct biasing of the weights in the rbyd tree
// so that lookups return strictly the tag greater than or equal to // so that lookups return strictly the tag greater than or equal to
// the tag requested // the tag requested
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0; LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0;
lfs_off_t off; tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
lfs_size_t size;
lfs_srtag_t tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
assert(tag == LFS_MKRTAG(GSTATE, 1, 0)); assert(tag == LFS_MKRTAG(GSTATE, 1, 0));
// TODO use lfs_tag_incid?
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size); tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_MKRTAG(GSTATE, 2, 0)); assert(tag == LFS_MKRTAG(GSTATE, 2, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size); tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
@@ -312,11 +317,15 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
lfs_srtag_t tag;
// traverse requires correct biasing of the weights in the rbyd tree // traverse requires correct biasing of the weights in the rbyd tree
// so that lookups return strictly the tag greater than or equal to // so that lookups return strictly the tag greater than or equal to
// the tag requested // the tag requested
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
@@ -324,9 +333,7 @@ code = '''
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0; LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
lfs_off_t off; tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
lfs_size_t size;
lfs_srtag_t tag = lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size);
assert(tag == LFS_MKRTAG(GSTATE, 1, 0)); assert(tag == LFS_MKRTAG(GSTATE, 1, 0));
tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size); tag = lfs_rbyd_lookup(&lfs, &rbyd, lfs_rtag_inc(tag), &off, &size);
assert(tag == LFS_MKRTAG(GSTATE, 2, 0)); assert(tag == LFS_MKRTAG(GSTATE, 2, 0));
@@ -357,20 +364,21 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// create a split in the leaves // create a split in the leaves
// <b // <b
// => .-'| // => .-'|
// 1 1 2 // 1 1 2
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0; LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
=> LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
@@ -408,12 +416,15 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a black edge // ignore a black edge
// <b <b // <b <b
// .-'| => .----'| // .-'| => .----'|
// 1 2 1 2 2 // 1 2 1 2 2
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
@@ -421,8 +432,6 @@ code = '''
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4, NULL)))) => 0; LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4, NULL)))) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
=> LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
@@ -461,6 +470,9 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a black edge // ignore a black edge
// <r // <r
@@ -468,7 +480,7 @@ code = '''
// <b => | <b // <b => | <b
// .-'| | .-'| // .-'| | .-'|
// 1 2 1 2 3 // 1 2 1 2 3
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
@@ -476,8 +488,6 @@ code = '''
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL)))) => 0; LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL)))) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
=> LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
@@ -523,6 +533,9 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a red edge and black edge // ignore a red edge and black edge
// <r <r // <r <r
@@ -530,7 +543,7 @@ code = '''
// | <b => | <b // | <b => | <b
// | .-'| | .----'| // | .-'| | .----'|
// 1 2 3 1 2 3 3 // 1 2 3 1 2 3 3
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
@@ -539,8 +552,6 @@ code = '''
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
=> LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
@@ -630,6 +641,9 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// ignore a red edge and black edge // ignore a red edge and black edge
// <y // <y
@@ -639,7 +653,7 @@ code = '''
// | <b | | <b // | <b | | <b
// | .-'| | | .-'| // | .-'| | | .-'|
// 1 2 3 1 2 3 4 // 1 2 3 1 2 3 4
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
@@ -648,8 +662,6 @@ code = '''
LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
=> LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
@@ -753,6 +765,9 @@ code = '''
.count = 0, .count = 0,
.erased = true, .erased = true,
}; };
lfs_rbyd_t rbyd;
lfs_off_t off;
lfs_size_t size;
// all three the same // all three the same
// <y // <y
@@ -762,7 +777,7 @@ code = '''
// | <b | | <b // | <b | | <b
// | .-'| | | .-'| // | .-'| | | .-'|
// 1 2 3 1 2 3 4 // 1 2 3 1 2 3 4
lfs_rbyd_t rbyd = rbyd_init; rbyd = rbyd_init;
lfs_bd_erase(&lfs, rbyd.block) => 0; lfs_bd_erase(&lfs, rbyd.block) => 0;
lfs_rbyd_commit(&lfs, &rbyd, lfs_rbyd_commit(&lfs, &rbyd,
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
@@ -771,8 +786,6 @@ code = '''
LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, NULL))))) => 0;
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
lfs_off_t off;
lfs_size_t size;
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
=> LFS_MKRTAG(GSTATE, 1, 0); => LFS_MKRTAG(GSTATE, 1, 0);
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
@@ -861,283 +874,286 @@ code = '''
=> LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 4, 0);
''' '''
#[cases.test_rbyd_ysplits] [cases.test_rbyd_ysplits]
#in = 'lfs.c' in = 'lfs.c'
#code = ''' code = '''
# lfs_t lfs; lfs_t lfs;
# lfs_init(&lfs, cfg) => 0; lfs_init(&lfs, cfg) => 0;
#
# lfs_rbyd_t rbyd_init = { lfs_rbyd_t rbyd_init = {
# .block = 0, .block = 0,
# .trunk = 0, .trunk = 0,
# .noff = 0, .noff = 0,
# .rev = 1, .rev = 1,
# .crc = 0, .crc = 0,
# .count = 0, .count = 0,
# .erased = true, .erased = true,
# }; };
# lfs_rbyd_t rbyd;
# // split a yellow triple, not taking any alt lfs_off_t off;
# // <b lfs_size_t size;
# // .-'|
# // <y <y | // split a yellow triple, not taking any alt
# // .-------'| .-------'| | // <b
# // | <r => | <r | // .-'|
# // | .----'| | .----' | // <y <y |
# // | | <b | | <b // .-------'| .-------'| |
# // | | .-'| | | .----'| // | <r => | <r |
# // 1 2 3 4 1 2 3 4 4 // | .----'| | .----' |
# lfs_rbyd_t rbyd = rbyd_init; // | | <b | | <b
# lfs_bd_erase(&lfs, rbyd.block) => 0; // | | .-'| | | .----'|
# lfs_rbyd_commit(&lfs, &rbyd, // 1 2 3 4 1 2 3 4 4
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, rbyd = rbyd_init;
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# lfs_off_t off; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_size_t size;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) => LFS_MKRTAG(GSTATE, 1, 0);
# => LFS_MKRTAG(GSTATE, 2, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) => LFS_MKRTAG(GSTATE, 2, 0);
# => LFS_MKRTAG(GSTATE, 3, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) => LFS_MKRTAG(GSTATE, 3, 0);
# => LFS_MKRTAG(GSTATE, 4, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0);
# // split a yellow triple, taking the black alt
# // <b // split a yellow triple, taking the black alt
# // .-'| // <b
# // <y <y | // .-'|
# // .-------'| .-------'| | // <y <y |
# // | <r => | <r | // .-------'| .-------'| |
# // | .----'| | .----' | // | <r => | <r |
# // | | <b | | >b // | .----'| | .----' |
# // | | .-'| | | .-'| // | | <b | | >b
# // 1 2 3 4 1 2 3 4 3 // | | .-'| | | .-'|
# rbyd = rbyd_init; // 1 2 3 4 1 2 3 4 3
# lfs_bd_erase(&lfs, rbyd.block) => 0; rbyd = rbyd_init;
# lfs_rbyd_commit(&lfs, &rbyd, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) => LFS_MKRTAG(GSTATE, 1, 0);
# => LFS_MKRTAG(GSTATE, 2, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) => LFS_MKRTAG(GSTATE, 2, 0);
# => LFS_MKRTAG(GSTATE, 3, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) => LFS_MKRTAG(GSTATE, 3, 0);
# => LFS_MKRTAG(GSTATE, 4, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0);
# // split a yellow triple, taking the red alt
# // <y >b // split a yellow triple, taking the red alt
# // .-------'| .-'| // <y >b
# // | <r | <b // .-------'| .-'|
# // | .----'| => .--------|-'| // | <r | <b
# // | | <b | <b | // | .----'| => .--------|-'|
# // | | .-'| | .-'| | // | | <b | <b |
# // 1 2 3 4 1 2 3 4 2 // | | .-'| | .-'| |
# rbyd = rbyd_init; // 1 2 3 4 1 2 3 4 2
# lfs_bd_erase(&lfs, rbyd.block) => 0; rbyd = rbyd_init;
# lfs_rbyd_commit(&lfs, &rbyd, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) => LFS_MKRTAG(GSTATE, 1, 0);
# => LFS_MKRTAG(GSTATE, 2, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) => LFS_MKRTAG(GSTATE, 2, 0);
# => LFS_MKRTAG(GSTATE, 3, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) => LFS_MKRTAG(GSTATE, 3, 0);
# => LFS_MKRTAG(GSTATE, 4, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0);
# // split a yellow triple, taking the yellow alt
# // <y >b // split a yellow triple, taking the yellow alt
# // .-------'| .-'| // <y >b
# // | <r | >b // .-------'| .-'|
# // | .----'| => .-----|-'| // | <r | >b
# // | | <b | <b | // | .----'| => .-----|-'|
# // | | .-'| | .-'| | // | | <b | <b |
# // 1 2 3 4 1 2 3 4 1 // | | .-'| | .-'| |
# rbyd = rbyd_init; // 1 2 3 4 1 2 3 4 1
# lfs_bd_erase(&lfs, rbyd.block) => 0; rbyd = rbyd_init;
# lfs_rbyd_commit(&lfs, &rbyd, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) => LFS_MKRTAG(GSTATE, 1, 0);
# => LFS_MKRTAG(GSTATE, 2, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) => LFS_MKRTAG(GSTATE, 2, 0);
# => LFS_MKRTAG(GSTATE, 3, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) => LFS_MKRTAG(GSTATE, 3, 0);
# => LFS_MKRTAG(GSTATE, 4, 0); lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
#''' => LFS_MKRTAG(GSTATE, 4, 0);
# '''
#[cases.test_rbyd_quintifoliate]
#in = 'lfs.c' [cases.test_rbyd_quintifoliate]
#code = ''' in = 'lfs.c'
# lfs_t lfs; code = '''
# lfs_init(&lfs, cfg) => 0; lfs_t lfs;
# lfs_init(&lfs, cfg) => 0;
# lfs_rbyd_t rbyd_init = {
# .block = 0, lfs_rbyd_t rbyd_init = {
# .trunk = 0, .block = 0,
# .noff = 0, .trunk = 0,
# .rev = 1, .noff = 0,
# .crc = 0, .rev = 1,
# .count = 0, .crc = 0,
# .erased = true, .count = 0,
# }; .erased = true,
# };
# // split a yellow triple, not taking any alt lfs_rbyd_t rbyd;
# // <b lfs_off_t off;
# // .-'| lfs_size_t size;
# // <y |
# // .-------'| | // split a yellow triple, not taking any alt
# // <y | <r | // <b
# // .-------'| => | .----' | // .-'|
# // | <r | | <r // <y |
# // | .----'| | | .----'| // .-------'| |
# // | | <b | | | <b // <y | <r |
# // | | .-'| | | | .-'| // .-------'| => | .----' |
# // 1 2 3 4 1 2 3 4 5 // | <r | | <r
# lfs_rbyd_t rbyd = rbyd_init; // | .----'| | | .----'|
# lfs_bd_erase(&lfs, rbyd.block) => 0; // | | <b | | | <b
# lfs_rbyd_commit(&lfs, &rbyd, // | | .-'| | | | .-'|
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, // 1 2 3 4 1 2 3 4 5
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, rbyd = rbyd_init;
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
# lfs_off_t off; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xdddddddd}, 4,
# lfs_size_t size; LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 2, 0); => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 3, 0); => LFS_MKRTAG(GSTATE, 2, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 3, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 4, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size)
# // split a yellow triple, taking the black alt => LFS_MKRTAG(GSTATE, 5, 0);
# // <b
# // .-'| // split a yellow triple, taking the black alt
# // <y | // <b
# // .-------'| | // .-'|
# // <y | <r | // <y |
# // .-------'| => | .----' | // .-------'| |
# // | <r | | >r // <y | <r |
# // | .----'| | | .-'| // .-------'| => | .----' |
# // | | <b | | | >b // | <r | | >r
# // | | .-'| | | .--|-'| // | .----'| | | .-'|
# // 1 2 4 5 1 2 4 5 3 // | | <b | | | >b
# rbyd = rbyd_init; // | | .-'| | | .--|-'|
# lfs_bd_erase(&lfs, rbyd.block) => 0; // 1 2 4 5 1 2 4 5 3
# lfs_rbyd_commit(&lfs, &rbyd, rbyd = rbyd_init;
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4,
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 2, 0); => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 3, 0); => LFS_MKRTAG(GSTATE, 2, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 3, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 4, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size)
# // split a yellow triple, taking the red alt => LFS_MKRTAG(GSTATE, 5, 0);
# // >b
# // .-'| // split a yellow triple, taking the red alt
# // <y | <r // >b
# // .-------'| .--------|-'| // .-'|
# // | <r | | >b // <y | <r
# // | .----'| => | .-----|-'| // .-------'| .--------|-'|
# // | | <b | | <b | // | <r | | >b
# // | | .-'| | | .-'| | // | .----'| => | .-----|-'|
# // 1 3 4 5 1 3 4 5 2 // | | <b | | <b |
# rbyd = rbyd_init; // | | .-'| | | .-'| |
# lfs_bd_erase(&lfs, rbyd.block) => 0; // 1 3 4 5 1 3 4 5 2
# lfs_rbyd_commit(&lfs, &rbyd, rbyd = rbyd_init;
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4,
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 2, 0); => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 3, 0); => LFS_MKRTAG(GSTATE, 2, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 3, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 4, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size)
# // split a yellow triple, taking the yellow alt => LFS_MKRTAG(GSTATE, 5, 0);
# // >b
# // .-'| // split a yellow triple, taking the yellow alt
# // <y | >r // >b
# // .-------'| .-----|-'| // .-'|
# // | <r | | >b // <y | >r
# // | .----'| => .--|-----|-'| // .-------'| .-----|-'|
# // | | <b | | <b | // | <r | | >b
# // | | .-'| | | .-'| | // | .----'| => .--|-----|-'|
# // 2 3 4 5 2 3 4 5 1 // | | <b | | <b |
# rbyd = rbyd_init; // | | .-'| | | .-'| |
# lfs_bd_erase(&lfs, rbyd.block) => 0; // 2 3 4 5 2 3 4 5 1
# lfs_rbyd_commit(&lfs, &rbyd, rbyd = rbyd_init;
# LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4, lfs_bd_erase(&lfs, rbyd.block) => 0;
# LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4, lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4, LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4, LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0; LFS_MKRATTR(GSTATE, 4, 0, &(uint32_t){0xcccccccc}, 4,
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xdddddddd}, 4,
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xeeeeeeee}, 4, NULL)))))) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 2, 0); => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 3, 0); => LFS_MKRTAG(GSTATE, 2, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 4, 0); => LFS_MKRTAG(GSTATE, 3, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size) lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 4, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 5, 0); => LFS_MKRTAG(GSTATE, 4, 0);
#''' lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 5, 0), &off, &size)
=> LFS_MKRTAG(GSTATE, 5, 0);
'''
#[cases.test_rbyd_prunes] #[cases.test_rbyd_prunes]
#in = 'lfs.c' #in = 'lfs.c'
#code = ''' #code = '''
@@ -1153,6 +1169,9 @@ code = '''
# .count = 0, # .count = 0,
# .erased = true, # .erased = true,
# }; # };
# lfs_rbyd_t rbyd;
# lfs_off_t off;
# lfs_size_t size;
# #
# // don't prune # // don't prune
# // <b <b # // <b <b
@@ -1166,7 +1185,7 @@ code = '''
# // | | | <b | | | <b # // | | | <b | | | <b
# // | | | .-'| | | | .----'| # // | | | .-'| | | | .----'|
# // 1 2 3 4 5 1 2 3 4 5 5 # // 1 2 3 4 5 1 2 3 4 5 5
# lfs_rbyd_t rbyd = rbyd_init; # rbyd = rbyd_init;
# lfs_bd_erase(&lfs, rbyd.block) => 0; # lfs_bd_erase(&lfs, rbyd.block) => 0;
# lfs_rbyd_commit(&lfs, &rbyd, # lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, # LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
@@ -1177,8 +1196,6 @@ code = '''
# LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0; # LFS_MKRATTR(GSTATE, 5, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0;
# #
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; # lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_off_t off;
# lfs_size_t size;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) # lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); # => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) # lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
@@ -1274,6 +1291,9 @@ code = '''
# .count = 0, # .count = 0,
# .erased = true, # .erased = true,
# }; # };
# lfs_rbyd_t rbyd;
# lfs_off_t off;
# lfs_size_t size;
# #
# // don't prune # // don't prune
# // <b # // <b
@@ -1289,7 +1309,7 @@ code = '''
# // | | | <b | | | | <b # // | | | <b | | | | <b
# // | | | .-'| | | | | .-'| # // | | | .-'| | | | | .-'|
# // 1 2 3 4 5 1 2 3 4 5 6 # // 1 2 3 4 5 1 2 3 4 5 6
# lfs_rbyd_t rbyd = rbyd_init; # rbyd = rbyd_init;
# lfs_bd_erase(&lfs, rbyd.block) => 0; # lfs_bd_erase(&lfs, rbyd.block) => 0;
# lfs_rbyd_commit(&lfs, &rbyd, # lfs_rbyd_commit(&lfs, &rbyd,
# LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, # LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
@@ -1300,8 +1320,6 @@ code = '''
# LFS_MKRATTR(GSTATE, 6, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0; # LFS_MKRATTR(GSTATE, 6, 0, &(uint32_t){0xffffffff}, 4, NULL))))))) => 0;
# #
# lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0; # lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
# lfs_off_t off;
# lfs_size_t size;
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size) # lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
# => LFS_MKRTAG(GSTATE, 1, 0); # => LFS_MKRTAG(GSTATE, 1, 0);
# lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size) # lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)