Attempting to add weight changes to every rbyd append
This does not work as is due to ambiguity with grows and insertions. Before, these were disambiguated by seperate grow and attr tags. You effectively grew the neighboring id before claiming its weight as yours. But now that the attr itself creates the grow/insertion, it's ambiguous which one is intended.
This commit is contained in:
@@ -449,7 +449,7 @@ static inline lfs_size_t lfs_tag_dsize(lfs_tag_t tag) {
|
|||||||
|
|
||||||
// 16-bit metadata tags
|
// 16-bit metadata tags
|
||||||
enum lfsr_tag_type {
|
enum lfsr_tag_type {
|
||||||
LFSR_TAG_UNREACHABLE = 0x0002,
|
LFSR_TAG_UNR = 0x0002,
|
||||||
|
|
||||||
LFSR_TAG_NAME = 0x1000,
|
LFSR_TAG_NAME = 0x1000,
|
||||||
LFSR_TAG_BNAME = 0x1000,
|
LFSR_TAG_BNAME = 0x1000,
|
||||||
@@ -475,9 +475,10 @@ enum lfsr_tag_type {
|
|||||||
LFSR_TAG_FCRC = 0x1004,
|
LFSR_TAG_FCRC = 0x1004,
|
||||||
|
|
||||||
// in-device only
|
// in-device only
|
||||||
LFSR_TAG_GROW = 0x0006,
|
LFSR_TAG_NOOP = 0x0006,
|
||||||
LFSR_TAG_SHRINK = 0x0016,
|
LFSR_TAG_GROW = 0x0016,
|
||||||
LFSR_TAG_FROM = 0x0026,
|
LFSR_TAG_SHRINK = 0x0026,
|
||||||
|
LFSR_TAG_FROM = 0x0036,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LFSR_TAG_ALT_(color, dir, key) \
|
#define LFSR_TAG_ALT_(color, dir, key) \
|
||||||
@@ -727,13 +728,60 @@ struct lfs_diskoff {
|
|||||||
struct lfsr_attr {
|
struct lfsr_attr {
|
||||||
lfsr_tag_t tag;
|
lfsr_tag_t tag;
|
||||||
lfs_ssize_t id;
|
lfs_ssize_t id;
|
||||||
|
lfs_ssize_t delta;
|
||||||
lfsr_data_t data;
|
lfsr_data_t data;
|
||||||
const struct lfsr_attr *next;
|
const struct lfsr_attr *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LFSD_ATTR_(_tag, _id, _delta, _buf, _len, _next) \
|
||||||
|
(&(const struct lfsr_attr){ \
|
||||||
|
_tag, _id, _delta, \
|
||||||
|
LFSR_DATA_BUF(_buf, _len), \
|
||||||
|
_next})
|
||||||
|
|
||||||
|
#define LFSD_ATTR(_type, _id, _delta, _buf, _len, _next) \
|
||||||
|
LFSD_ATTR_(LFSR_TAG_##_type, _id, _delta, _buf, _len, _next)
|
||||||
|
|
||||||
|
#define LFSD_ATTR_DISK_(_tag, _id, _delta, _block, _off, _len, _next) \
|
||||||
|
(&(const struct lfsr_attr){ \
|
||||||
|
_tag, _id, _delta, \
|
||||||
|
LFSR_DATA_DISK(_block, _off, _len), \
|
||||||
|
_next})
|
||||||
|
|
||||||
|
#define LFSD_ATTR_DISK(_type, _id, _delta, _block, _off, _len, _next) \
|
||||||
|
LFSD_ATTR_DISK_(LFSR_TAG_##_type, _id, _delta, _block, _off, _len, _next)
|
||||||
|
|
||||||
|
#define LFSD_ATTR_IF_(_pred, _tag, _id, _delta, _buf, _len, _next) \
|
||||||
|
LFSD_ATTR_( \
|
||||||
|
(_pred) ? (_tag) : LFSR_TAG_NOOP, \
|
||||||
|
_id, \
|
||||||
|
_delta, \
|
||||||
|
_buf, \
|
||||||
|
(_pred) ? (_len) : 0, \
|
||||||
|
_next)
|
||||||
|
|
||||||
|
#define LFSD_ATTR_IF(_pred, _type, _id, _delta, _buf, _len, _next) \
|
||||||
|
LFSD_ATTR_IF_(_pred, LFSR_TAG_##_type, _id, _delta, _buf, _len, _next)
|
||||||
|
|
||||||
|
#define LFSD_ATTR_DISK_IF_(_pred, \
|
||||||
|
_tag, _id, _delta, _block, _off, _len, _next) \
|
||||||
|
LFSD_ATTR_DISK_( \
|
||||||
|
(_pred) ? (_tag) : LFSD_TAG_NOOP, \
|
||||||
|
_id, \
|
||||||
|
_delta, \
|
||||||
|
_block, \
|
||||||
|
_off, \
|
||||||
|
(_pred) ? (_len) : 0, \
|
||||||
|
_next)
|
||||||
|
|
||||||
|
#define LFSD_ATTR_DISK_IF(_pred, \
|
||||||
|
_type, _id, _delta, _block, _off, _len, _next) \
|
||||||
|
LFSD_ATTR_DISK_IF_(_pred, \
|
||||||
|
LFSD_TAG_##_type, _id, _delta, _block, _off, _len, _next)
|
||||||
|
|
||||||
#define LFSR_ATTR_(_tag, _id, _buf, _len, _next) \
|
#define LFSR_ATTR_(_tag, _id, _buf, _len, _next) \
|
||||||
(&(const struct lfsr_attr){ \
|
(&(const struct lfsr_attr){ \
|
||||||
_tag, _id, \
|
_tag, _id, 0, \
|
||||||
LFSR_DATA_BUF(_buf, _len), \
|
LFSR_DATA_BUF(_buf, _len), \
|
||||||
_next})
|
_next})
|
||||||
|
|
||||||
@@ -742,7 +790,7 @@ struct lfsr_attr {
|
|||||||
|
|
||||||
#define LFSR_ATTR_DISK_(_tag, _id, _block, _off, _len, _next) \
|
#define LFSR_ATTR_DISK_(_tag, _id, _block, _off, _len, _next) \
|
||||||
(&(const struct lfsr_attr){ \
|
(&(const struct lfsr_attr){ \
|
||||||
_tag, _id, \
|
_tag, _id, 0, \
|
||||||
LFSR_DATA_DISK(_block, _off, _len), \
|
LFSR_DATA_DISK(_block, _off, _len), \
|
||||||
_next})
|
_next})
|
||||||
|
|
||||||
@@ -751,7 +799,7 @@ struct lfsr_attr {
|
|||||||
|
|
||||||
#define LFSR_ATTR_IF_(_pred, _tag, _id, _buf, _len, _next) \
|
#define LFSR_ATTR_IF_(_pred, _tag, _id, _buf, _len, _next) \
|
||||||
LFSR_ATTR_( \
|
LFSR_ATTR_( \
|
||||||
(_pred) ? (_tag) : LFSR_TAG_GROW, \
|
(_pred) ? (_tag) : LFSR_TAG_NOOP, \
|
||||||
_id, \
|
_id, \
|
||||||
_buf, \
|
_buf, \
|
||||||
(_pred) ? (_len) : 0, \
|
(_pred) ? (_len) : 0, \
|
||||||
@@ -762,7 +810,7 @@ struct lfsr_attr {
|
|||||||
|
|
||||||
#define LFSR_ATTR_DISK_IF_(_pred, _tag, _id, _block, _off, _len, _next) \
|
#define LFSR_ATTR_DISK_IF_(_pred, _tag, _id, _block, _off, _len, _next) \
|
||||||
LFSR_ATTR_DISK_( \
|
LFSR_ATTR_DISK_( \
|
||||||
(_pred) ? (_tag) : LFSR_TAG_GROW, \
|
(_pred) ? (_tag) : LFSR_TAG_NOOP, \
|
||||||
_id, \
|
_id, \
|
||||||
_block, \
|
_block, \
|
||||||
_off, \
|
_off, \
|
||||||
@@ -1882,7 +1930,7 @@ static void lfsr_rbyd_p_red(
|
|||||||
p_weights[0] = weight_;
|
p_weights[0] = weight_;
|
||||||
p_jumps[0] = jump_;
|
p_jumps[0] = jump_;
|
||||||
} else {
|
} else {
|
||||||
LFS_ASSERT(false);
|
LFS_UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1890,7 +1938,9 @@ static void lfsr_rbyd_p_red(
|
|||||||
|
|
||||||
// core rbyd algorithm
|
// core rbyd algorithm
|
||||||
static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
||||||
lfsr_tag_t tag, lfs_ssize_t id, lfsr_data_t data) {
|
lfsr_tag_t tag, lfs_ssize_t id, lfs_ssize_t delta,
|
||||||
|
lfsr_data_t data) {
|
||||||
|
printf("append w=%d id=%d d=%d\n", rbyd->weight, id, delta);
|
||||||
LFS_ASSERT(tag != 0);
|
LFS_ASSERT(tag != 0);
|
||||||
|
|
||||||
// we can't do anything if we're not erased
|
// we can't do anything if we're not erased
|
||||||
@@ -1898,6 +1948,12 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
return LFS_ERR_RANGE;
|
return LFS_ERR_RANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO do we really need this?
|
||||||
|
// ignore noops
|
||||||
|
if (tag == LFSR_TAG_NOOP) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// make sure every rbyd starts with its revision count
|
// make sure every rbyd starts with its revision count
|
||||||
if (rbyd->off == 0) {
|
if (rbyd->off == 0) {
|
||||||
uint32_t rev;
|
uint32_t rev;
|
||||||
@@ -1926,51 +1982,26 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
//
|
//
|
||||||
// note lfsr_rbyd_commit will throw out this copy of the rbyd if an
|
// note lfsr_rbyd_commit will throw out this copy of the rbyd if an
|
||||||
// error occurs
|
// error occurs
|
||||||
lfsr_tag_t tag_;
|
LFS_ASSERT(delta >= -(lfs_ssize_t)rbyd->weight);
|
||||||
lfs_ssize_t id_;
|
LFS_ASSERT(id <= rbyd->weight + delta);
|
||||||
lfsr_tag_t other_tag_;
|
rbyd->weight += delta;
|
||||||
lfs_ssize_t other_id_;
|
|
||||||
if (tag == LFSR_TAG_GROW) {
|
|
||||||
// noop?
|
|
||||||
if (lfsr_data_len(data) == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LFS_ASSERT(id <= rbyd->weight);
|
|
||||||
rbyd->weight += lfsr_data_len(data);
|
|
||||||
|
|
||||||
|
lfs_ssize_t id_ = id-delta - lfs_smax32(-delta, 0);
|
||||||
|
lfs_ssize_t other_id_ = id-delta;
|
||||||
|
lfsr_tag_t tag_ = lfsr_tag_isrm(tag) ? tag & ~0x2 : tag;
|
||||||
|
lfsr_tag_t other_tag_ = lfsr_tag_isrm(tag) ? (tag & ~0x2) + 0x10 : tag;
|
||||||
|
|
||||||
|
// TODO need this?
|
||||||
|
// TODO restructure with above?
|
||||||
|
if (delta > 0) {
|
||||||
|
id_ += 1;
|
||||||
|
other_id_ += 1;
|
||||||
tag_ = 0;
|
tag_ = 0;
|
||||||
id_ = id;
|
other_tag_ = 0;
|
||||||
other_tag_ = tag_;
|
|
||||||
other_id_ = id_;
|
|
||||||
} else if (tag == LFSR_TAG_SHRINK) {
|
|
||||||
// noop?
|
|
||||||
if (lfsr_data_len(data) == 0) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
LFS_ASSERT(id < rbyd->weight);
|
|
||||||
LFS_ASSERT(lfsr_data_len(data) <= rbyd->weight);
|
|
||||||
rbyd->weight -= lfsr_data_len(data);
|
|
||||||
|
|
||||||
tag_ = 0;
|
|
||||||
id_ = id;
|
|
||||||
other_tag_ = tag_;
|
|
||||||
other_id_ = id_ + lfsr_data_len(data);
|
|
||||||
} else if (lfsr_tag_isrm(tag)) {
|
|
||||||
LFS_ASSERT(id < rbyd->weight);
|
|
||||||
|
|
||||||
tag_ = tag & ~0x2;
|
|
||||||
id_ = id;
|
|
||||||
other_tag_ = tag_ + 0x10;
|
|
||||||
other_id_ = id_;
|
|
||||||
} else {
|
|
||||||
LFS_ASSERT(id < rbyd->weight);
|
|
||||||
|
|
||||||
tag_ = tag;
|
|
||||||
id_ = id;
|
|
||||||
other_tag_ = tag_;
|
|
||||||
other_id_ = id_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("ids %d..%d\n", id_, other_id_);
|
||||||
|
|
||||||
// diverged state in case we are removing a range from the tree
|
// diverged state in case we are removing a range from the tree
|
||||||
//
|
//
|
||||||
// this is a second copy of the search path state, used to keep track
|
// this is a second copy of the search path state, used to keep track
|
||||||
@@ -2012,19 +2043,19 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
lfsr_tag_t alt;
|
lfsr_tag_t alt;
|
||||||
lfs_ssize_t weight;
|
lfs_ssize_t weight;
|
||||||
lfs_off_t jump;
|
lfs_off_t jump;
|
||||||
lfs_ssize_t delta = lfsr_rbyd_readtag(lfs,
|
lfs_ssize_t d = lfsr_rbyd_readtag(lfs,
|
||||||
&lfs->pcache, &lfs->rcache, 0,
|
&lfs->pcache, &lfs->rcache, 0,
|
||||||
rbyd->block, branch, &alt, &weight, &jump, NULL);
|
rbyd->block, branch, &alt, &weight, &jump, NULL);
|
||||||
if (delta < 0) {
|
if (d < 0) {
|
||||||
rbyd->erased = false;
|
rbyd->erased = false;
|
||||||
return delta;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
// found an alt?
|
// found an alt?
|
||||||
if (lfsr_tag_isalt(alt)) {
|
if (lfsr_tag_isalt(alt)) {
|
||||||
// make jump absolute
|
// make jump absolute
|
||||||
jump = branch - jump;
|
jump = branch - jump;
|
||||||
lfs_off_t branch_ = branch + delta;
|
lfs_off_t branch_ = branch + d;
|
||||||
|
|
||||||
// do bounds want to take different paths? begin cutting
|
// do bounds want to take different paths? begin cutting
|
||||||
if (!diverged
|
if (!diverged
|
||||||
@@ -2036,6 +2067,7 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
p_alts[0], p_weights[0],
|
p_alts[0], p_weights[0],
|
||||||
lower_id, upper_id,
|
lower_id, upper_id,
|
||||||
other_tag_, other_id_)) {
|
other_tag_, other_id_)) {
|
||||||
|
printf("diverged! %x\n", branch);
|
||||||
// first take care of any lingering red alts
|
// first take care of any lingering red alts
|
||||||
if (lfsr_tag_isred(p_alts[0])) {
|
if (lfsr_tag_isred(p_alts[0])) {
|
||||||
alt = lfsr_tag_mkblack(p_alts[0]);
|
alt = lfsr_tag_mkblack(p_alts[0]);
|
||||||
@@ -2257,6 +2289,8 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
lower_id = other_lower_id;
|
lower_id = other_lower_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printf("found %d\n", id_);
|
||||||
|
|
||||||
// split leaf nodes?
|
// split leaf nodes?
|
||||||
//
|
//
|
||||||
// note we bias the weights here so that lfsr_rbyd_lookup
|
// note we bias the weights here so that lfsr_rbyd_lookup
|
||||||
@@ -2266,41 +2300,61 @@ static int lfsr_rbyd_append(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
if (lfsr_tag_isrm(tag_)) {
|
if (lfsr_tag_isrm(tag_)) {
|
||||||
// found an old removed tag, no split needed, just prune the
|
// found an old removed tag, no split needed, just prune the
|
||||||
// removed tag
|
// removed tag
|
||||||
|
printf("a %x %x\n", branch, rbyd->off);
|
||||||
|
|
||||||
} else if (id_ < id
|
} else if (id_ < (delta > 0 ? id : id-lfs_smax32(-delta, 0))
|
||||||
|| (id_ == id && lfsr_tag_key(tag_) < lfsr_tag_key(tag)
|
|| (id_ == (delta > 0 ? id : id-lfs_smax32(-delta, 0))
|
||||||
&& tag != LFSR_TAG_GROW
|
&& lfsr_tag_key(tag_) < lfsr_tag_key(tag))) {
|
||||||
&& tag != LFSR_TAG_SHRINK)) {
|
if (lfsr_tag_isrm(tag)) {
|
||||||
// split less than
|
printf("b %x %x\n", branch, rbyd->off);
|
||||||
//
|
// if removed make our tag unreachable
|
||||||
// note this is consistent for all appends and only happens when
|
|
||||||
// appending to the end of the tree
|
|
||||||
alt = LFSR_TAG_ALT(R, LE, tag_);
|
|
||||||
weight = id_ - lower_id;
|
|
||||||
|
|
||||||
} else if (tag == LFSR_TAG_GROW) {
|
|
||||||
// decrease weight when growing
|
|
||||||
alt = LFSR_TAG_ALT(B, LE, 0xfff0);
|
|
||||||
weight = upper_id - lower_id - 1 + lfsr_data_len(data);
|
|
||||||
|
|
||||||
} else if (tag == LFSR_TAG_SHRINK) {
|
|
||||||
// decrease weight when shrinking
|
|
||||||
if (upper_id - lower_id - 1 > (lfs_ssize_t)lfsr_data_len(data)) {
|
|
||||||
alt = LFSR_TAG_ALT(B, LE, 0xfff0);
|
alt = LFSR_TAG_ALT(B, LE, 0xfff0);
|
||||||
weight = upper_id - lower_id - 1 - lfsr_data_len(data);
|
weight = upper_id - lower_id - 1 + delta;
|
||||||
|
} else {
|
||||||
|
// split less than
|
||||||
|
printf("c %x %x\n", branch, rbyd->off);
|
||||||
|
alt = LFSR_TAG_ALT(R, LE, tag_);
|
||||||
|
weight = id_ - lower_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (id_ > id
|
|
||||||
|| (id_ == id && lfsr_tag_key(tag_) > lfsr_tag_key(tag))) {
|
// // Also note that this handles the case for rms/unreachables,
|
||||||
|
// // we might pick up an rm/unreachable during lfsr_tag_lookup, but
|
||||||
|
// // this is unavoidable in the case we've removed everything in a tree.
|
||||||
|
// // This probably makes "unreachable" a bad tag name, but I can't think
|
||||||
|
// // of a better one.
|
||||||
|
// //
|
||||||
|
//
|
||||||
|
// } else if (tag == LFSR_TAG_GROW) {
|
||||||
|
// // decrease weight when growing
|
||||||
|
// alt = LFSR_TAG_ALT(B, LE, 0xfff0);
|
||||||
|
// weight = upper_id - lower_id - 1 + lfsr_data_len(data);
|
||||||
|
//
|
||||||
|
// } else if (tag == LFSR_TAG_SHRINK) {
|
||||||
|
// // decrease weight when shrinking
|
||||||
|
// if (upper_id - lower_id - 1 > (lfs_ssize_t)lfsr_data_len(data)) {
|
||||||
|
// alt = LFSR_TAG_ALT(B, LE, 0xfff0);
|
||||||
|
// weight = upper_id - lower_id - 1 - lfsr_data_len(data);
|
||||||
|
// }
|
||||||
|
|
||||||
|
} else if (id_ > id-delta
|
||||||
|
|| (id_ == id-delta
|
||||||
|
&& lfsr_tag_key(tag_) > lfsr_tag_key(tag))) {
|
||||||
if (lfsr_tag_isrm(tag)) {
|
if (lfsr_tag_isrm(tag)) {
|
||||||
// hide our tag during removes
|
printf("d %x %x\n", branch, rbyd->off);
|
||||||
|
// if removed make our tag unreachable
|
||||||
alt = LFSR_TAG_ALT(B, LE, 0xfff0);
|
alt = LFSR_TAG_ALT(B, LE, 0xfff0);
|
||||||
weight = upper_id - lower_id - 1;
|
weight = upper_id - lower_id - 1 + delta;
|
||||||
} else {
|
} else {
|
||||||
|
printf("e %x %x\n", branch, rbyd->off);
|
||||||
// split greater than
|
// split greater than
|
||||||
alt = LFSR_TAG_ALT(R, GT, tag);
|
alt = LFSR_TAG_ALT(R, GT, tag);
|
||||||
weight = upper_id - id - 1;
|
weight = upper_id - id - 1 + delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO rm me
|
||||||
|
} else {
|
||||||
|
printf("g %x %x\n", branch, rbyd->off);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alt) {
|
if (alt) {
|
||||||
@@ -2331,13 +2385,9 @@ leaf:;
|
|||||||
//
|
//
|
||||||
// note we always need something after the alts! without something between
|
// note we always need something after the alts! without something between
|
||||||
// alts we may not be able to find the trunk of our tree
|
// alts we may not be able to find the trunk of our tree
|
||||||
if (tag == LFSR_TAG_GROW || tag == LFSR_TAG_SHRINK) {
|
|
||||||
tag = LFSR_TAG_UNREACHABLE;
|
|
||||||
data = LFSR_DATA_NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = lfsr_rbyd_progtag(lfs, rbyd,
|
err = lfsr_rbyd_progtag(lfs, rbyd,
|
||||||
tag, id, lfsr_data_len(data), &rbyd->crc);
|
// TODO WHY OFF BY ONE delta > 0???
|
||||||
|
tag, id /*+(delta > 0 ? delta-1 : delta)*/, lfsr_data_len(data), &rbyd->crc);
|
||||||
if (err) {
|
if (err) {
|
||||||
rbyd->erased = false;
|
rbyd->erased = false;
|
||||||
return err;
|
return err;
|
||||||
@@ -2353,6 +2403,38 @@ leaf:;
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO remove this wrapper
|
||||||
|
static int lfsr_rbyd_append_(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
||||||
|
lfsr_tag_t tag, lfs_ssize_t id, lfsr_data_t data) {
|
||||||
|
if (tag == LFSR_TAG_GROW) {
|
||||||
|
int err = lfsr_rbyd_append(lfs, rbyd,
|
||||||
|
LFSR_TAG_UNR, id,
|
||||||
|
+lfsr_data_len(data), LFSR_DATA_NULL);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else if (tag == LFSR_TAG_SHRINK) {
|
||||||
|
int err = lfsr_rbyd_append(lfs, rbyd,
|
||||||
|
LFSR_TAG_UNR, id,
|
||||||
|
-lfsr_data_len(data), LFSR_DATA_NULL);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
int err = lfsr_rbyd_append(lfs, rbyd,
|
||||||
|
tag, id, 0, data);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
||||||
const struct lfsr_attr *attrs) {
|
const struct lfsr_attr *attrs) {
|
||||||
// we can't do anything if we're not erased
|
// we can't do anything if we're not erased
|
||||||
@@ -2378,10 +2460,19 @@ static int lfsr_rbyd_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
|
|
||||||
// append each tag to the tree
|
// append each tag to the tree
|
||||||
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
||||||
int err = lfsr_rbyd_append(lfs, &rbyd_,
|
// TODO rm this
|
||||||
attr->tag, attr->id, attr->data);
|
if (attr->delta == 0) {
|
||||||
if (err) {
|
int err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
return err;
|
attr->tag, attr->id, attr->data);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int err = lfsr_rbyd_append(lfs, &rbyd_,
|
||||||
|
attr->tag, attr->id, attr->delta, attr->data);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3037,7 +3128,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// size, can we combine grows into the tag append in the rbyd
|
// size, can we combine grows into the tag append in the rbyd
|
||||||
// somehow?
|
// somehow?
|
||||||
// create grows as necessary
|
// create grows as necessary
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
LFSR_TAG_GROW,
|
LFSR_TAG_GROW,
|
||||||
id - (weight-1),
|
id - (weight-1),
|
||||||
// TODO also this is a weird way to use lfsr_data_t
|
// TODO also this is a weird way to use lfsr_data_t
|
||||||
@@ -3059,7 +3150,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// append the attr
|
// append the attr
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
tag, id, LFSR_DATA_DISK(rbyd->block, off, size));
|
tag, id, LFSR_DATA_DISK(rbyd->block, off, size));
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -3075,7 +3166,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// append any pending attrs, it's up to upper
|
// append any pending attrs, it's up to upper
|
||||||
// layers to make sure these always fit
|
// layers to make sure these always fit
|
||||||
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
attr->tag, attr->id, attr->data);
|
attr->tag, attr->id, attr->data);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -3145,7 +3236,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// TODO does this work if we're removing nothing/oob?
|
// TODO does this work if we're removing nothing/oob?
|
||||||
// add an rbyd and btree test?
|
// add an rbyd and btree test?
|
||||||
if ((lfs_size_t)bisect < rbyd_.weight) {
|
if ((lfs_size_t)bisect < rbyd_.weight) {
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
LFSR_TAG_SHRINK,
|
LFSR_TAG_SHRINK,
|
||||||
bisect,
|
bisect,
|
||||||
LFSR_DATA_BUF(NULL, rbyd_.weight-bisect));
|
LFSR_DATA_BUF(NULL, rbyd_.weight-bisect));
|
||||||
@@ -3161,7 +3252,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
lfs_ssize_t bisect_ = bisect;
|
lfs_ssize_t bisect_ = bisect;
|
||||||
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
||||||
if (attr->id < bisect_) {
|
if (attr->id < bisect_) {
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
attr->tag, attr->id, attr->data);
|
attr->tag, attr->id, attr->data);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -3213,7 +3304,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// size, can we combine grows into the tag append in the rbyd
|
// size, can we combine grows into the tag append in the rbyd
|
||||||
// somehow?
|
// somehow?
|
||||||
// create grows as necessary
|
// create grows as necessary
|
||||||
err = lfsr_rbyd_append(lfs, &sibling,
|
err = lfsr_rbyd_append_(lfs, &sibling,
|
||||||
LFSR_TAG_GROW,
|
LFSR_TAG_GROW,
|
||||||
id - bisect - (weight-1),
|
id - bisect - (weight-1),
|
||||||
// TODO also this is a weird way to use lfsr_data_t
|
// TODO also this is a weird way to use lfsr_data_t
|
||||||
@@ -3223,7 +3314,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// append the attr
|
// append the attr
|
||||||
err = lfsr_rbyd_append(lfs, &sibling,
|
err = lfsr_rbyd_append_(lfs, &sibling,
|
||||||
tag, id - bisect,
|
tag, id - bisect,
|
||||||
LFSR_DATA_DISK(rbyd->block, off, size));
|
LFSR_DATA_DISK(rbyd->block, off, size));
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -3237,7 +3328,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
bisect_ = bisect;
|
bisect_ = bisect;
|
||||||
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
for (const struct lfsr_attr *attr = attrs; attr; attr = attr->next) {
|
||||||
if (attr->id >= bisect_) {
|
if (attr->id >= bisect_) {
|
||||||
err = lfsr_rbyd_append(lfs, &sibling,
|
err = lfsr_rbyd_append_(lfs, &sibling,
|
||||||
attr->tag, attr->id-bisect_, attr->data);
|
attr->tag, attr->id-bisect_, attr->data);
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -3452,7 +3543,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// size, can we combine grows into the tag append in the rbyd
|
// size, can we combine grows into the tag append in the rbyd
|
||||||
// somehow?
|
// somehow?
|
||||||
// create grows as necessary
|
// create grows as necessary
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
LFSR_TAG_GROW,
|
LFSR_TAG_GROW,
|
||||||
sdelta + id - (weight-1),
|
sdelta + id - (weight-1),
|
||||||
// TODO also this is a weird way to use lfsr_data_t
|
// TODO also this is a weird way to use lfsr_data_t
|
||||||
@@ -3462,7 +3553,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// append the attr
|
// append the attr
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
tag, sdelta + id, LFSR_DATA_DISK(sibling.block, off, size));
|
tag, sdelta + id, LFSR_DATA_DISK(sibling.block, off, size));
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
@@ -3471,7 +3562,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
// if we exceed our compaction threshold our merge has
|
// if we exceed our compaction threshold our merge has
|
||||||
// failed, clean up ids and merge_abort
|
// failed, clean up ids and merge_abort
|
||||||
if (rbyd_.off > lfs->cfg->block_size/2) {
|
if (rbyd_.off > lfs->cfg->block_size/2) {
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
LFSR_TAG_SHRINK,
|
LFSR_TAG_SHRINK,
|
||||||
sdelta,
|
sdelta,
|
||||||
// TODO also this is a weird way to use lfsr_data_t
|
// TODO also this is a weird way to use lfsr_data_t
|
||||||
@@ -3506,7 +3597,7 @@ static int lfsr_btree_commit(lfs_t *lfs,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = lfsr_rbyd_append(lfs, &rbyd_,
|
err = lfsr_rbyd_append_(lfs, &rbyd_,
|
||||||
LFSR_TAG_BNAME, split_id,
|
LFSR_TAG_BNAME, split_id,
|
||||||
LFSR_DATA_DISK(parent.block, split_off, split_size));
|
LFSR_DATA_DISK(parent.block, split_off, split_size));
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -100,6 +100,14 @@ extern "C"
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_UNREACHABLE
|
||||||
|
#ifndef LFS_NO_ASSERT
|
||||||
|
#define LFS_UNREACHABLE() __builtin_unreachable()
|
||||||
|
#else
|
||||||
|
#define LFS_UNREACHABLE() LFS_ASSERT(false)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Builtin functions, these may be replaced by more efficient
|
// Builtin functions, these may be replaced by more efficient
|
||||||
// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
|
// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
|
||||||
|
|||||||
+16
-16
@@ -7,20 +7,20 @@ import os
|
|||||||
import struct
|
import struct
|
||||||
|
|
||||||
|
|
||||||
TAG_UNREACHABLE = 0x0002
|
TAG_UNR = 0x0002
|
||||||
TAG_NAME = 0x1000
|
TAG_NAME = 0x1000
|
||||||
TAG_BNAME = 0x1000
|
TAG_BNAME = 0x1000
|
||||||
TAG_REG = 0x1010
|
TAG_REG = 0x1010
|
||||||
TAG_DIR = 0x1020
|
TAG_DIR = 0x1020
|
||||||
TAG_STRUCT = 0x3000
|
TAG_STRUCT = 0x3000
|
||||||
TAG_INLINED = 0x3000
|
TAG_INLINED = 0x3000
|
||||||
TAG_BLOCK = 0x3100
|
TAG_BLOCK = 0x3100
|
||||||
TAG_BRANCH = 0x3200
|
TAG_BRANCH = 0x3200
|
||||||
TAG_BTREE = 0x3300
|
TAG_BTREE = 0x3300
|
||||||
TAG_UATTR = 0x4000
|
TAG_UATTR = 0x4000
|
||||||
TAG_ALT = 0x0008
|
TAG_ALT = 0x0008
|
||||||
TAG_CRC = 0x0004
|
TAG_CRC = 0x0004
|
||||||
TAG_FCRC = 0x1004
|
TAG_FCRC = 0x1004
|
||||||
|
|
||||||
def blocklim(s):
|
def blocklim(s):
|
||||||
if '.' in s:
|
if '.' in s:
|
||||||
@@ -83,8 +83,8 @@ def xxd(data, width=16, crc=False):
|
|||||||
for b in map(chr, data[i:i+width])))
|
for b in map(chr, data[i:i+width])))
|
||||||
|
|
||||||
def tagrepr(tag, id, size, off=None):
|
def tagrepr(tag, id, size, off=None):
|
||||||
if (tag & 0xfffe) == TAG_UNREACHABLE:
|
if (tag & 0xfffe) == TAG_UNR:
|
||||||
return 'unreachable id%d%s' % (
|
return 'unr id%d%s' % (
|
||||||
id,
|
id,
|
||||||
' %d' % size if size else '')
|
' %d' % size if size else '')
|
||||||
elif (tag & 0xf00c) == TAG_NAME:
|
elif (tag & 0xf00c) == TAG_NAME:
|
||||||
|
|||||||
+16
-16
@@ -16,20 +16,20 @@ COLORS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
TAG_UNREACHABLE = 0x0002
|
TAG_UNR = 0x0002
|
||||||
TAG_NAME = 0x1000
|
TAG_NAME = 0x1000
|
||||||
TAG_BNAME = 0x1000
|
TAG_BNAME = 0x1000
|
||||||
TAG_REG = 0x1010
|
TAG_REG = 0x1010
|
||||||
TAG_DIR = 0x1020
|
TAG_DIR = 0x1020
|
||||||
TAG_STRUCT = 0x3000
|
TAG_STRUCT = 0x3000
|
||||||
TAG_INLINED = 0x3000
|
TAG_INLINED = 0x3000
|
||||||
TAG_BLOCK = 0x3100
|
TAG_BLOCK = 0x3100
|
||||||
TAG_BRANCH = 0x3200
|
TAG_BRANCH = 0x3200
|
||||||
TAG_BTREE = 0x3300
|
TAG_BTREE = 0x3300
|
||||||
TAG_UATTR = 0x4000
|
TAG_UATTR = 0x4000
|
||||||
TAG_ALT = 0x0008
|
TAG_ALT = 0x0008
|
||||||
TAG_CRC = 0x0004
|
TAG_CRC = 0x0004
|
||||||
TAG_FCRC = 0x1004
|
TAG_FCRC = 0x1004
|
||||||
|
|
||||||
def blocklim(s):
|
def blocklim(s):
|
||||||
if '.' in s:
|
if '.' in s:
|
||||||
@@ -92,8 +92,8 @@ def xxd(data, width=16, crc=False):
|
|||||||
for b in map(chr, data[i:i+width])))
|
for b in map(chr, data[i:i+width])))
|
||||||
|
|
||||||
def tagrepr(tag, id, size, off=None):
|
def tagrepr(tag, id, size, off=None):
|
||||||
if (tag & 0xfffe) == TAG_UNREACHABLE:
|
if (tag & 0xfffe) == TAG_UNR:
|
||||||
return 'unreachable id%d%s' % (
|
return 'unr id%d%s' % (
|
||||||
id,
|
id,
|
||||||
' %d' % size if size else '')
|
' %d' % size if size else '')
|
||||||
elif (tag & 0xf00c) == TAG_NAME:
|
elif (tag & 0xf00c) == TAG_NAME:
|
||||||
|
|||||||
+1253
-852
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user