Added a bias to alt weights so in-between tags prefer larger tags
This bias makes it so that tag lookups always find a tag strictly >= the requested tag, unless we are at the end of the tree. This makes tree traversal trivial, which is quite nice. Need to remove ntag now, it's no longer needed.
This commit is contained in:
@@ -452,7 +452,7 @@ static inline bool lfs_rtag_isalt(lfs_rtag_t tag) {
|
||||
}
|
||||
|
||||
static inline bool lfs_rtag_intree(lfs_rtag_t tag) {
|
||||
return (tag & 0x6) != 0x2;
|
||||
return !(tag & 0x2);
|
||||
}
|
||||
|
||||
static inline uint8_t lfs_rtag_type1(lfs_rtag_t tag) {
|
||||
@@ -491,6 +491,10 @@ static inline lfs_rtag_t lfs_rtag_weight(lfs_rtag_t tag) {
|
||||
return (tag >> 3) & 0xfffffff;
|
||||
}
|
||||
|
||||
static inline lfs_rtag_t lfs_rtag_weight2(lfs_rtag_t tag, lfs_rtag_t tag2) {
|
||||
return lfs_rtag_weight(tag) + lfs_rtag_weight(tag2);
|
||||
}
|
||||
|
||||
static inline lfs_rtag_t lfs_rtag_red(lfs_rtag_t tag) {
|
||||
return tag | 0x1;
|
||||
}
|
||||
@@ -949,7 +953,7 @@ static int lfs_rbyd_fetch(lfs_t *lfs,
|
||||
|
||||
// found trunk of tree?
|
||||
printf("%x: %08x => %d %d\n", off, tag, wastrunk, lfs_rtag_intree(tag));
|
||||
if (!wastrunk && lfs_rtag_intree(tag)) {
|
||||
if (!wastrunk && (lfs_rtag_isalt(tag) || lfs_rtag_intree(tag))) {
|
||||
trunk = off;
|
||||
wastrunk = true;
|
||||
}
|
||||
@@ -1067,54 +1071,96 @@ static int lfs_rbyd_fetch(lfs_t *lfs,
|
||||
|
||||
// TODO make these rtag functions?
|
||||
static inline bool lfs_rbyd_follow(lfs_rtag_t alt,
|
||||
lfs_rtag_t lo, lfs_rtag_t hi) {
|
||||
lfs_rtag_t lt, lfs_rtag_t gt) {
|
||||
if (lfs_rtag_islt(alt)) {
|
||||
return lfs_rtag_weight(alt) > lo;
|
||||
return lfs_rtag_weight(alt) > lt;
|
||||
} else {
|
||||
return lfs_rtag_weight(alt) > hi;
|
||||
return lfs_rtag_weight(alt) > gt;
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool lfs_rbyd_follow2(
|
||||
lfs_rtag_t alt, lfs_rtag_t alt_, lfs_rtag_t lt, lfs_rtag_t gt) {
|
||||
if (lfs_rtag_islt(alt) && lfs_rtag_islt(alt_)) {
|
||||
return lfs_rtag_weight(alt) + lfs_rtag_weight(alt_) > lt;
|
||||
} else if (lfs_rtag_isgt(alt) && lfs_rtag_isgt(alt_)) {
|
||||
return lfs_rtag_weight(alt) + lfs_rtag_weight(alt_) > gt;
|
||||
} else {
|
||||
return lfs_rbyd_follow(alt, lt, gt);
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
|
||||
static inline lfs_rtag_t lfs_rbyd_flip(
|
||||
lfs_rtag_t alt, lfs_rtag_t lt, lfs_rtag_t gt) {
|
||||
return LFS_MKRALT_(
|
||||
lfs_rtag_isred(alt),
|
||||
!lfs_rtag_isgt(alt),
|
||||
(lt+gt-1) - lfs_rtag_weight(alt));
|
||||
// TODO
|
||||
}
|
||||
|
||||
static inline lfs_rtag_t lfs_rbyd_flip2(
|
||||
lfs_rtag_t alt, lfs_rtag_t alt_, lfs_rtag_t lt, lfs_rtag_t gt) {
|
||||
return LFS_MKRALT_(
|
||||
lfs_rtag_isred(alt),
|
||||
!lfs_rtag_isgt(alt),
|
||||
(lt+gt-1) - (lfs_rtag_weight(alt)+lfs_rtag_weight(alt_)));
|
||||
// TODO
|
||||
}
|
||||
|
||||
static inline void lfs_rbyd_trim(lfs_rtag_t alt,
|
||||
lfs_rtag_t *lo, lfs_rtag_t *hi) {
|
||||
lfs_rtag_t lo_ = *lo;
|
||||
lfs_rtag_t hi_ = *hi;
|
||||
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, lo_, hi_)) {
|
||||
*hi = lfs_rtag_weight(alt)-1 - *lo;
|
||||
if (lfs_rbyd_follow(alt, lt_, gt_)) {
|
||||
*gt = lfs_rtag_weight(alt)-1 - *lt;
|
||||
} else {
|
||||
*lo = *lo - lfs_rtag_weight(alt);
|
||||
*lt = *lt - lfs_rtag_weight(alt);
|
||||
}
|
||||
} else {
|
||||
if (lfs_rbyd_follow(alt, lo_, hi_)) {
|
||||
*lo = lfs_rtag_weight(alt)-1 - *hi;
|
||||
if (lfs_rbyd_follow(alt, lt_, gt_)) {
|
||||
*lt = lfs_rtag_weight(alt)-1 - *gt;
|
||||
} else {
|
||||
*hi = *hi - lfs_rtag_weight(alt);
|
||||
*gt = *gt - lfs_rtag_weight(alt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO lfs_rtag_weight_lt?
|
||||
static inline lfs_rtag_t lfs_rbyd_partition_lt(
|
||||
lfs_rtag_t tag, uint16_t count) {
|
||||
(void)count;
|
||||
return lfs_rtag_weight(tag);
|
||||
}
|
||||
|
||||
static inline lfs_rtag_t lfs_rbyd_partition_gt(
|
||||
lfs_rtag_t tag, uint16_t count) {
|
||||
return (((lfs_rtag_t)count << 12) + 0xff8)-1 - lfs_rtag_weight(tag);
|
||||
}
|
||||
|
||||
//static inline void lfs_rbyd_trim(lfs_rtag_t alt,
|
||||
// lfs_rtag_t *lo, lfs_rtag_t *hi) {
|
||||
// lfs_rtag_t *lt, lfs_rtag_t *gt) {
|
||||
// if (lfs_rtag_islt(alt)) {
|
||||
// *lo = *lo - lfs_rtag_weight(alt);
|
||||
// *lt = *lt - lfs_rtag_weight(alt);
|
||||
// } else {
|
||||
// *hi = *hi - lfs_rtag_weight(alt);
|
||||
// *gt = *gt - lfs_rtag_weight(alt);
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//static inline void lfs_rbyd_trimf(lfs_rtag_t alt,
|
||||
// lfs_rtag_t *lo, lfs_rtag_t *hi) {
|
||||
// lfs_rtag_t *lt, lfs_rtag_t *gt) {
|
||||
// if (lfs_rtag_islt(alt)) {
|
||||
// *hi = lfs_rtag_weight(alt)-1 - *lo;
|
||||
// *gt = lfs_rtag_weight(alt)-1 - *lt;
|
||||
// } else {
|
||||
// *lo = lfs_rtag_weight(alt)-1 - *hi;
|
||||
// *lt = lfs_rtag_weight(alt)-1 - *gt;
|
||||
// }
|
||||
//}
|
||||
|
||||
static lfs_ssize_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
||||
lfs_rtag_t tag, lfs_off_t *off, lfs_rtag_t *ntag) {
|
||||
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) {
|
||||
// no trunk yet?
|
||||
lfs_off_t branch = rbyd->trunk;
|
||||
if (!branch) {
|
||||
@@ -1122,10 +1168,9 @@ static lfs_ssize_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
||||
}
|
||||
|
||||
// weights for pruning
|
||||
lfs_rtag_t lo = lfs_rtag_weight(tag);
|
||||
lfs_rtag_t hi = (((lfs_rtag_t)rbyd->count << 12) + 0xff8)-1
|
||||
- lfs_rtag_weight(tag);
|
||||
printf("lo, hi = (%x, %x)\n", lo, hi);
|
||||
lfs_rtag_t lt = lfs_rbyd_partition_lt(tag, rbyd->count);
|
||||
lfs_rtag_t gt = lfs_rbyd_partition_gt(tag, rbyd->count);
|
||||
printf("lt, gt = (%x, %x)\n", lt, gt);
|
||||
|
||||
// descend down tree, building alt pointers
|
||||
while (true) {
|
||||
@@ -1140,35 +1185,55 @@ static lfs_ssize_t lfs_rbyd_lookup(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
||||
|
||||
// found an alt?
|
||||
if (lfs_rtag_isalt(alt)) {
|
||||
printf("follow %x (%x, %x)? => %d\n", alt, lo, hi, lfs_rbyd_follow(alt, lo, hi));
|
||||
if (lfs_rbyd_follow(alt, lo, hi)) {
|
||||
lfs_rbyd_trim(alt, &lo, &hi);
|
||||
branch = branch - jump;
|
||||
// make jump absolute
|
||||
jump = branch - jump;
|
||||
branch += delta;
|
||||
|
||||
printf("follow %x (%x, %x)? => %d\n", alt, lt, gt, lfs_rbyd_follow(alt, lt, gt));
|
||||
if (lfs_rbyd_follow(alt, lt, gt)) {
|
||||
lfs_rbyd_trim(alt, <, >);
|
||||
branch = jump;
|
||||
} else {
|
||||
lfs_rbyd_trim(alt, &lo, &hi);
|
||||
branch += delta;
|
||||
lfs_rbyd_trim(alt, <, >);
|
||||
}
|
||||
|
||||
// found end of tree?
|
||||
} else {
|
||||
// different tag => not found
|
||||
if (lfs_rtag_type3(alt) != lfs_rtag_type3(tag)) {
|
||||
// if (lfs_rtag_type3(alt) != lfs_rtag_type3(tag)) {
|
||||
// return LFS_ERR_NOENT;
|
||||
// }
|
||||
|
||||
// update the tag id
|
||||
lfs_rtag_t tag_ = LFS_MKRTAG_(
|
||||
lfs_rtag_type1(alt),
|
||||
lfs_rtag_type2(alt),
|
||||
lt >> 12); // TODO there's no way this can be right
|
||||
|
||||
// not what we're looking for?
|
||||
if (tag_ < tag) {
|
||||
return LFS_ERR_NOENT;
|
||||
}
|
||||
|
||||
// update with what we found
|
||||
// save what we found
|
||||
*off = branch + delta;
|
||||
*size = jump;
|
||||
if (ntag) {
|
||||
lfs_rtag_t ntag_ = tag + ((hi+1) << 3);
|
||||
if (lfs_rtag_weight(ntag_)
|
||||
== ((lfs_rtag_t)rbyd->count << 12) + 0xff8) {
|
||||
ntag_ = 0;
|
||||
if (gt == lfs_rbyd_partition_gt(tag, rbyd->count)) {
|
||||
*ntag = LFS_ERR_NOENT;
|
||||
} else {
|
||||
*ntag = tag + ((gt+1) << 3);
|
||||
}
|
||||
*ntag = ntag_;
|
||||
}
|
||||
*off = branch;
|
||||
return jump;
|
||||
}
|
||||
|
||||
printf("lt, gt = (%x, %x)\n", lt, gt);
|
||||
printf("lookup %08x => %08x (raw %08x)\n", tag, tag_, alt);
|
||||
if (ntag) { printf("ntag %08x => %08x\n", tag, *ntag); }
|
||||
//return alt; // TODO adjust
|
||||
//return lt << 3;
|
||||
//return lfs_rtag_setid(alt, lt >> 12);
|
||||
return tag_;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1232,6 +1297,7 @@ static lfs_ssize_t lfs_rbyd_progtag(lfs_t *lfs,
|
||||
return i;
|
||||
}
|
||||
|
||||
// TODO should crc be in a different argument position?
|
||||
static lfs_ssize_t lfs_rbyd_p_push(lfs_t *lfs,
|
||||
lfs_cache_t *pcache, lfs_cache_t *rcache,
|
||||
lfs_block_t block, lfs_off_t off,
|
||||
@@ -1266,6 +1332,17 @@ static lfs_ssize_t lfs_rbyd_p_push(lfs_t *lfs,
|
||||
return delta;
|
||||
}
|
||||
|
||||
static inline void lfs_rbyd_p_pop(
|
||||
lfs_rtag_t p_alts[static 3],
|
||||
lfs_off_t p_jumps[static 3]) {
|
||||
p_alts[0] = p_alts[1];
|
||||
p_jumps[0] = p_jumps[1];
|
||||
p_alts[1] = p_alts[2];
|
||||
p_jumps[1] = p_jumps[2];
|
||||
p_alts[2] = 0;
|
||||
p_jumps[2] = 0;
|
||||
}
|
||||
|
||||
static lfs_ssize_t lfs_rbyd_p_flush(lfs_t *lfs,
|
||||
lfs_cache_t *pcache, lfs_cache_t *rcache,
|
||||
lfs_block_t block, lfs_off_t off,
|
||||
@@ -1355,6 +1432,7 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
||||
// append each tag to the tree
|
||||
for (const struct lfs_rattr *attr = attrs; attr; attr = attr->next) {
|
||||
// assume we'll update our trunk
|
||||
// TODO this name is confusing, us trunk and trunk_?
|
||||
lfs_off_t branch = trunk;
|
||||
trunk = off;
|
||||
|
||||
@@ -1364,13 +1442,14 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
||||
}
|
||||
|
||||
// weights for pruning
|
||||
lfs_rtag_t lo = lfs_rtag_weight(attr->tag);
|
||||
lfs_rtag_t hi = ((count << 12)+0xfff)-1 - lfs_rtag_weight(attr->tag);
|
||||
printf("lo, hi = (%x, %x)\n", lo, hi);
|
||||
lfs_rtag_t lt = lfs_rbyd_partition_lt(attr->tag, count);
|
||||
lfs_rtag_t gt = lfs_rbyd_partition_gt(attr->tag, count);
|
||||
printf("lt, gt = (%x, %x)\n", lt, gt);
|
||||
|
||||
// queue of pending alts we can emulate rotations with
|
||||
lfs_rtag_t p_alts[3] = {0, 0, 0};
|
||||
lfs_off_t p_jumps[3] = {0, 0, 0};
|
||||
lfs_rtag_t incoming = 0;
|
||||
|
||||
// descend down tree, building alt pointers
|
||||
while (true) {
|
||||
@@ -1385,50 +1464,152 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
||||
|
||||
// found an alt?
|
||||
if (lfs_rtag_isalt(alt)) {
|
||||
LFS_ASSERT(false); // TODO
|
||||
|
||||
// make jump absolute
|
||||
jump = branch - jump;
|
||||
lfs_rtag_t branch_ = branch; // TODO can this be done a better way?
|
||||
branch += delta;
|
||||
|
||||
// // prune?
|
||||
// if (lfs_rtag_weight(alt) >= lo+hi+1) {
|
||||
// LFS_ASSERT(p_alts[0]);
|
||||
// alt = lfs_rtag_black(p_alts[0]);
|
||||
// jump = p_jumps[0];
|
||||
// branch = ?;
|
||||
// lfs_rbyd_p_pop(p_alts, p_jumps);
|
||||
// }
|
||||
//
|
||||
// // split?
|
||||
// if (p_alts[0] && lfs_rtag_isred(alt) && lfs_rtag_isred(p_alts[0])) {
|
||||
// LFS_ASSERT(lfs_rtag_parallel(alt, p_alts[0]));
|
||||
// if (lfs_rbyd_follow(lo, hi, alt)) {
|
||||
// lfs_rbyd_trim(&lo, &hi, alt[0]);
|
||||
// lfs_rbyd_trim(&lo, &hi, alt);
|
||||
// lfs_rtag_t alt_ = lfs_rtag_black(p_alts[0]);
|
||||
// lfs_off_t jump_ = p_jumps[0];
|
||||
//
|
||||
//
|
||||
// p_jumps[0] = branch;
|
||||
//
|
||||
//
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps);
|
||||
//
|
||||
//
|
||||
// } else {
|
||||
// p_alts[0] = lfs_rbyd_black(p_alts[0]);
|
||||
// p_jumps[0] = ?; // TODO where does this come from?
|
||||
// lfs_rbyd_p_red(p_alts, p_jumps);
|
||||
// lfs_rbyd_trim(&lo, &hi, alt);
|
||||
//
|
||||
// branch += delta;
|
||||
// continue;
|
||||
// }
|
||||
// }
|
||||
// prune?
|
||||
// TODO ugh, just clean this up later
|
||||
if (p_alts[0]
|
||||
&& lfs_rtag_isred(p_alts[0])
|
||||
&& lfs_rtag_weight2(alt, p_alts[0]) >= lt+gt+1) {
|
||||
LFS_ASSERT(p_alts[0]);
|
||||
|
||||
branch = jump;
|
||||
alt = lfs_rtag_black(p_alts[0]);
|
||||
jump = p_jumps[0];
|
||||
lfs_rbyd_p_pop(p_alts, p_jumps);
|
||||
|
||||
} else if (lfs_rtag_weight(alt) >= lt+gt+1) {
|
||||
// TODO does this get hit?
|
||||
// TODO can we simplify these two?
|
||||
LFS_ASSERT(p_alts[0]);
|
||||
|
||||
branch = jump;
|
||||
alt = lfs_rtag_black(p_alts[0]);
|
||||
jump = p_jumps[0];
|
||||
lfs_rbyd_p_pop(p_alts, p_jumps);
|
||||
}
|
||||
|
||||
|
||||
// split?
|
||||
if (lfs_rtag_isred(alt)
|
||||
&& p_alts[0]
|
||||
&& lfs_rtag_isred(p_alts[0])) {
|
||||
LFS_ASSERT(lfs_rtag_parallel(alt, p_alts[0]));
|
||||
|
||||
//branch += delta;
|
||||
if (lfs_rbyd_follow2(alt, p_alts[0], lt, gt)) {
|
||||
lfs_rtag_t alt_ = p_alts[0];
|
||||
lfs_off_t jump_ = p_jumps[0];
|
||||
p_alts[0] = lfs_rtag_black(
|
||||
lfs_rbyd_flip2(alt, alt_, lt, gt));
|
||||
p_jumps[0] = jump;
|
||||
alt = lfs_rtag_black(alt_);
|
||||
jump = jump_;
|
||||
|
||||
lfs_rbyd_trim(alt_, <, >);
|
||||
lfs_rbyd_trim(alt, <, >);
|
||||
lfs_rbyd_p_red(p_alts, p_jumps);
|
||||
|
||||
} else {
|
||||
lfs_rtag_t alt_ = p_alts[0];
|
||||
p_alts[0] = lfs_rtag_black(alt);
|
||||
p_jumps[0] = incoming;
|
||||
|
||||
lfs_rbyd_trim(alt_, <, >);
|
||||
lfs_rbyd_trim(alt, <, >);
|
||||
lfs_rbyd_p_red(p_alts, p_jumps);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// should've taken red alt?
|
||||
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_, <, >);
|
||||
incoming = 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;
|
||||
|
||||
incoming = branch_;
|
||||
branch = jump_;
|
||||
|
||||
// take black alt?
|
||||
} else if (lfs_rtag_isblack(alt)
|
||||
&& lfs_rbyd_follow(alt, lt, gt)) {
|
||||
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
||||
&lfs->pcache, &lfs->rcache,
|
||||
block, off,
|
||||
p_alts, p_jumps,
|
||||
lfs_rbyd_flip(alt, lt, gt), branch, &crc);
|
||||
if (delta < 0) {
|
||||
return delta;
|
||||
}
|
||||
off += delta;
|
||||
|
||||
lfs_rbyd_trim(alt, <, >);
|
||||
incoming = branch_;
|
||||
branch = jump;
|
||||
|
||||
// continue down current path
|
||||
} else {
|
||||
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
||||
&lfs->pcache, &lfs->rcache,
|
||||
block, off,
|
||||
p_alts, p_jumps,
|
||||
alt, jump, &crc);
|
||||
if (delta < 0) {
|
||||
return delta;
|
||||
}
|
||||
off += delta;
|
||||
|
||||
lfs_rbyd_trim(alt, <, >);
|
||||
incoming = branch_;
|
||||
}
|
||||
|
||||
// found end of tree?
|
||||
} else {
|
||||
@@ -1436,15 +1617,20 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
||||
if (alt != attr->tag) {
|
||||
lfs_rtag_t alt_;
|
||||
if (lfs_rtag_weight(alt) < lfs_rtag_weight(attr->tag)) {
|
||||
alt_ = LFS_MKRALT(B, LT, lo);
|
||||
// bias the weights so that lookups always find the
|
||||
// next biggest tag
|
||||
alt_ = LFS_MKRALT(B, LT, lt+1 - (
|
||||
lfs_rtag_weight(attr->tag)
|
||||
- lfs_rtag_weight(alt)));
|
||||
} else {
|
||||
alt_ = LFS_MKRALT(B, GT, hi);
|
||||
alt_ = LFS_MKRALT(B, GT, gt);
|
||||
}
|
||||
|
||||
lfs_ssize_t delta = lfs_rbyd_p_push(lfs,
|
||||
&lfs->pcache, &lfs->rcache,
|
||||
block, off,
|
||||
p_alts, p_jumps, alt_, branch, &crc);
|
||||
p_alts, p_jumps,
|
||||
alt_, branch, &crc);
|
||||
if (delta < 0) {
|
||||
return delta;
|
||||
}
|
||||
|
||||
+18
-1
@@ -176,6 +176,19 @@ def main(disk, block_size, block1, block2=None, **args):
|
||||
' (%s)' % ', '.join(notes)
|
||||
if notes else ''))
|
||||
|
||||
if args.get('device'):
|
||||
print('%8s %-47s %08x %x' % (
|
||||
'',
|
||||
'%-22s%s' % (
|
||||
'%08x %08x' % (tag, size),
|
||||
' %s' % ' '.join(
|
||||
'%08x' % struct.unpack('<I',
|
||||
data[j_+delta+i*4:j_+delta+i*4+4])
|
||||
for i in range(min(size//4, 3)))[:23]
|
||||
if not tag & 0x4 else ''),
|
||||
crc,
|
||||
popc(crc) & 1))
|
||||
|
||||
if args.get('raw'):
|
||||
for o, line in enumerate(xxd(data[j_:j_+delta])):
|
||||
print('%8s: %s' % ('%04x' % (j_ + o*16), line))
|
||||
@@ -213,9 +226,13 @@ if __name__ == "__main__":
|
||||
action='store_true',
|
||||
help="Don't stop parsing on bad commits.")
|
||||
parser.add_argument(
|
||||
'-R', '--raw',
|
||||
'-r', '--raw',
|
||||
action='store_true',
|
||||
help="Show the raw data including tag encodings.")
|
||||
parser.add_argument(
|
||||
'-x', '--device',
|
||||
action='store_true',
|
||||
help="Show the device-side representation of tags.")
|
||||
parser.add_argument(
|
||||
'-T', '--no-truncate',
|
||||
action='store_true',
|
||||
|
||||
+189
-113
@@ -39,18 +39,6 @@ code = '''
|
||||
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||
NULL))) => 0;
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
|
||||
// // commit with three attributes
|
||||
// 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) => 0;
|
||||
|
||||
// TODO more?
|
||||
'''
|
||||
|
||||
[cases.rbyd_multi_commit_fetch]
|
||||
@@ -92,19 +80,6 @@ code = '''
|
||||
lfs_rbyd_commit(&lfs, &rbyd,
|
||||
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
|
||||
// // commit with three attributes
|
||||
// rbyd = rbyd_init;
|
||||
// lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||
// lfs_rbyd_commit(&lfs, &rbyd,
|
||||
// LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||
// lfs_rbyd_commit(&lfs, &rbyd,
|
||||
// LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
|
||||
// lfs_rbyd_commit(&lfs, &rbyd,
|
||||
// LFS_MKRATTR(GSTATE, 3, 0, &(uint32_t){0xcccccccc}, 4, NULL)) => 0;
|
||||
// lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block) => 0;
|
||||
|
||||
// TODO more?
|
||||
'''
|
||||
|
||||
[cases.rbyd_commit_lookup]
|
||||
@@ -126,16 +101,23 @@ code = '''
|
||||
|
||||
// try an empty commit
|
||||
lfs_rbyd_t rbyd = rbyd_init;
|
||||
lfs_rtag_t ntag; // TODO assert on ntag?
|
||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
|
||||
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
// TODO test in-between lookups for consistently finding the next >= tag?
|
||||
lfs_off_t off;
|
||||
lfs_size_t size;
|
||||
lfs_rtag_t ntag;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
// commit with one attribute
|
||||
rbyd = rbyd_init;
|
||||
@@ -143,18 +125,28 @@ code = '''
|
||||
lfs_rbyd_commit(&lfs, &rbyd,
|
||||
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
// commit with two attributes
|
||||
rbyd = rbyd_init;
|
||||
@@ -164,36 +156,36 @@ code = '''
|
||||
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||
NULL))) => 0;
|
||||
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 3, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 3, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
|
||||
// // commit with three attributes
|
||||
// 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) => 0;
|
||||
|
||||
// TODO more?
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
'''
|
||||
|
||||
# TODO we should make sure lookup always returns <= the requested tag,
|
||||
@@ -218,16 +210,22 @@ code = '''
|
||||
|
||||
// try an empty commit
|
||||
lfs_rbyd_t rbyd = rbyd_init;
|
||||
lfs_rtag_t ntag; // TODO assert on ntag?
|
||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
|
||||
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_off_t off;
|
||||
lfs_size_t size;
|
||||
lfs_rtag_t ntag;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
// commit with one attribute
|
||||
rbyd = rbyd_init;
|
||||
@@ -235,18 +233,28 @@ code = '''
|
||||
lfs_rbyd_commit(&lfs, &rbyd,
|
||||
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 2, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
// commit with two attributes
|
||||
rbyd = rbyd_init;
|
||||
@@ -256,39 +264,107 @@ code = '''
|
||||
lfs_rbyd_commit(&lfs, &rbyd,
|
||||
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
|
||||
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 3, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 1, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 2, 0), &(lfs_off_t){0}, &ntag) => 4;
|
||||
assert(ntag == 0);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd,
|
||||
LFS_MKRTAG(GSTATE, 3, 0), &(lfs_off_t){0}, &ntag) => LFS_ERR_NOENT;
|
||||
|
||||
// // commit with three attributes
|
||||
// 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) => 0;
|
||||
|
||||
// TODO more?
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0, &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//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);
|
||||
assert(size == 4);
|
||||
//assert(ntag == LFS_ERR_NOENT);
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 3, 0), &off, &size, &ntag)
|
||||
=> LFS_ERR_NOENT;
|
||||
'''
|
||||
|
||||
# [cases.rbyd_commit_fetchmatch]
|
||||
# [cases.rbyd_multi_commit_fetchmatch]
|
||||
# [cases.rbyd_commit_traverse]
|
||||
# [cases.rbyd_multi_commit_traverse]
|
||||
|
||||
[cases.rbyd_leaves]
|
||||
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,
|
||||
};
|
||||
|
||||
// create a split in the leaves
|
||||
// <r
|
||||
// => /|
|
||||
// 1 1 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, NULL))) => 0;
|
||||
|
||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||
lfs_off_t off;
|
||||
lfs_size_t size;
|
||||
lfs_rtag_t ntag;
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, LFS_MKRTAG(GSTATE, 1, 0), &off, &size, &ntag)
|
||||
=> LFS_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0x98, &off, &size, &ntag)
|
||||
=> 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
|
||||
// >r
|
||||
// => /|
|
||||
// 2 2 1
|
||||
rbyd = rbyd_init;
|
||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||
lfs_rbyd_commit(&lfs, &rbyd,
|
||||
LFS_MKRATTR(GSTATE, 2, 0, &(uint32_t){0xbbbbbbbb}, 4,
|
||||
LFS_MKRATTR(GSTATE, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, 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_MKRTAG(GSTATE, 1, 0);
|
||||
assert(size == 4);
|
||||
//assert(ntag == LFS_MKRTAG(GSTATE, 2, 0));
|
||||
lfs_rbyd_lookup(&lfs, &rbyd, 0x98, &off, &size, &ntag)
|
||||
=> 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);
|
||||
'''
|
||||
|
||||
|
||||
Reference in New Issue
Block a user