diff --git a/lfs.c b/lfs.c index 7c7e37ff..fefc7b74 100644 --- a/lfs.c +++ b/lfs.c @@ -2827,6 +2827,41 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd, } } + // if we diverged, paint alts black, this isn't perfect but + // otherwise we run into recoloring issues + if (lfsr_tag_hasdiverged(tag_)) { + alt &= ~LFSR_TAG_R; + + // prune diverged? + if (lfsr_tag_isdivergedupper(tag_) + ^ lfsr_tag_isgt(alt) + ^ lfsr_tag_follow2( + alt, weight, + p_alts[0], p_weights[0], + lower_rid, upper_rid, + rid_, tag_)) { + if (lfsr_tag_follow2( + alt, weight, + p_alts[0], p_weights[0], + lower_rid, upper_rid, + rid_, tag_)) { + lfsr_tag_flip2( + &alt, &weight, + p_alts[0], p_weights[0], + lower_rid, upper_rid); + lfs_swap32(&jump, &branch_); + } + lfsr_tag_trim( + alt, weight, + &lower_rid, &upper_rid, + &lower_tag, &upper_tag); + + graft = branch; + branch = branch_; + continue; + } + } + // prune? // b // .-'| .-'| @@ -2838,62 +2873,20 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd, // | | .----'| | .----'| | // 1 2 3 4 4 1 2 3 4 4 2 if (lfsr_tag_prune2( - alt, weight, - p_alts[0], p_weights[0], - lower_rid, upper_rid, - lower_tag, upper_tag) - // prune because of diverged paths? - || (lfsr_tag_hasdiverged(tag_) - && lfsr_tag_isdivergedupper(tag_) - ^ lfsr_tag_isgt(alt) - ^ lfsr_tag_follow2( - alt, weight, - p_alts[0], p_weights[0], - lower_rid, upper_rid, - rid_, tag_))) { - // note yellow prunes always follow and have no weight, it's - // only the diverged paths that need all these special cases - if (lfsr_tag_follow2( - alt, weight, - p_alts[0], p_weights[0], - lower_rid, upper_rid, - rid_, tag_)) { - lfsr_tag_flip2( - &alt, &weight, - p_alts[0], p_weights[0], - lower_rid, upper_rid); - lfsr_tag_trim( - alt, weight, - &lower_rid, &upper_rid, - &lower_tag, &upper_tag); - - if (lfsr_tag_isred(p_alts[0])) { - alt = p_alts[0] & ~LFSR_TAG_R; - weight = p_weights[0]; - branch_ = jump; - jump = p_jumps[0]; - lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps); - } else { - graft = branch; - branch = jump; - continue; - } + alt, weight, + p_alts[0], p_weights[0], + lower_rid, upper_rid, + lower_tag, upper_tag)) { + if (lfsr_tag_isred(p_alts[0])) { + alt = p_alts[0] & ~LFSR_TAG_R; + weight = p_weights[0]; + branch_ = jump; + jump = p_jumps[0]; + lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps); } else { - lfsr_tag_trim( - alt, weight, - &lower_rid, &upper_rid, - &lower_tag, &upper_tag); - - if (lfsr_tag_isred(p_alts[0])) { - alt = p_alts[0] & ~LFSR_TAG_R; - weight = p_weights[0]; - jump = p_jumps[0]; - lfsr_rbyd_p_pop(p_alts, p_weights, p_jumps); - } else { - graft = branch; - branch = branch_; - continue; - } + graft = branch; + branch = jump; + continue; } } @@ -2998,18 +2991,20 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd, } if (lfsr_tag_isblack(alt)) { - // trim alt from our current bounds + // trim alts from our current bounds lfsr_tag_trim2( alt, weight, p_alts[0], p_weights[0], &lower_rid, &upper_rid, &lower_tag, &upper_tag); - // if diverged, stitch our paths together with alternating - // red alts + // if we diverged, stitch our paths together with alternating + // red alts, this gives us an optimal ternary tree if we + // started with a binary tree, but the above recoloring makes + // this not optimal if (lfsr_tag_hasdiverged(tag_) && p_alts[0] - && !lfsr_tag_isred(p_alts[1])) { + && lfsr_tag_isblack(p_alts[1])) { p_alts[0] |= LFSR_TAG_R; } } @@ -3042,7 +3037,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd, } // switch to the other path if we have diverged - if (lfsr_tag_hasdiverged(tag_) && lfsr_tag_isblack(p_alts[0])) { + if (lfsr_tag_hasdiverged(tag_)) { lfs_swap16(&tag_, &other_tag_); lfs_sswap32(&rid_, &other_rid_); lfs_swap32(&branch, &other_branch); diff --git a/tests/test_rbyd.toml b/tests/test_rbyd.toml index 0555def8..4cacb412 100644 --- a/tests/test_rbyd.toml +++ b/tests/test_rbyd.toml @@ -7350,6 +7350,1289 @@ code = ''' &data) => LFS_ERR_NOENT; ''' +# some additional delete range special cases +[cases.test_rbyd_delete_range_b] +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfs_init(&lfs, CFG) => 0; + + lfsr_rbyd_t init_rbyd = { + .blocks[0] = 0, + .eoff = 0, + .cksum = 0, + .trunk = 0, + .weight = 0, + }; + lfsr_rbyd_t rbyd; + lfsr_data_t data; + uint8_t buffer[4]; + + // delete inner branches + // + // .-------o-------. + // .---o---. .---o---. + // .-o-. .-o-. .-o-. .-o-. + // .o. .o. .o. .o. .o. .o. .o. .o. + // a a a a a a a c c e e e e e e e + // '-+-' + // remove + // + rbyd = init_rbyd; + lfsr_bd_erase(&lfs, rbyd.blocks[0]) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xaa\xaa\xaa\xaa", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(3), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xcc\xcc", 2)), + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xee\xee\xee\xee", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(3), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + // propagate yellow to the root + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)))) => 0; + + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR(LFSR_TAG_RM, -1, LFSR_DATA_NULL()))) => 0; + + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + // try to recreate + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)))) => 0; + + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; +''' + +[cases.test_rbyd_delete_range_r] +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfs_init(&lfs, CFG) => 0; + + lfsr_rbyd_t init_rbyd = { + .blocks[0] = 0, + .eoff = 0, + .cksum = 0, + .trunk = 0, + .weight = 0, + }; + lfsr_rbyd_t rbyd; + lfsr_data_t data; + uint8_t buffer[4]; + + // delete inner branches + // + // .-------o-------. + // .---r----. .----r---. + // .o. .o. .-r-. .-r-. .o. .o. + // a a a a a a c c e e e e e e + // '-+-' + // remove + // + rbyd = init_rbyd; + lfsr_bd_erase(&lfs, rbyd.blocks[0]) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xaa\xaa\xaa\xaa", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xcc\xcc", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(3), +1, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + // propagate yellow to the root + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xee\xee", 2)))) => 0; + // this gets a bit messy as we try to make the rbyd take the right shape + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(3), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)))) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 2, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_REG, 0, + LFSR_DATA_BUF("\xee\xee\xee\xee", 4)))) => 0; + + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR(LFSR_TAG_RM, -1, LFSR_DATA_NULL()))) => 0; + + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + // try to recreate + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)))) => 0; + + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; +''' + +[cases.test_rbyd_delete_range_y] +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfs_init(&lfs, CFG) => 0; + + lfsr_rbyd_t init_rbyd = { + .blocks[0] = 0, + .eoff = 0, + .cksum = 0, + .trunk = 0, + .weight = 0, + }; + lfsr_rbyd_t rbyd; + lfsr_data_t data; + uint8_t buffer[4]; + + // delete inner branches + // + // .-------------o-------------. + // .---y---+------. .------+---y---. + // .o. .o. .o. .-+-y-. .-y-+-. .o. .o. .o. + // a a a a a a a a a c c e e e e e e e e e + // '-+-' + // remove + // + rbyd = init_rbyd; + lfsr_bd_erase(&lfs, rbyd.blocks[0]) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xaa\xaa\xaa\xaa", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(3), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xcc\xcc", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), +1, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + // propagate yellow to the root + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)))) => 0; + // this gets a bit messy as we try to make the rbyd take the right shape + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(7), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(8), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)))) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + // propagate yellow + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)))) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 2, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(3), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_REG, 0, + LFSR_DATA_BUF("\xee\xee\xee\xee", 4)))) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 2, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(8), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(7), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + // propagate yellow + LFSR_ATTR( + LFSR_TAG_UATTR(7), 0, + LFSR_DATA_BUF("\xee\xee", 2)))) => 0; + + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR(LFSR_TAG_RM, -1, LFSR_DATA_NULL()))) => 0; + + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + // try to recreate + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)))) => 0; + + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; +''' + +[cases.test_rbyd_delete_range_ryy] +in = 'lfs.c' +code = ''' + lfs_t lfs; + lfs_init(&lfs, CFG) => 0; + + lfsr_rbyd_t init_rbyd = { + .blocks[0] = 0, + .eoff = 0, + .cksum = 0, + .trunk = 0, + .weight = 0, + }; + lfsr_rbyd_t rbyd; + lfsr_data_t data; + uint8_t buffer[4]; + + // delete inner branches + // + // .-------------r-------------. + // .-o-. .----y---+---. .-o-. + // .o. .o. .-+-y-. .o. .o. .o. .o. .o. + // a a a a a a a c e e e e e e e e e e + // '+' + // remove + // + // this is a specific nasty case that can happen if you try to + // preserve coloring during range removes + // + rbyd = init_rbyd; + lfsr_bd_erase(&lfs, rbyd.blocks[0]) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xaa\xaa\xaa\xaa", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(3), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)), + LFSR_ATTR( + LFSR_TAG_UATTR(4), +1, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(7), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(8), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(9), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + // propagate yellow to the root + LFSR_ATTR( + LFSR_TAG_UATTR(9), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(9), 0, + LFSR_DATA_BUF("\xee\xee", 2)))) => 0; + // this gets a bit messy as we try to make the rbyd take the right shape + lfsr_rbyd_commit(&lfs, &rbyd, 0, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(5), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(6), 0, + LFSR_DATA_BUF("\xaa\xaa", 2)))) => 0; + lfsr_rbyd_commit(&lfs, &rbyd, 2, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_UATTR(3), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(2), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_UATTR(1), 0, + LFSR_DATA_BUF("\xee\xee", 2)), + LFSR_ATTR( + LFSR_TAG_REG, 0, + LFSR_DATA_BUF("\xee\xee\xee\xee", 4)), + // propagate yellow + LFSR_ATTR( + LFSR_TAG_REG, 0, + LFSR_DATA_BUF("\xee\xee\xee\xee", 4)))) => 0; + + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR(LFSR_TAG_RM, -1, LFSR_DATA_NULL()))) => 0; + + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(9), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 2); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_UATTR(9), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + // try to recreate + lfsr_rbyd_commit(&lfs, &rbyd, 1, LFSR_ATTRS( + LFSR_ATTR( + LFSR_TAG_REG, +1, + LFSR_DATA_BUF("\xcc\xcc\xcc\xcc", 4)))) => 0; + + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(9), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; + + lfsr_rbyd_fetch(&lfs, &rbyd, rbyd.blocks[0], 0) => 0; + assert(rbyd.weight == 3); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xaa\xaa\xaa\xaa", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 0, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xaa\xaa", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 1, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xcc\xcc\xcc\xcc", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_REG, &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 4; + assert(memcmp(buffer, "\xee\xee\xee\xee", 4) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(1), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(2), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(3), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(4), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(5), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(6), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(7), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(8), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 2, LFSR_TAG_UATTR(9), &data) => 0; + lfsr_data_read(&lfs, &data, buffer, 4) => 2; + assert(memcmp(buffer, "\xee\xee", 2) == 0); + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_REG, + &data) => LFS_ERR_NOENT; + lfsr_rbyd_lookup(&lfs, &rbyd, 3, LFSR_TAG_UATTR(1), + &data) => LFS_ERR_NOENT; +''' + # NOTE if we separate physical/logical block sizes we may be able to # use emubd's copy-on-write copy to speed this up significantly [cases.test_rbyd_delete_permutations]