This method of leaf splitting works, but I want to explore another option
Committing current progress.
This commit is contained in:
@@ -575,9 +575,10 @@ static inline lfs_rtag_t lfs_rtag_isparallel(lfs_rtag_t a, lfs_rtag_t b) {
|
|||||||
return (a & 0x2) == (b & 0x2);
|
return (a & 0x2) == (b & 0x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_srtag_t lfs_rtag_weight(lfs_rtag_t tag) {
|
// TODO rm
|
||||||
return tag >> 3;
|
//static inline lfs_srtag_t lfs_rtag_weight(lfs_rtag_t tag) {
|
||||||
}
|
// return tag >> 3;
|
||||||
|
//}
|
||||||
|
|
||||||
static inline lfs_rtag_t lfs_rtag_weight_(lfs_rtag_t tag) {
|
static inline lfs_rtag_t lfs_rtag_weight_(lfs_rtag_t tag) {
|
||||||
return tag & ~0x7;
|
return tag & ~0x7;
|
||||||
@@ -587,23 +588,23 @@ static inline lfs_rtag_t lfs_rtag_merge(lfs_rtag_t a, lfs_rtag_t b) {
|
|||||||
return a + (b & ~0x7);
|
return a + (b & ~0x7);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_srtag_t lfs_rtag_weight_lt(lfs_rtag_t tag, uint16_t count) {
|
//static inline lfs_srtag_t lfs_rtag_weight_lt(lfs_rtag_t tag, uint16_t count) {
|
||||||
(void)count;
|
// (void)count;
|
||||||
return lfs_rtag_weight(tag);
|
// return lfs_rtag_weight(tag);
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
|
//static inline lfs_srtag_t lfs_rtag_weight_gt(lfs_rtag_t tag, uint16_t count) {
|
||||||
|
// return (((lfs_srtag_t)count) << 12)-1 - lfs_rtag_weight(tag);
|
||||||
|
//}
|
||||||
|
|
||||||
static inline lfs_srtag_t lfs_rtag_weight_gt(lfs_rtag_t tag, uint16_t count) {
|
//static inline bool lfs_rtag_follow(lfs_rtag_t alt,
|
||||||
return (((lfs_srtag_t)count) << 12)-1 - lfs_rtag_weight(tag);
|
// lfs_srtag_t lt, lfs_srtag_t gt) {
|
||||||
}
|
// if (lfs_rtag_islt(alt)) {
|
||||||
|
// return lfs_rtag_weight(alt) > lt;
|
||||||
static inline bool lfs_rtag_follow(lfs_rtag_t alt,
|
// } else {
|
||||||
lfs_srtag_t lt, lfs_srtag_t gt) {
|
// return lfs_rtag_weight(alt) > gt;
|
||||||
if (lfs_rtag_islt(alt)) {
|
// }
|
||||||
return lfs_rtag_weight(alt) > lt;
|
//}
|
||||||
} else {
|
|
||||||
return lfs_rtag_weight(alt) > gt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool lfs_rtag_follow_(lfs_rtag_t alt,
|
static inline bool lfs_rtag_follow_(lfs_rtag_t alt,
|
||||||
lfs_rtag_t lower, lfs_rtag_t upper, lfs_rtag_t tag) {
|
lfs_rtag_t lower, lfs_rtag_t upper, lfs_rtag_t tag) {
|
||||||
@@ -615,13 +616,13 @@ static inline bool lfs_rtag_follow_(lfs_rtag_t alt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline lfs_rtag_t lfs_rtag_flip(
|
//static inline lfs_rtag_t lfs_rtag_flip(
|
||||||
lfs_rtag_t alt, lfs_rtag_t lt, lfs_rtag_t gt) {
|
// lfs_rtag_t alt, lfs_rtag_t lt, lfs_rtag_t gt) {
|
||||||
return LFS_MKRALT_(
|
// return LFS_MKRALT_(
|
||||||
lfs_rtag_isred(alt),
|
// lfs_rtag_isred(alt),
|
||||||
!lfs_rtag_isgt(alt),
|
// !lfs_rtag_isgt(alt),
|
||||||
(lt+gt+1) - lfs_rtag_weight(alt));
|
// (lt+gt+1) - lfs_rtag_weight(alt));
|
||||||
}
|
//}
|
||||||
|
|
||||||
static inline lfs_rtag_t lfs_rtag_flip_(lfs_rtag_t alt,
|
static inline lfs_rtag_t lfs_rtag_flip_(lfs_rtag_t alt,
|
||||||
lfs_rtag_t lower, lfs_rtag_t upper) {
|
lfs_rtag_t lower, lfs_rtag_t upper) {
|
||||||
@@ -631,14 +632,14 @@ static inline lfs_rtag_t lfs_rtag_flip_(lfs_rtag_t alt,
|
|||||||
(upper-lower) - lfs_rtag_weight_(alt));
|
(upper-lower) - lfs_rtag_weight_(alt));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lfs_rtag_trim(lfs_rtag_t alt,
|
//static inline void lfs_rtag_trim(lfs_rtag_t alt,
|
||||||
lfs_srtag_t *lt, lfs_srtag_t *gt) {
|
// lfs_srtag_t *lt, lfs_srtag_t *gt) {
|
||||||
if (lfs_rtag_islt(alt)) {
|
// if (lfs_rtag_islt(alt)) {
|
||||||
*lt = *lt - lfs_rtag_weight(alt);
|
// *lt = *lt - lfs_rtag_weight(alt);
|
||||||
} else {
|
// } else {
|
||||||
*gt = *gt - lfs_rtag_weight(alt);
|
// *gt = *gt - lfs_rtag_weight(alt);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
static inline void lfs_rtag_trim_(lfs_rtag_t alt,
|
static inline void lfs_rtag_trim_(lfs_rtag_t alt,
|
||||||
lfs_rtag_t *lower, lfs_rtag_t *upper) {
|
lfs_rtag_t *lower, lfs_rtag_t *upper) {
|
||||||
@@ -649,14 +650,14 @@ static inline void lfs_rtag_trim_(lfs_rtag_t alt,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lfs_rtag_untrim(lfs_rtag_t alt,
|
//static inline void lfs_rtag_untrim(lfs_rtag_t alt,
|
||||||
lfs_srtag_t *lt, lfs_srtag_t *gt) {
|
// lfs_srtag_t *lt, lfs_srtag_t *gt) {
|
||||||
if (lfs_rtag_islt(alt)) {
|
// if (lfs_rtag_islt(alt)) {
|
||||||
*lt = *lt + lfs_rtag_weight(alt);
|
// *lt = *lt + lfs_rtag_weight(alt);
|
||||||
} else {
|
// } else {
|
||||||
*gt = *gt + lfs_rtag_weight(alt);
|
// *gt = *gt + lfs_rtag_weight(alt);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
static inline void lfs_rtag_untrim_(lfs_rtag_t alt,
|
static inline void lfs_rtag_untrim_(lfs_rtag_t alt,
|
||||||
lfs_rtag_t *lower, lfs_rtag_t *upper) {
|
lfs_rtag_t *lower, lfs_rtag_t *upper) {
|
||||||
@@ -1035,12 +1036,11 @@ static lfs_ssize_t lfs_rbyd_readtag(lfs_t *lfs,
|
|||||||
*tag = 0;
|
*tag = 0;
|
||||||
|
|
||||||
// read a pair of leb128s
|
// read a pair of leb128s
|
||||||
uint8_t buffer[2*4];
|
//
|
||||||
|
// note we force leb decoding to overflow when truncated
|
||||||
|
uint8_t buffer[2*4] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||||
lfs_size_t i = 0;
|
lfs_size_t i = 0;
|
||||||
|
|
||||||
// force leb decoding to overflow when truncated
|
|
||||||
memset(buffer, 0xff, 2*4);
|
|
||||||
|
|
||||||
// TODO allow different hint for lookup? bench this? does our hint work backwards?
|
// TODO allow different hint for lookup? bench this? does our hint work backwards?
|
||||||
// TODO should lfs_bd_read allow a range for reads?
|
// TODO should lfs_bd_read allow a range for reads?
|
||||||
int err = lfs_bd_read(lfs,
|
int err = lfs_bd_read(lfs,
|
||||||
@@ -1388,6 +1388,7 @@ static int lfs_rbyd_prog(lfs_t *lfs, lfs_rbyd_t *rbyd_,
|
|||||||
static int lfs_rbyd_progtag(lfs_t *lfs, lfs_rbyd_t *rbyd_,
|
static int lfs_rbyd_progtag(lfs_t *lfs, lfs_rbyd_t *rbyd_,
|
||||||
lfs_rtag_t tag, lfs_size_t size, uint32_t *crc) {
|
lfs_rtag_t tag, lfs_size_t size, uint32_t *crc) {
|
||||||
// convert to on-disk repr
|
// convert to on-disk repr
|
||||||
|
LFS_ASSERT(lfs_rtag_isvalid(tag));
|
||||||
tag <<= 1;
|
tag <<= 1;
|
||||||
|
|
||||||
// make sure to include the parity of the current crc
|
// make sure to include the parity of the current crc
|
||||||
@@ -1770,125 +1771,62 @@ stem:;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// split leaf nodes?
|
// split leaf nodes?
|
||||||
lfs_rtag_t alt;
|
//
|
||||||
if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE) {
|
// note we bias the weights here so that lfs_rbyd_lookup
|
||||||
// TODO why are both paths never taken??
|
// always finds the next biggest tag
|
||||||
if (lfs_rtag_weight_(lower_tag_)
|
lfs_rtag_t alt = 0;
|
||||||
< lfs_rtag_weight_(tag & ~0x7fff)) {
|
lfs_off_t jump = 0;
|
||||||
alt = LFS_MKRALT__(B, LT,
|
|
||||||
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
|
||||||
|
|
||||||
// TODO can we rededuplicate this?
|
if (lfs_rtag_isrm(lower_tag_)) {
|
||||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
// no split needed, prune the removed tag
|
||||||
p_alts, p_jumps,
|
|
||||||
alt, lower_branch);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE
|
||||||
} else
|
&& lfs_rtag_weight_(upper_tag_) >= lfs_rtag_weight_(tag & ~0x7fff)) {
|
||||||
|
// increase biased weight when creating
|
||||||
|
alt = LFS_MKRALT__(B, GT,
|
||||||
|
(upper_upper+0x8000) - (lfs_rtag_weight_(tag)+0x8));
|
||||||
|
jump = upper_branch;
|
||||||
|
|
||||||
if (lfs_rtag_weight_(upper_tag_)
|
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_DELETE
|
||||||
>= lfs_rtag_weight_(tag & ~0x7fff)+0x8000) {
|
&& lfs_rtag_weight_(upper_tag_) >= lfs_rtag_weight_(tag & ~0x7fff)+0x8000) {
|
||||||
alt = LFS_MKRALT__(B, GT,
|
// decrease biased weight when deleting
|
||||||
upper_upper - (lfs_rtag_weight_(lower_tag_)+0x8));
|
alt = LFS_MKRALT__(B, GT,
|
||||||
|
upper_upper-0x8000 - lower_lower);
|
||||||
|
jump = upper_branch;
|
||||||
|
|
||||||
// TODO can we rededuplicate this?
|
} else if (lfs_rtag_type1(tag) != LFS_TYPE1_DELETE
|
||||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
&& lfs_rtag_isrm(tag)
|
||||||
p_alts, p_jumps,
|
&& lfs_rtag_weight_(upper_tag_) > lfs_rtag_weight_(tag)) {
|
||||||
alt, upper_branch);
|
// hide our tag during removes
|
||||||
if (err) {
|
alt = LFS_MKRALT__(B, GT,
|
||||||
return err;
|
upper_upper - lower_lower);
|
||||||
}
|
jump = upper_branch;
|
||||||
|
|
||||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
} else if (!lfs_rtag_isrm(tag)
|
||||||
|
&& lfs_rtag_weight_(upper_tag_) > lfs_rtag_weight_(tag)) {
|
||||||
|
// split greater than
|
||||||
|
alt = LFS_MKRALT__(B, GT,
|
||||||
|
upper_upper - (lfs_rtag_weight_(tag)+0x8));
|
||||||
|
jump = upper_branch;
|
||||||
|
|
||||||
|
} else if (lfs_rtag_weight_(lower_tag_) < lfs_rtag_weight_(tag)) {
|
||||||
|
// split less than, this is consistent for all appends and only happens
|
||||||
|
// when appending to the end of the tree
|
||||||
|
alt = LFS_MKRALT__(B, LT,
|
||||||
|
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
||||||
|
jump = lower_branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alt) {
|
||||||
|
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
||||||
|
p_alts, p_jumps,
|
||||||
|
alt, jump);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
} else if (lfs_rtag_isrm(tag)) {
|
|
||||||
// TODO why are both paths never taken??
|
|
||||||
if (lfs_rtag_weight_(lower_tag_)
|
|
||||||
< lfs_rtag_weight_(tag & ~0x1)) {
|
|
||||||
alt = LFS_MKRALT__(B, LT,
|
|
||||||
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
|
||||||
|
|
||||||
// TODO can we rededuplicate this?
|
|
||||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
|
||||||
p_alts, p_jumps,
|
|
||||||
alt, lower_branch);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// lfs_rbyd_p_red(p_alts, p_jumps); these should not be here
|
|
||||||
} else
|
|
||||||
|
|
||||||
if (lfs_rtag_weight_(upper_tag_)
|
|
||||||
>= lfs_rtag_weight_(tag & ~0x1)+0x8) {
|
|
||||||
// remove found a tag
|
|
||||||
if (lfs_rtag_weight(lower_tag_) == lfs_rtag_weight(tag)) {
|
|
||||||
alt = LFS_MKRALT__(B, GT,
|
|
||||||
upper_upper - (lfs_rtag_weight_(lower_tag_)+0x8)+0x8);
|
|
||||||
// remove found no tag?
|
|
||||||
} else {
|
|
||||||
alt = LFS_MKRALT__(B, GT,
|
|
||||||
upper_upper - lower_lower);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO can we rededuplicate this?
|
|
||||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
|
||||||
p_alts, p_jumps,
|
|
||||||
alt, upper_branch);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (lfs_rtag_type1(tag) == LFS_TYPE1_CREATE) {
|
|
||||||
// inserting a new id?
|
|
||||||
LFS_ASSERT(!diverged);
|
|
||||||
// TODO rm should probably be handled generally
|
|
||||||
if (!lfs_rtag_isrm(lower_tag_)) {
|
|
||||||
// note we bias the weights here so that lfs_rbyd_lookup
|
|
||||||
// always finds the next biggest tag
|
|
||||||
if (lfs_rtag_weight(lower_tag_)
|
|
||||||
< lfs_rtag_weight(tag & ~0x7fff)) {
|
|
||||||
alt = LFS_MKRALT__(B, LT,
|
|
||||||
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
|
||||||
} else {
|
|
||||||
alt = LFS_MKRALT__(B, GT,
|
|
||||||
(lower_upper+0x8000) - (lfs_rtag_weight_(tag)+0x8));
|
|
||||||
}
|
|
||||||
|
|
||||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
|
||||||
p_alts, p_jumps,
|
|
||||||
alt, lower_branch);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
lfs_rbyd_p_red(p_alts, p_jumps);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LFS_ASSERT(!diverged);
|
|
||||||
// TODO use weights here?
|
|
||||||
if (lfs_rtag_weight_(lower_tag_) != lfs_rtag_weight_(tag)
|
|
||||||
&& !lfs_rtag_isrm(lower_tag_)) {
|
|
||||||
// note we bias the weights here so that lfs_rbyd_lookup
|
|
||||||
// always finds the next biggest tag
|
|
||||||
if (lfs_rtag_weight_(lower_tag_) < lfs_rtag_weight_(tag)) {
|
|
||||||
alt = LFS_MKRALT__(B, LT,
|
|
||||||
(lfs_rtag_weight_(lower_tag_)+0x8) - lower_lower);
|
|
||||||
} else {
|
|
||||||
alt = LFS_MKRALT__(B, GT,
|
|
||||||
lower_upper - (lfs_rtag_weight_(tag)+0x8));
|
|
||||||
}
|
|
||||||
|
|
||||||
int err = lfs_rbyd_p_push(lfs, rbyd_,
|
|
||||||
p_alts, p_jumps,
|
|
||||||
alt, lower_branch);
|
|
||||||
if (err) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!lfs_rtag_isrm(tag)) {
|
||||||
|
// introduce a red edge
|
||||||
lfs_rbyd_p_red(p_alts, p_jumps);
|
lfs_rbyd_p_red(p_alts, p_jumps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+78
-38
@@ -1969,6 +1969,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRRMATTR(UATTR, j+1, 0, NULL)) => 0;
|
LFS_MKRRMATTR(UATTR, j+1, 0, NULL)) => 0;
|
||||||
@@ -2398,6 +2399,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
// remove each tag in permutation order
|
// remove each tag in permutation order
|
||||||
for (unsigned j = 0; j < N; j++) {
|
for (unsigned j = 0; j < N; j++) {
|
||||||
@@ -2529,6 +2531,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
// remove
|
// remove
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
@@ -3684,6 +3687,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(DELETE, 0, j+1, NULL, 0, NULL)) => 0;
|
LFS_MKRATTR(DELETE, 0, j+1, NULL, 0, NULL)) => 0;
|
||||||
@@ -3738,6 +3742,7 @@ code = '''
|
|||||||
|
|
||||||
[cases.test_rbyd_delete_range_permutations]
|
[cases.test_rbyd_delete_range_permutations]
|
||||||
defines.N = 'range(1, 7)'
|
defines.N = 'range(1, 7)'
|
||||||
|
defines.M = 'range(1, 4)'
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -3801,9 +3806,13 @@ code = '''
|
|||||||
|
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(CREATEREG, 0, id+1, names[perm[j] % 6], 4,
|
LFS_MKRATTR(CREATEREG, 0, id+1, names[perm[j] % 6], 4,
|
||||||
// note uattrs have a smaller size
|
NULL)) => 0;
|
||||||
LFS_MKRATTR(UATTR, 1, id+1, names[perm[j] % 6], 2,
|
// note uattrs have a smaller size to help debugging
|
||||||
NULL))) => 0;
|
for (unsigned u = 0; u < M; u++) {
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, u+1, id+1, names[perm[j] % 6], 2,
|
||||||
|
NULL)) => 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(rbyd.count == N);
|
assert(rbyd.count == N);
|
||||||
|
|
||||||
@@ -3822,6 +3831,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(DELETE, 0, j+1, NULL, 0, NULL)) => 0;
|
LFS_MKRATTR(DELETE, 0, j+1, NULL, 0, NULL)) => 0;
|
||||||
@@ -3837,12 +3847,14 @@ code = '''
|
|||||||
assert(memcmp(buffer, names[k % 6], 4) == 0);
|
assert(memcmp(buffer, names[k % 6], 4) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
lfs_rbyd_get(&lfs, &rbyd,
|
for (unsigned u = 0; u < M; u++) {
|
||||||
LFS_MKRTAG(UATTR, 1, k+1), buffer, 4) => 2;
|
lfs_rbyd_get(&lfs, &rbyd,
|
||||||
if (k >= j) {
|
LFS_MKRTAG(UATTR, u+1, k+1), buffer, 4) => 2;
|
||||||
assert(memcmp(buffer, names[(k+1) % 6], 2) == 0);
|
if (k >= j) {
|
||||||
} else {
|
assert(memcmp(buffer, names[(k+1) % 6], 2) == 0);
|
||||||
assert(memcmp(buffer, names[k % 6], 2) == 0);
|
} else {
|
||||||
|
assert(memcmp(buffer, names[k % 6], 2) == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lfs_rbyd_get(&lfs, &rbyd,
|
lfs_rbyd_get(&lfs, &rbyd,
|
||||||
@@ -3877,7 +3889,7 @@ code = '''
|
|||||||
|
|
||||||
// test that tree is self-balancing, we should be strictly bounded
|
// test that tree is self-balancing, we should be strictly bounded
|
||||||
// by height <= 2*log(n)+1, assume tags are roughly ~8 bytes
|
// by height <= 2*log(n)+1, assume tags are roughly ~8 bytes
|
||||||
lfs_size_t n = 1 + 2*N + 1;
|
lfs_size_t n = 1 + N+N*M + 1;
|
||||||
printf("worst size: %u B (N=%u, estimate=%u)\n",
|
printf("worst size: %u B (N=%u, estimate=%u)\n",
|
||||||
worst_size, n, 8*n*(2*lfs_nlog2(n)+1));
|
worst_size, n, 8*n*(2*lfs_nlog2(n)+1));
|
||||||
printf("avg height: %u B (N=%u, estimate=%u)\n",
|
printf("avg height: %u B (N=%u, estimate=%u)\n",
|
||||||
@@ -4200,6 +4212,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
// delete each id in permutation order
|
// delete each id in permutation order
|
||||||
for (unsigned j = 0; j < N; j++) {
|
for (unsigned j = 0; j < N; j++) {
|
||||||
@@ -4274,6 +4287,7 @@ code = '''
|
|||||||
|
|
||||||
[cases.test_rbyd_delete_all_range_permutations]
|
[cases.test_rbyd_delete_all_range_permutations]
|
||||||
defines.N = 'range(1, 7)'
|
defines.N = 'range(1, 7)'
|
||||||
|
defines.M = 'range(1, 4)'
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -4309,8 +4323,13 @@ code = '''
|
|||||||
for (unsigned j = 0; j < N; j++) {
|
for (unsigned j = 0; j < N; j++) {
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(CREATEREG, 0, j+1, names[j % 6], 4,
|
LFS_MKRATTR(CREATEREG, 0, j+1, names[j % 6], 4,
|
||||||
LFS_MKRATTR(UATTR, 1, j+1, names[j % 6], 2,
|
NULL)) => 0;
|
||||||
NULL))) => 0;
|
// note uattrs have a smaller size to help debugging
|
||||||
|
for (unsigned u = 0; u < M; u++) {
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, u+1, j+1, names[j % 6], 2,
|
||||||
|
NULL)) => 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(rbyd.count == N);
|
assert(rbyd.count == N);
|
||||||
|
|
||||||
@@ -4345,6 +4364,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
// delete each id in permutation order
|
// delete each id in permutation order
|
||||||
for (unsigned j = 0; j < N; j++) {
|
for (unsigned j = 0; j < N; j++) {
|
||||||
@@ -4372,8 +4392,12 @@ code = '''
|
|||||||
// try resuming from all tags being removed
|
// try resuming from all tags being removed
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(CREATEREG, 0, 1, "\xaa\xaa\xaa\xaa\xaa\xaa", 6,
|
LFS_MKRATTR(CREATEREG, 0, 1, "\xaa\xaa\xaa\xaa\xaa\xaa", 6,
|
||||||
LFS_MKRATTR(UATTR, 1, 1, "\xaa\xaa\xaa", 3,
|
NULL)) => 0;
|
||||||
NULL))) => 0;
|
for (unsigned u = 0; u < M; u++) {
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, u+1, 1, "\xaa\xaa\xaa", 3,
|
||||||
|
NULL)) => 0;
|
||||||
|
}
|
||||||
assert(rbyd.count == 1);
|
assert(rbyd.count == 1);
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
@@ -4382,10 +4406,12 @@ code = '''
|
|||||||
LFS_MKRTAG(CREATEREG, 0, 1), buffer, 6)
|
LFS_MKRTAG(CREATEREG, 0, 1), buffer, 6)
|
||||||
=> 6;
|
=> 6;
|
||||||
assert(memcmp(buffer, "\xaa\xaa\xaa\xaa\xaa\xaa", 6) == 0);
|
assert(memcmp(buffer, "\xaa\xaa\xaa\xaa\xaa\xaa", 6) == 0);
|
||||||
lfs_rbyd_get(&lfs, &rbyd,
|
for (unsigned u = 0; u < M; u++) {
|
||||||
LFS_MKRTAG(UATTR, 1, 1), buffer, 6)
|
lfs_rbyd_get(&lfs, &rbyd,
|
||||||
=> 3;
|
LFS_MKRTAG(UATTR, u+1, 1), buffer, 6)
|
||||||
assert(memcmp(buffer, "\xaa\xaa\xaa", 3) == 0);
|
=> 3;
|
||||||
|
assert(memcmp(buffer, "\xaa\xaa\xaa", 3) == 0);
|
||||||
|
}
|
||||||
lfs_rbyd_get(&lfs, &rbyd,
|
lfs_rbyd_get(&lfs, &rbyd,
|
||||||
LFS_MKRTAG(CREATEREG, 0, 2), buffer, 6)
|
LFS_MKRTAG(CREATEREG, 0, 2), buffer, 6)
|
||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
@@ -4417,7 +4443,7 @@ code = '''
|
|||||||
|
|
||||||
// test that tree is self-balancing, we should be strictly bounded
|
// test that tree is self-balancing, we should be strictly bounded
|
||||||
// by height <= 2*log(n)+1, assume tags are roughly ~8 bytes
|
// by height <= 2*log(n)+1, assume tags are roughly ~8 bytes
|
||||||
lfs_size_t n = 1 + 2*N + N + 2;
|
lfs_size_t n = 1 + N+N*M + N + 1+M;
|
||||||
printf("worst size: %u B (N=%u, estimate=%u)\n",
|
printf("worst size: %u B (N=%u, estimate=%u)\n",
|
||||||
worst_size, n, 8*n*(2*lfs_nlog2(n)+1));
|
worst_size, n, 8*n*(2*lfs_nlog2(n)+1));
|
||||||
printf("avg height: %u B (N=%u, estimate=%u)\n",
|
printf("avg height: %u B (N=%u, estimate=%u)\n",
|
||||||
@@ -4510,6 +4536,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
// delete
|
// delete
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
@@ -4580,6 +4607,7 @@ code = '''
|
|||||||
|
|
||||||
[cases.test_rbyd_delete_create_range_permutations]
|
[cases.test_rbyd_delete_create_range_permutations]
|
||||||
defines.N = 'range(1, 6)'
|
defines.N = 'range(1, 6)'
|
||||||
|
defines.M = 'range(1, 4)'
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
lfs_t lfs;
|
lfs_t lfs;
|
||||||
@@ -4643,8 +4671,13 @@ code = '''
|
|||||||
|
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(CREATEREG, 0, id+1, names[perm[j] % 6], 4,
|
LFS_MKRATTR(CREATEREG, 0, id+1, names[perm[j] % 6], 4,
|
||||||
LFS_MKRATTR(UATTR, 1, id+1, names[perm[j] % 6], 2,
|
NULL)) => 0;
|
||||||
NULL))) => 0;
|
// note uattrs have a smaller size to help debugging
|
||||||
|
for (unsigned u = 0; u < M; u++) {
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, u+1, id+1, names[perm[j] % 6], 2,
|
||||||
|
NULL)) => 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
assert(rbyd.count == N);
|
assert(rbyd.count == N);
|
||||||
|
|
||||||
@@ -4664,6 +4697,7 @@ code = '''
|
|||||||
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
lfs_bd_prog(&lfs, &lfs.pcache, &lfs.rcache, false,
|
||||||
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
rbyd.block, 0, backup_block, rbyd.off) => 0;
|
||||||
|
lfs_bd_flush(&lfs, &lfs.pcache, &lfs.rcache, false) => 0;
|
||||||
|
|
||||||
// delete
|
// delete
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
@@ -4675,8 +4709,12 @@ code = '''
|
|||||||
// is still usable
|
// is still usable
|
||||||
lfs_rbyd_commit(&lfs, &rbyd,
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
LFS_MKRATTR(CREATEREG, 0, l+1, names[l % 6], 6,
|
LFS_MKRATTR(CREATEREG, 0, l+1, names[l % 6], 6,
|
||||||
LFS_MKRATTR(UATTR, 1, l+1, names[l % 6], 3,
|
NULL)) => 0;
|
||||||
NULL))) => 0;
|
for (unsigned u = 0; u < M; u++) {
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, u+1, l+1, names[l % 6], 3,
|
||||||
|
NULL)) => 0;
|
||||||
|
}
|
||||||
assert(rbyd.count == N);
|
assert(rbyd.count == N);
|
||||||
|
|
||||||
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
@@ -4698,21 +4736,23 @@ code = '''
|
|||||||
assert(memcmp(buffer, names[expected % 6], 4) == 0);
|
assert(memcmp(buffer, names[expected % 6], 4) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size = lfs_rbyd_get(&lfs, &rbyd,
|
for (unsigned u = 0; u < M; u++) {
|
||||||
LFS_MKRTAG(UATTR, 1, k+1), buffer, 6);
|
size = lfs_rbyd_get(&lfs, &rbyd,
|
||||||
if (k == l) {
|
LFS_MKRTAG(UATTR, u+1, k+1), buffer, 6);
|
||||||
assert(size == 3);
|
if (k == l) {
|
||||||
assert(memcmp(buffer, names[l % 6], 3) == 0);
|
assert(size == 3);
|
||||||
} else {
|
assert(memcmp(buffer, names[l % 6], 3) == 0);
|
||||||
uint16_t expected = k;
|
} else {
|
||||||
if (expected > l) {
|
uint16_t expected = k;
|
||||||
expected -= 1;
|
if (expected > l) {
|
||||||
|
expected -= 1;
|
||||||
|
}
|
||||||
|
if (expected >= j) {
|
||||||
|
expected += 1;
|
||||||
|
}
|
||||||
|
assert(size == 2);
|
||||||
|
assert(memcmp(buffer, names[expected % 6], 2) == 0);
|
||||||
}
|
}
|
||||||
if (expected >= j) {
|
|
||||||
expected += 1;
|
|
||||||
}
|
|
||||||
assert(size == 2);
|
|
||||||
assert(memcmp(buffer, names[expected % 6], 2) == 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4742,7 +4782,7 @@ code = '''
|
|||||||
|
|
||||||
// test that tree is self-balancing, we should be strictly bounded
|
// test that tree is self-balancing, we should be strictly bounded
|
||||||
// by height <= 2*log(n)+1, assume tags are roughly ~8 bytes
|
// by height <= 2*log(n)+1, assume tags are roughly ~8 bytes
|
||||||
lfs_size_t n = 1 + N + 1 + 2;
|
lfs_size_t n = 1 + N+N*M + 2 + 1+M;
|
||||||
printf("worst size: %u B (N=%u, estimate=%u)\n",
|
printf("worst size: %u B (N=%u, estimate=%u)\n",
|
||||||
worst_size, n, 8*n*(2*lfs_nlog2(n)+1));
|
worst_size, n, 8*n*(2*lfs_nlog2(n)+1));
|
||||||
printf("avg height: %u B (N=%u, estimate=%u)\n",
|
printf("avg height: %u B (N=%u, estimate=%u)\n",
|
||||||
|
|||||||
Reference in New Issue
Block a user