Rbyd rflips are now working, quite nicely actually
It turns out statefulness works quite well with this algorithm (The prototype was in Haskell, which created some artificial problems. I think it may have just been too high-level a language for this near-instruction-level algorithm).
This commit is contained in:
@@ -468,7 +468,7 @@ static inline uint16_t lfs_rtag_type3(lfs_rtag_t tag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline uint16_t lfs_rtag_id(lfs_rtag_t tag) {
|
static inline uint16_t lfs_rtag_id(lfs_rtag_t tag) {
|
||||||
return (tag >> 15) & 0xffff;
|
return tag >> 15;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool lfs_rtag_islt(lfs_rtag_t tag) {
|
static inline bool lfs_rtag_islt(lfs_rtag_t tag) {
|
||||||
@@ -487,11 +487,11 @@ static inline bool lfs_rtag_isred(lfs_rtag_t tag) {
|
|||||||
return tag & 0x1;
|
return tag & 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_rtag_t lfs_rtag_weight(lfs_rtag_t tag) {
|
static inline lfs_srtag_t lfs_rtag_weight(lfs_rtag_t tag) {
|
||||||
return (tag >> 3) & 0xfffffff;
|
return tag >> 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_rtag_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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -952,7 +952,6 @@ static int lfs_rbyd_fetch(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// found trunk of tree?
|
// found trunk of tree?
|
||||||
printf("%x: %08x => %d %d\n", off, tag, wastrunk, lfs_rtag_intree(tag));
|
|
||||||
if (!wastrunk && (lfs_rtag_isalt(tag) || lfs_rtag_intree(tag))) {
|
if (!wastrunk && (lfs_rtag_isalt(tag) || lfs_rtag_intree(tag))) {
|
||||||
trunk = off;
|
trunk = off;
|
||||||
wastrunk = true;
|
wastrunk = true;
|
||||||
@@ -1071,7 +1070,7 @@ static int lfs_rbyd_fetch(lfs_t *lfs,
|
|||||||
|
|
||||||
// TODO make these rtag functions?
|
// TODO make these rtag functions?
|
||||||
static inline bool lfs_rbyd_follow(lfs_rtag_t alt,
|
static inline bool lfs_rbyd_follow(lfs_rtag_t alt,
|
||||||
lfs_rtag_t lt, lfs_rtag_t gt) {
|
lfs_srtag_t lt, lfs_srtag_t gt) {
|
||||||
if (lfs_rtag_islt(alt)) {
|
if (lfs_rtag_islt(alt)) {
|
||||||
return lfs_rtag_weight(alt) > lt;
|
return lfs_rtag_weight(alt) > lt;
|
||||||
} else {
|
} else {
|
||||||
@@ -1080,7 +1079,7 @@ static inline bool lfs_rbyd_follow(lfs_rtag_t alt,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline bool lfs_rbyd_follow2(
|
static inline bool lfs_rbyd_follow2(
|
||||||
lfs_rtag_t alt, lfs_rtag_t alt_, lfs_rtag_t lt, lfs_rtag_t gt) {
|
lfs_rtag_t alt, lfs_rtag_t alt_, lfs_srtag_t lt, lfs_srtag_t gt) {
|
||||||
if (lfs_rtag_islt(alt) && lfs_rtag_islt(alt_)) {
|
if (lfs_rtag_islt(alt) && lfs_rtag_islt(alt_)) {
|
||||||
return lfs_rtag_weight(alt) + lfs_rtag_weight(alt_) > lt;
|
return lfs_rtag_weight(alt) + lfs_rtag_weight(alt_) > lt;
|
||||||
} else if (lfs_rtag_isgt(alt) && lfs_rtag_isgt(alt_)) {
|
} else if (lfs_rtag_isgt(alt) && lfs_rtag_isgt(alt_)) {
|
||||||
@@ -1110,35 +1109,53 @@ static inline lfs_rtag_t lfs_rbyd_flip2(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void lfs_rbyd_trim(lfs_rtag_t alt,
|
static inline void lfs_rbyd_trim(lfs_rtag_t alt,
|
||||||
lfs_rtag_t *lt, lfs_rtag_t *gt) {
|
lfs_srtag_t *lt, lfs_srtag_t *gt) {
|
||||||
lfs_rtag_t lt_ = *lt;
|
|
||||||
lfs_rtag_t gt_ = *gt;
|
|
||||||
|
|
||||||
if (lfs_rtag_islt(alt)) {
|
if (lfs_rtag_islt(alt)) {
|
||||||
if (lfs_rbyd_follow(alt, lt_, gt_)) {
|
*lt = *lt - lfs_rtag_weight(alt);
|
||||||
*gt = lfs_rtag_weight(alt)-1 - *lt;
|
|
||||||
} else {
|
|
||||||
*lt = *lt - lfs_rtag_weight(alt);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (lfs_rbyd_follow(alt, lt_, gt_)) {
|
*gt = *gt - lfs_rtag_weight(alt);
|
||||||
*lt = lfs_rtag_weight(alt)-1 - *gt;
|
|
||||||
} else {
|
|
||||||
*gt = *gt - lfs_rtag_weight(alt);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void lfs_rbyd_untrim(lfs_rtag_t alt,
|
||||||
|
lfs_srtag_t *lt, lfs_srtag_t *gt) {
|
||||||
|
if (lfs_rtag_islt(alt)) {
|
||||||
|
*lt = *lt + lfs_rtag_weight(alt);
|
||||||
|
} else {
|
||||||
|
*gt = *gt + lfs_rtag_weight(alt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//static inline void lfs_rbyd_trim(lfs_rtag_t alt,
|
||||||
|
// lfs_rtag_t *lt, lfs_rtag_t *gt) {
|
||||||
|
// lfs_rtag_t lt_ = *lt;
|
||||||
|
// lfs_rtag_t gt_ = *gt;
|
||||||
|
//
|
||||||
|
// if (lfs_rtag_islt(alt)) {
|
||||||
|
// if (lfs_rbyd_follow(alt, lt_, gt_)) {
|
||||||
|
// *gt = lfs_rtag_weight(alt)-1 - *lt;
|
||||||
|
// } else {
|
||||||
|
// *lt = *lt - lfs_rtag_weight(alt);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// if (lfs_rbyd_follow(alt, lt_, gt_)) {
|
||||||
|
// *lt = lfs_rtag_weight(alt)-1 - *gt;
|
||||||
|
// } else {
|
||||||
|
// *gt = *gt - lfs_rtag_weight(alt);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
// TODO lfs_rtag_weight_lt?
|
// TODO lfs_rtag_weight_lt?
|
||||||
static inline lfs_rtag_t lfs_rbyd_partition_lt(
|
static inline lfs_srtag_t lfs_rbyd_partition_lt(
|
||||||
lfs_rtag_t tag, uint16_t count) {
|
lfs_rtag_t tag, uint16_t count) {
|
||||||
(void)count;
|
(void)count;
|
||||||
return lfs_rtag_weight(tag);
|
return lfs_rtag_weight(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_rtag_t lfs_rbyd_partition_gt(
|
static inline lfs_srtag_t lfs_rbyd_partition_gt(
|
||||||
lfs_rtag_t tag, uint16_t count) {
|
lfs_rtag_t tag, uint16_t count) {
|
||||||
return (((lfs_rtag_t)count << 12) + 0xff8)-1 - lfs_rtag_weight(tag);
|
return (((lfs_srtag_t)count << 12) + 0xff8)-1 - lfs_rtag_weight(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
//static inline void lfs_rbyd_trim(lfs_rtag_t alt,
|
//static inline void lfs_rbyd_trim(lfs_rtag_t alt,
|
||||||
@@ -1160,7 +1177,7 @@ static inline lfs_rtag_t lfs_rbyd_partition_gt(
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
||||||
lfs_rtag_t tag, lfs_off_t *off, lfs_size_t *size, lfs_rtag_t *ntag) {
|
lfs_rtag_t tag, lfs_off_t *off, lfs_size_t *size) {
|
||||||
// no trunk yet?
|
// no trunk yet?
|
||||||
lfs_off_t branch = rbyd->trunk;
|
lfs_off_t branch = rbyd->trunk;
|
||||||
if (!branch) {
|
if (!branch) {
|
||||||
@@ -1168,11 +1185,11 @@ static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// weights for pruning
|
// weights for pruning
|
||||||
lfs_rtag_t lt = lfs_rbyd_partition_lt(tag, rbyd->count);
|
lfs_srtag_t lt = lfs_rbyd_partition_lt(tag, rbyd->count);
|
||||||
lfs_rtag_t gt = lfs_rbyd_partition_gt(tag, rbyd->count);
|
lfs_srtag_t gt = lfs_rbyd_partition_gt(tag, rbyd->count);
|
||||||
printf("lt, gt = (%x, %x)\n", lt, gt);
|
printf("lt, gt = (%x, %x)\n", lt, gt);
|
||||||
|
|
||||||
// descend down tree, building alt pointers
|
// descend down tree
|
||||||
while (true) {
|
while (true) {
|
||||||
lfs_rtag_t alt;
|
lfs_rtag_t alt;
|
||||||
lfs_off_t jump;
|
lfs_off_t jump;
|
||||||
@@ -1189,9 +1206,9 @@ static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
|||||||
jump = branch - jump;
|
jump = branch - jump;
|
||||||
branch += delta;
|
branch += delta;
|
||||||
|
|
||||||
printf("follow %x (%x, %x)? => %d\n", alt, lt, gt, lfs_rbyd_follow(alt, lt, gt));
|
printf("follow %c%x (%x, %x)? => %d\n", lfs_rtag_isgt(alt) ? '>' : '<', lfs_rtag_weight(alt), lt, gt, lfs_rbyd_follow(alt, lt, gt));
|
||||||
if (lfs_rbyd_follow(alt, lt, gt)) {
|
if (lfs_rbyd_follow(alt, lt, gt)) {
|
||||||
lfs_rbyd_trim(alt, <, >);
|
lfs_rbyd_trim(lfs_rbyd_flip(alt, lt, gt), <, >);
|
||||||
branch = jump;
|
branch = jump;
|
||||||
} else {
|
} else {
|
||||||
lfs_rbyd_trim(alt, <, >);
|
lfs_rbyd_trim(alt, <, >);
|
||||||
@@ -1208,7 +1225,7 @@ static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
|||||||
lfs_rtag_t tag_ = LFS_MKRTAG_(
|
lfs_rtag_t tag_ = LFS_MKRTAG_(
|
||||||
lfs_rtag_type1(alt),
|
lfs_rtag_type1(alt),
|
||||||
lfs_rtag_type2(alt),
|
lfs_rtag_type2(alt),
|
||||||
lt >> 12); // TODO there's no way this can be right
|
lfs_rtag_id(tag));
|
||||||
|
|
||||||
// not what we're looking for?
|
// not what we're looking for?
|
||||||
if (tag_ < tag) {
|
if (tag_ < tag) {
|
||||||
@@ -1218,17 +1235,9 @@ static lfs_srtag_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
|||||||
// save what we found
|
// save what we found
|
||||||
*off = branch + delta;
|
*off = branch + delta;
|
||||||
*size = jump;
|
*size = jump;
|
||||||
if (ntag) {
|
|
||||||
if (gt == lfs_rbyd_partition_gt(tag, rbyd->count)) {
|
|
||||||
*ntag = LFS_ERR_NOENT;
|
|
||||||
} else {
|
|
||||||
*ntag = tag + ((gt+1) << 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("lt, gt = (%x, %x)\n", lt, gt);
|
printf("lt, gt = (%x, %x)\n", lt, gt);
|
||||||
printf("lookup %08x => %08x (raw %08x)\n", tag, tag_, alt);
|
printf("lookup %08x => %08x (raw %08x)\n", tag, tag_, alt);
|
||||||
if (ntag) { printf("ntag %08x => %08x\n", tag, *ntag); }
|
|
||||||
//return alt; // TODO adjust
|
//return alt; // TODO adjust
|
||||||
//return lt << 3;
|
//return lt << 3;
|
||||||
//return lfs_rtag_setid(alt, lt >> 12);
|
//return lfs_rtag_setid(alt, lt >> 12);
|
||||||
@@ -1304,13 +1313,13 @@ static lfs_ssize_t lfs_rbyd_p_push(lfs_t *lfs,
|
|||||||
lfs_rtag_t p_alts[static 3],
|
lfs_rtag_t p_alts[static 3],
|
||||||
lfs_off_t p_jumps[static 3],
|
lfs_off_t p_jumps[static 3],
|
||||||
lfs_rtag_t alt, lfs_off_t jump, uint32_t *crc) {
|
lfs_rtag_t alt, lfs_off_t jump, uint32_t *crc) {
|
||||||
lfs_ssize_t delta = 0;
|
|
||||||
|
|
||||||
// too many alts, need to write one out?
|
// too many alts, need to write one out?
|
||||||
|
lfs_ssize_t delta = 0;
|
||||||
if (p_alts[2]) {
|
if (p_alts[2]) {
|
||||||
// change to relative jump at the last minute
|
// change to relative jump at the last minute
|
||||||
lfs_rtag_t alt_ = p_alts[2];
|
lfs_rtag_t alt_ = p_alts[2];
|
||||||
lfs_off_t jump_ = off - p_jumps[2];
|
lfs_off_t jump_ = off - p_jumps[2];
|
||||||
|
printf("%x: writing %08x %08x\n", off, alt_, jump_);
|
||||||
|
|
||||||
delta = lfs_rbyd_progtag(lfs,
|
delta = lfs_rbyd_progtag(lfs,
|
||||||
pcache, rcache,
|
pcache, rcache,
|
||||||
@@ -1348,12 +1357,12 @@ static lfs_ssize_t lfs_rbyd_p_flush(lfs_t *lfs,
|
|||||||
lfs_block_t block, lfs_off_t off,
|
lfs_block_t block, lfs_off_t off,
|
||||||
lfs_rtag_t p_alts[static 3],
|
lfs_rtag_t p_alts[static 3],
|
||||||
lfs_rtag_t p_jumps[static 3], uint32_t *crc) {
|
lfs_rtag_t p_jumps[static 3], uint32_t *crc) {
|
||||||
|
// just push zeros into everything is written out
|
||||||
lfs_ssize_t delta = 0;
|
lfs_ssize_t delta = 0;
|
||||||
|
|
||||||
for (unsigned i = 0; i < 3; i++) {
|
for (unsigned i = 0; i < 3; i++) {
|
||||||
lfs_ssize_t delta_ = lfs_rbyd_p_push(lfs,
|
lfs_ssize_t delta_ = lfs_rbyd_p_push(lfs,
|
||||||
pcache, rcache,
|
pcache, rcache,
|
||||||
block, off,
|
block, off+delta,
|
||||||
p_alts, p_jumps, 0, 0, crc);
|
p_alts, p_jumps, 0, 0, crc);
|
||||||
if (delta_ < 0) {
|
if (delta_ < 0) {
|
||||||
return delta_;
|
return delta_;
|
||||||
@@ -1442,14 +1451,14 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// weights for pruning
|
// weights for pruning
|
||||||
lfs_rtag_t lt = lfs_rbyd_partition_lt(attr->tag, count);
|
lfs_srtag_t lt = lfs_rbyd_partition_lt(attr->tag, count);
|
||||||
lfs_rtag_t gt = lfs_rbyd_partition_gt(attr->tag, count);
|
lfs_srtag_t gt = lfs_rbyd_partition_gt(attr->tag, count);
|
||||||
printf("lt, gt = (%x, %x)\n", lt, gt);
|
printf("lt, gt = (%x, %x)\n", lt, gt);
|
||||||
|
|
||||||
// queue of pending alts we can emulate rotations with
|
// queue of pending alts we can emulate rotations with
|
||||||
lfs_rtag_t p_alts[3] = {0, 0, 0};
|
lfs_rtag_t p_alts[3] = {0, 0, 0};
|
||||||
lfs_off_t p_jumps[3] = {0, 0, 0};
|
lfs_off_t p_jumps[3] = {0, 0, 0};
|
||||||
lfs_rtag_t incoming = 0;
|
lfs_rtag_t stump = 0;
|
||||||
|
|
||||||
// descend down tree, building alt pointers
|
// descend down tree, building alt pointers
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -1469,118 +1478,156 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
lfs_rtag_t branch_ = branch; // TODO can this be done a better way?
|
lfs_rtag_t branch_ = branch; // TODO can this be done a better way?
|
||||||
branch += delta;
|
branch += delta;
|
||||||
|
|
||||||
// prune?
|
// // prune?
|
||||||
// TODO ugh, just clean this up later
|
// // TODO ugh, just clean this up later
|
||||||
if (p_alts[0]
|
// if (p_alts[0]
|
||||||
&& lfs_rtag_isred(p_alts[0])
|
// && lfs_rtag_isred(p_alts[0])
|
||||||
&& lfs_rtag_weight2(alt, p_alts[0]) >= lt+gt+1) {
|
// && lfs_rtag_weight2(alt, p_alts[0]) >= lt+gt+1) {
|
||||||
LFS_ASSERT(p_alts[0]);
|
// LFS_ASSERT(p_alts[0]);
|
||||||
|
//
|
||||||
branch = jump;
|
// branch = jump;
|
||||||
alt = lfs_rtag_black(p_alts[0]);
|
// alt = lfs_rtag_black(p_alts[0]);
|
||||||
jump = p_jumps[0];
|
// jump = p_jumps[0];
|
||||||
lfs_rbyd_p_pop(p_alts, p_jumps);
|
// lfs_rbyd_p_pop(p_alts, p_jumps);
|
||||||
|
//
|
||||||
} else if (lfs_rtag_weight(alt) >= lt+gt+1) {
|
// } else if (lfs_rtag_weight(alt) >= lt+gt+1) {
|
||||||
// TODO does this get hit?
|
// // TODO does this get hit?
|
||||||
// TODO can we simplify these two?
|
// // TODO can we simplify these two?
|
||||||
LFS_ASSERT(p_alts[0]);
|
// LFS_ASSERT(p_alts[0]);
|
||||||
|
//
|
||||||
branch = jump;
|
// branch = jump;
|
||||||
alt = lfs_rtag_black(p_alts[0]);
|
// alt = lfs_rtag_black(p_alts[0]);
|
||||||
jump = p_jumps[0];
|
// jump = p_jumps[0];
|
||||||
lfs_rbyd_p_pop(p_alts, p_jumps);
|
// lfs_rbyd_p_pop(p_alts, p_jumps);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
// split?
|
// // split?
|
||||||
if (lfs_rtag_isred(alt)
|
// if (lfs_rtag_isred(alt)
|
||||||
&& p_alts[0]
|
// && p_alts[0]
|
||||||
&& lfs_rtag_isred(p_alts[0])) {
|
// && lfs_rtag_isred(p_alts[0])) {
|
||||||
LFS_ASSERT(lfs_rtag_parallel(alt, p_alts[0]));
|
// LFS_ASSERT(lfs_rtag_parallel(alt, p_alts[0]));
|
||||||
|
//
|
||||||
if (lfs_rbyd_follow2(alt, p_alts[0], lt, gt)) {
|
// if (lfs_rbyd_follow2(alt, p_alts[0], lt, gt)) {
|
||||||
lfs_rtag_t alt_ = p_alts[0];
|
// lfs_rtag_t alt_ = p_alts[0];
|
||||||
lfs_off_t jump_ = p_jumps[0];
|
// lfs_off_t jump_ = p_jumps[0];
|
||||||
p_alts[0] = lfs_rtag_black(
|
// p_alts[0] = lfs_rtag_black(
|
||||||
lfs_rbyd_flip2(alt, alt_, lt, gt));
|
// lfs_rbyd_flip2(alt, alt_, lt, gt));
|
||||||
p_jumps[0] = jump;
|
// p_jumps[0] = jump;
|
||||||
alt = lfs_rtag_black(alt_);
|
// alt = lfs_rtag_black(alt_);
|
||||||
jump = jump_;
|
// jump = jump_;
|
||||||
|
//
|
||||||
lfs_rbyd_trim(alt_, <, >);
|
// lfs_rbyd_trim(alt_, <, >);
|
||||||
lfs_rbyd_trim(alt, <, >);
|
// lfs_rbyd_trim(alt, <, >);
|
||||||
lfs_rbyd_p_red(p_alts, p_jumps);
|
// lfs_rbyd_p_red(p_alts, p_jumps);
|
||||||
|
//
|
||||||
} else {
|
// } else {
|
||||||
lfs_rtag_t alt_ = p_alts[0];
|
// lfs_rtag_t alt_ = p_alts[0];
|
||||||
p_alts[0] = lfs_rtag_black(alt);
|
// p_alts[0] = lfs_rtag_black(alt);
|
||||||
p_jumps[0] = incoming;
|
// p_jumps[0] = stump;
|
||||||
|
//
|
||||||
lfs_rbyd_trim(alt_, <, >);
|
// lfs_rbyd_trim(alt_, <, >);
|
||||||
lfs_rbyd_trim(alt, <, >);
|
// lfs_rbyd_trim(alt, <, >);
|
||||||
lfs_rbyd_p_red(p_alts, p_jumps);
|
// lfs_rbyd_p_red(p_alts, p_jumps);
|
||||||
|
//
|
||||||
continue;
|
// continue;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// should've taken red alt?
|
// should've taken red alt?
|
||||||
if (p_alts[0]
|
if (lt < 0 || gt < 0) {
|
||||||
&& lfs_rtag_isred(p_alts[0])
|
LFS_ASSERT(p_alts[0] && lfs_rtag_isred(p_alts[0]));
|
||||||
&& lfs_rbyd_follow(p_alts[0], lt, gt)
|
|
||||||
&& lfs_rbyd_follow2(alt, p_alts[0], lt, gt)) {
|
|
||||||
LFS_ASSERT(lfs_rtag_isblack(alt));
|
LFS_ASSERT(lfs_rtag_isblack(alt));
|
||||||
|
|
||||||
lfs_rtag_t alt_ = p_alts[0];
|
if (lfs_rtag_parallel(alt, p_alts[0])) {
|
||||||
lfs_off_t jump_ = p_jumps[0];
|
printf("rflip parallel (%x,%x)\n", lt, gt);
|
||||||
p_alts[0] = lfs_rtag_red(lfs_rbyd_flip2(alt, alt_, lt, gt));
|
lfs_rtag_t alt_ = p_alts[0];
|
||||||
p_jumps[0] = branch;
|
p_alts[0] = lfs_rtag_red(lfs_rbyd_flip(alt, lt, gt));
|
||||||
lfs_rbyd_trim(alt, <, >); // TODO is this the place for this?
|
alt = lfs_rtag_black(alt_);
|
||||||
|
lfs_off_t jump_ = p_jumps[0];
|
||||||
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
p_jumps[0] = branch;
|
||||||
&lfs->pcache, &lfs->rcache,
|
branch = jump;
|
||||||
block, off,
|
jump = jump_;
|
||||||
p_alts, p_jumps,
|
} else {
|
||||||
lfs_rtag_black(lfs_rbyd_flip(alt_, lt, gt)),
|
printf("rflip perpendicular\n");
|
||||||
jump, &crc);
|
lfs_rtag_t alt_ = p_alts[0];
|
||||||
if (delta < 0) {
|
p_alts[0] = lfs_rtag_red(alt);
|
||||||
return delta;
|
alt = lfs_rtag_black(alt_);
|
||||||
|
lfs_off_t jump_ = p_jumps[0];
|
||||||
|
p_jumps[0] = branch;
|
||||||
|
jump = jump_;
|
||||||
}
|
}
|
||||||
off += delta;
|
|
||||||
|
|
||||||
lfs_rbyd_trim(alt_, <, >);
|
lfs_rbyd_untrim(alt, <, >);
|
||||||
incoming = branch_;
|
lfs_rbyd_trim(p_alts[0], <, >);
|
||||||
branch = jump_;
|
}
|
||||||
|
|
||||||
} else if (p_alts[0]
|
|
||||||
&& lfs_rtag_isred(p_alts[0])
|
|
||||||
&& lfs_rbyd_follow(p_alts[0], lt, gt)) {
|
|
||||||
LFS_ASSERT(lfs_rtag_isblack(alt));
|
|
||||||
|
|
||||||
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;
|
|
||||||
lfs_rbyd_trim(alt, <, >);
|
|
||||||
|
|
||||||
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
|
||||||
&lfs->pcache, &lfs->rcache,
|
|
||||||
block, off,
|
|
||||||
p_alts, p_jumps,
|
|
||||||
lfs_rtag_black(lfs_rbyd_flip(alt_, lt, gt)),
|
|
||||||
branch, &crc);
|
|
||||||
if (delta < 0) {
|
|
||||||
return delta;
|
|
||||||
}
|
|
||||||
off += delta;
|
|
||||||
|
|
||||||
incoming = branch_;
|
|
||||||
branch = jump_;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// if (p_alts[0]
|
||||||
|
// && lfs_rtag_isred(p_alts[0])
|
||||||
|
// && lfs_rbyd_follow(p_alts[0], lt, gt)
|
||||||
|
// && lfs_rbyd_follow2(alt, p_alts[0], lt, gt)) {
|
||||||
|
// LFS_ASSERT(lfs_rtag_isblack(alt));
|
||||||
|
//
|
||||||
|
// lfs_rtag_t alt_ = p_alts[0];
|
||||||
|
// lfs_off_t jump_ = p_jumps[0];
|
||||||
|
// p_alts[0] = lfs_rtag_red(lfs_rbyd_flip2(alt, alt_, lt, gt));
|
||||||
|
// p_jumps[0] = branch;
|
||||||
|
// lfs_rbyd_trim(alt, <, >); // TODO is this the place for this?
|
||||||
|
//
|
||||||
|
// lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
||||||
|
// &lfs->pcache, &lfs->rcache,
|
||||||
|
// block, off,
|
||||||
|
// p_alts, p_jumps,
|
||||||
|
// lfs_rtag_black(lfs_rbyd_flip(alt_, lt, gt)),
|
||||||
|
// jump, &crc);
|
||||||
|
// if (delta < 0) {
|
||||||
|
// return delta;
|
||||||
|
// }
|
||||||
|
// off += delta;
|
||||||
|
//
|
||||||
|
// lfs_rbyd_trim(alt_, <, >);
|
||||||
|
// stump = branch_;
|
||||||
|
// branch = jump_;
|
||||||
|
//
|
||||||
|
// } else if (p_alts[0]
|
||||||
|
// && lfs_rtag_isred(p_alts[0])
|
||||||
|
// && lfs_rbyd_follow(p_alts[0], lt, gt)) {
|
||||||
|
// LFS_ASSERT(lfs_rtag_isblack(alt));
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
// lfs_rbyd_trim(alt, <, >);
|
||||||
|
//
|
||||||
|
// lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
||||||
|
// &lfs->pcache, &lfs->rcache,
|
||||||
|
// block, off,
|
||||||
|
// p_alts, p_jumps,
|
||||||
|
// lfs_rtag_black(lfs_rbyd_flip(alt_, lt, gt)),
|
||||||
|
// branch, &crc);
|
||||||
|
// if (delta < 0) {
|
||||||
|
// return delta;
|
||||||
|
// }
|
||||||
|
// off += delta;
|
||||||
|
//
|
||||||
|
// stump = branch_;
|
||||||
|
// branch = jump_;
|
||||||
|
|
||||||
// take black alt?
|
// take black alt?
|
||||||
} else if (lfs_rtag_isblack(alt)
|
if (lfs_rtag_isblack(alt)
|
||||||
&& lfs_rbyd_follow(alt, lt, gt)) {
|
&& lfs_rbyd_follow(alt, lt, gt)) {
|
||||||
|
printf("bflip\n");
|
||||||
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
||||||
&lfs->pcache, &lfs->rcache,
|
&lfs->pcache, &lfs->rcache,
|
||||||
block, off,
|
block, off,
|
||||||
@@ -1591,12 +1638,13 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
}
|
}
|
||||||
off += delta;
|
off += delta;
|
||||||
|
|
||||||
lfs_rbyd_trim(alt, <, >);
|
lfs_rbyd_trim(lfs_rbyd_flip(alt, lt, gt), <, >);
|
||||||
incoming = branch_;
|
stump = branch_;
|
||||||
branch = jump;
|
branch = jump;
|
||||||
|
|
||||||
// continue down current path
|
// continue down current path
|
||||||
} else {
|
} else {
|
||||||
|
printf("continue\n");
|
||||||
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
||||||
&lfs->pcache, &lfs->rcache,
|
&lfs->pcache, &lfs->rcache,
|
||||||
block, off,
|
block, off,
|
||||||
@@ -1608,7 +1656,7 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
off += delta;
|
off += delta;
|
||||||
|
|
||||||
lfs_rbyd_trim(alt, <, >);
|
lfs_rbyd_trim(alt, <, >);
|
||||||
incoming = branch_;
|
stump = branch_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// found end of tree?
|
// found end of tree?
|
||||||
@@ -1796,6 +1844,7 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
|
|
||||||
if (crc_ != crc) {
|
if (crc_ != crc) {
|
||||||
// oh no, something went wrong
|
// oh no, something went wrong
|
||||||
|
printf("oh no %08x != %08x\n", crc_, crc);
|
||||||
return LFS_ERR_CORRUPT;
|
return LFS_ERR_CORRUPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -72,7 +72,7 @@ def tagrepr(tag, size, off=None):
|
|||||||
return 'fcrc x%02x %d' % (type2, size)
|
return 'fcrc x%02x %d' % (type2, size)
|
||||||
elif type1 & 0x4:
|
elif type1 & 0x4:
|
||||||
return 'alt%s%s x%x %s' % (
|
return 'alt%s%s x%x %s' % (
|
||||||
'r' if type1 & 4 else 'b',
|
'r' if type1 & 1 else 'b',
|
||||||
'gt' if type1 & 2 else 'lt',
|
'gt' if type1 & 2 else 'lt',
|
||||||
tag >> 3,
|
tag >> 3,
|
||||||
'x%x' % (0xffffffff & (off-size))
|
'x%x' % (0xffffffff & (off-size))
|
||||||
|
|||||||
+280
-114
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
# Test this inner rbyd data-structure
|
# Test this inner rbyd data-structure
|
||||||
|
|
||||||
[cases.rbyd_commit_fetch]
|
[cases.test_rbyd_commit_fetch]
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
code = '''
|
code = '''
|
||||||
@@ -41,7 +41,7 @@ code = '''
|
|||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[cases.rbyd_multi_commit_fetch]
|
[cases.test_rbyd_multi_commit_fetch]
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
code = '''
|
code = '''
|
||||||
@@ -82,7 +82,7 @@ code = '''
|
|||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
[cases.rbyd_commit_lookup]
|
[cases.test_rbyd_commit_lookup]
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
code = '''
|
code = '''
|
||||||
@@ -107,16 +107,15 @@ code = '''
|
|||||||
// 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_off_t off;
|
||||||
lfs_size_t size;
|
lfs_size_t size;
|
||||||
lfs_rtag_t ntag;
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
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, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
// commit with one attribute
|
// commit with one attribute
|
||||||
@@ -125,27 +124,19 @@ code = '''
|
|||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||||
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
// commit with two attributes
|
// commit with two attributes
|
||||||
@@ -156,42 +147,30 @@ code = '''
|
|||||||
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
NULL))) => 0;
|
NULL))) => 0;
|
||||||
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
//assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
//assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# TODO we should make sure lookup always returns <= the requested tag,
|
# TODO we should make sure lookup always returns <= the requested tag,
|
||||||
# this may require fixing in lfs_rbyd_commit to make sure the weights lean
|
# this may require fixing in lfs_rbyd_commit to make sure the weights lean
|
||||||
# one way
|
# one way
|
||||||
[cases.rbyd_multi_commit_lookup]
|
[cases.test_rbyd_multi_commit_lookup]
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
code = '''
|
code = '''
|
||||||
@@ -215,16 +194,16 @@ code = '''
|
|||||||
|
|
||||||
lfs_off_t off;
|
lfs_off_t off;
|
||||||
lfs_size_t size;
|
lfs_size_t size;
|
||||||
lfs_rtag_t ntag;
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
// TODO move these extra checks (for 0, in-between, enoent) to other tests
|
||||||
|
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, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
// commit with one attribute
|
// commit with one attribute
|
||||||
@@ -233,27 +212,19 @@ code = '''
|
|||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||||
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
// commit with two attributes
|
// commit with two attributes
|
||||||
@@ -264,42 +235,30 @@ 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_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
//assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
//assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# [cases.rbyd_commit_fetchmatch]
|
# [cases.test_rbyd_commit_fetchmatch]
|
||||||
# [cases.rbyd_multi_commit_fetchmatch]
|
# [cases.test_rbyd_multi_commit_fetchmatch]
|
||||||
|
|
||||||
[cases.rbyd_leaves]
|
[cases.test_rbyd_bifoliate]
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
code = '''
|
code = '''
|
||||||
@@ -317,9 +276,9 @@ code = '''
|
|||||||
};
|
};
|
||||||
|
|
||||||
// create a split in the leaves
|
// create a split in the leaves
|
||||||
// <r
|
// <b
|
||||||
// => /|
|
// => .-'|
|
||||||
// 1 1 2
|
// 1 1 2
|
||||||
lfs_rbyd_t rbyd = rbyd_init;
|
lfs_rbyd_t 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,
|
||||||
@@ -329,42 +288,249 @@ code = '''
|
|||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
lfs_off_t off;
|
lfs_off_t off;
|
||||||
lfs_size_t size;
|
lfs_size_t size;
|
||||||
lfs_rtag_t ntag;
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0x98, &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
assert(size == 4);
|
|
||||||
//assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
|
||||||
assert(size == 4);
|
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
|
|
||||||
// split the other direction
|
// split the other direction
|
||||||
// >r
|
// >b
|
||||||
// => /|
|
// => .-'|
|
||||||
// 2 2 1
|
// 2 2 1
|
||||||
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, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL))) => 0;
|
LFS_MKRATTR(GSTATE, 1, 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_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size)
|
||||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||||
assert(size == 4);
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, 0x98, &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
assert(size == 4);
|
|
||||||
//assert(ntag == LFS_ERR_NOENT);
|
|
||||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
|
||||||
=> LFS_MKRTAG(GSTATE, 2, 0);
|
|
||||||
assert(size == 4);
|
|
||||||
assert(ntag == LFS_ERR_NOENT);
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
[cases.test_rbyd_bflips]
|
||||||
|
in = 'lfs.c'
|
||||||
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_t rbyd_init = {
|
||||||
|
.block = 0,
|
||||||
|
.trunk = 0,
|
||||||
|
.noff = 0,
|
||||||
|
.rev = 1,
|
||||||
|
.crc = 0,
|
||||||
|
.count = 0,
|
||||||
|
.erased = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ignore a black edge
|
||||||
|
// <b <b
|
||||||
|
// .-'| => .----'|
|
||||||
|
// 1 2 1 2 2
|
||||||
|
lfs_rbyd_t rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
|
||||||
|
// flip a black edge
|
||||||
|
// <b >b
|
||||||
|
// .-'| => .-'|
|
||||||
|
// 1 2 1 2 1
|
||||||
|
rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xcccccccc}, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
'''
|
||||||
|
|
||||||
|
[cases.test_rbyd_trifoliate]
|
||||||
|
in = 'lfs.c'
|
||||||
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_t rbyd_init = {
|
||||||
|
.block = 0,
|
||||||
|
.trunk = 0,
|
||||||
|
.noff = 0,
|
||||||
|
.rev = 1,
|
||||||
|
.crc = 0,
|
||||||
|
.count = 0,
|
||||||
|
.erased = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// without a flip
|
||||||
|
// <r
|
||||||
|
// .----'|
|
||||||
|
// <b => | <b
|
||||||
|
// .-'| | .-'|
|
||||||
|
// 1 2 1 2 3
|
||||||
|
lfs_rbyd_t rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 3, 0);
|
||||||
|
|
||||||
|
// with a flip
|
||||||
|
// >r
|
||||||
|
// .-'|
|
||||||
|
// <b => | >b
|
||||||
|
// .-'| .--|-'|
|
||||||
|
// 2 3 2 3 1
|
||||||
|
rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xcccccccc}, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 3, 0);
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
[cases.test_rbyd_rflips]
|
||||||
|
in = 'lfs.c'
|
||||||
|
defines.ERASE_VALUE = [0xff, 0x00, 0x1b, -1]
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_t rbyd_init = {
|
||||||
|
.block = 0,
|
||||||
|
.trunk = 0,
|
||||||
|
.noff = 0,
|
||||||
|
.rev = 1,
|
||||||
|
.crc = 0,
|
||||||
|
.count = 0,
|
||||||
|
.erased = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ignore a red edge and black edge
|
||||||
|
// <r <r
|
||||||
|
// .----'| .-------'|
|
||||||
|
// | <b => | <b
|
||||||
|
// | .-'| | .----'|
|
||||||
|
// 1 2 3 1 2 3 3
|
||||||
|
lfs_rbyd_t rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xdddddddd}, 4, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 3, 0);
|
||||||
|
|
||||||
|
// ignore a red edge, flip a black edge
|
||||||
|
// <r <r
|
||||||
|
// .----'| .-------'|
|
||||||
|
// | <b => | >b
|
||||||
|
// | .-'| | .-'|
|
||||||
|
// 1 2 3 1 2 3 2
|
||||||
|
rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xdddddddd}, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 3, 0);
|
||||||
|
|
||||||
|
// flip a red edge and black edge
|
||||||
|
// <r >r
|
||||||
|
// .----'| .-'|
|
||||||
|
// | <b => | >b
|
||||||
|
// | .-'| .--|-'|
|
||||||
|
// 1 2 3 1 2 3 1
|
||||||
|
rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xdddddddd}, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 3, 0);
|
||||||
|
|
||||||
|
// flip a red edge, ignore a black edge
|
||||||
|
// <r >r
|
||||||
|
// .-'| .-------'|
|
||||||
|
// | >b => | >b
|
||||||
|
// .--|-'| | .-'|
|
||||||
|
// 3 1 2 3 1 2 1
|
||||||
|
rbyd = rbyd_init;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xcccccccc}, 4,
|
||||||
|
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xdddddddd}, 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_MKRTAG(GSTATE, 1, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 2, 0);
|
||||||
|
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size)
|
||||||
|
=> LFS_MKRTAG(GSTATE, 3, 0);
|
||||||
|
'''
|
||||||
|
|||||||
Reference in New Issue
Block a user