Added a couple attr-related helper functions
Some relatively-annoying states to check for: - lfsr_attr_isnoop - lfsr_attr_isinsert And some accessors for marshalled pointers used by internal tags: - lfsr_attr_grm - lfsr_attr_mdir - lfsr_attr_shrubcommit - lfsr_attr_shrubtrunk
This commit is contained in:
@@ -1063,6 +1063,8 @@ enum {
|
|||||||
((lfsr_data_t){.u.buf.buffer=(const void*)(lfsr_grm_t*){_grm}})
|
((lfsr_data_t){.u.buf.buffer=(const void*)(lfsr_grm_t*){_grm}})
|
||||||
|
|
||||||
// writing to an unrelated trunk in the rbyd
|
// writing to an unrelated trunk in the rbyd
|
||||||
|
typedef struct lfsr_shrubcommit lfsr_shrubcommit_t;
|
||||||
|
|
||||||
#define LFSR_DATA_SHRUBCOMMIT(_shrub, _rid, _attrs, _attr_count) \
|
#define LFSR_DATA_SHRUBCOMMIT(_shrub, _rid, _attrs, _attr_count) \
|
||||||
((lfsr_data_t){.u.buf.buffer=(const void*)&(const lfsr_shrubcommit_t){ \
|
((lfsr_data_t){.u.buf.buffer=(const void*)&(const lfsr_shrubcommit_t){ \
|
||||||
.shrub=_shrub, \
|
.shrub=_shrub, \
|
||||||
@@ -1438,13 +1440,37 @@ typedef struct lfsr_attr {
|
|||||||
|
|
||||||
#define LFSR_ATTR_NOOP() LFSR_ATTR(NULL, 0, NULL())
|
#define LFSR_ATTR_NOOP() LFSR_ATTR(NULL, 0, NULL())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO make this const again eventually
|
|
||||||
#define LFSR_ATTRS(...) \
|
#define LFSR_ATTRS(...) \
|
||||||
(const lfsr_attr_t[]){__VA_ARGS__}, \
|
(const lfsr_attr_t[]){__VA_ARGS__}, \
|
||||||
sizeof((const lfsr_attr_t[]){__VA_ARGS__}) / sizeof(lfsr_attr_t)
|
sizeof((const lfsr_attr_t[]){__VA_ARGS__}) / sizeof(lfsr_attr_t)
|
||||||
|
|
||||||
|
// some helpers
|
||||||
|
static inline bool lfsr_attr_isnoop(const lfsr_attr_t *attr) {
|
||||||
|
return !attr->tag && attr->delta == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool lfsr_attr_isinsert(const lfsr_attr_t *attr) {
|
||||||
|
return !lfsr_tag_isgrow(attr->tag) && attr->delta > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lfsr_grm_t *lfsr_attr_grm(const lfsr_attr_t *attr) {
|
||||||
|
return (lfsr_grm_t*)attr->data.u.buf.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lfsr_mdir_t *lfsr_attr_mdir(const lfsr_attr_t *attr) {
|
||||||
|
return (lfsr_mdir_t*)attr->data.u.buf.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline const lfsr_shrubcommit_t *lfsr_attr_shrubcommit(
|
||||||
|
const lfsr_attr_t *attr) {
|
||||||
|
return (const lfsr_shrubcommit_t*)attr->data.u.buf.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline lfsr_shrub_t *lfsr_attr_shrubtrunk(const lfsr_attr_t *attr) {
|
||||||
|
return (lfsr_shrub_t*)attr->data.u.buf.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// generalized info returned by traveral functions
|
// generalized info returned by traveral functions
|
||||||
typedef struct lfsr_tinfo {
|
typedef struct lfsr_tinfo {
|
||||||
@@ -2543,7 +2569,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
lfsr_srid_t other_rid_;
|
lfsr_srid_t other_rid_;
|
||||||
lfsr_tag_t tag_;
|
lfsr_tag_t tag_;
|
||||||
lfsr_tag_t other_tag_;
|
lfsr_tag_t other_tag_;
|
||||||
if (delta != 0 && !lfsr_tag_isgrow(tag)) {
|
if (!lfsr_tag_isgrow(tag) && delta != 0) {
|
||||||
if (delta > 0) {
|
if (delta > 0) {
|
||||||
LFS_ASSERT(rid <= rbyd->weight);
|
LFS_ASSERT(rid <= rbyd->weight);
|
||||||
|
|
||||||
@@ -2906,7 +2932,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
if (lfsr_tag_key(tag_)
|
if (lfsr_tag_key(tag_)
|
||||||
&& (upper_rid-1 < rid-lfs_smax32(-delta, 0)
|
&& (upper_rid-1 < rid-lfs_smax32(-delta, 0)
|
||||||
|| (upper_rid-1 == rid-lfs_smax32(-delta, 0)
|
|| (upper_rid-1 == rid-lfs_smax32(-delta, 0)
|
||||||
&& ((delta > 0 && !lfsr_tag_isgrow(tag))
|
&& ((!lfsr_tag_isgrow(tag) && delta > 0)
|
||||||
|| (!lfsr_tag_issupwide(tag)
|
|| (!lfsr_tag_issupwide(tag)
|
||||||
&& lfsr_tag_supkey(tag_) < lfsr_tag_supkey(tag))
|
&& lfsr_tag_supkey(tag_) < lfsr_tag_supkey(tag))
|
||||||
|| (!lfsr_tag_issupwide(tag)
|
|| (!lfsr_tag_issupwide(tag)
|
||||||
@@ -2932,7 +2958,7 @@ static int lfsr_rbyd_appendattr(lfs_t *lfs, lfsr_rbyd_t *rbyd,
|
|||||||
} else if (lfsr_tag_key(tag_)
|
} else if (lfsr_tag_key(tag_)
|
||||||
&& (upper_rid-1 > rid
|
&& (upper_rid-1 > rid
|
||||||
|| (upper_rid-1 == rid
|
|| (upper_rid-1 == rid
|
||||||
&& ((delta > 0 && !lfsr_tag_isgrow(tag))
|
&& ((!lfsr_tag_isgrow(tag) && delta > 0)
|
||||||
|| (!lfsr_tag_issupwide(tag)
|
|| (!lfsr_tag_issupwide(tag)
|
||||||
&& lfsr_tag_supkey(tag_) > lfsr_tag_supkey(tag))
|
&& lfsr_tag_supkey(tag_) > lfsr_tag_supkey(tag))
|
||||||
|| (!lfsr_tag_issupwide(tag)
|
|| (!lfsr_tag_issupwide(tag)
|
||||||
@@ -3156,9 +3182,7 @@ static int lfsr_rbyd_appendattrs(lfs_t *lfs,
|
|||||||
for (lfs_size_t i = 0; i < attr_count; i++) {
|
for (lfs_size_t i = 0; i < attr_count; i++) {
|
||||||
// treat inserts after the first tag as though they are splits,
|
// treat inserts after the first tag as though they are splits,
|
||||||
// sequential inserts don't really make sense otherwise
|
// sequential inserts don't really make sense otherwise
|
||||||
if (i > 0
|
if (i > 0 && lfsr_attr_isinsert(&attrs[i])) {
|
||||||
&& !lfsr_tag_isgrow(attrs[i].tag)
|
|
||||||
&& attrs[i].delta > 0) {
|
|
||||||
rid += 1;
|
rid += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3187,7 +3211,7 @@ static int lfsr_rbyd_appendattrs(lfs_t *lfs,
|
|||||||
|
|
||||||
// adjust rid
|
// adjust rid
|
||||||
rid += attrs[i].delta;
|
rid += attrs[i].delta;
|
||||||
if (!lfsr_tag_isgrow(attrs[i].tag) && attrs[i].delta > 0) {
|
if (lfsr_attr_isinsert(&attrs[i])) {
|
||||||
rid -= 1;
|
rid -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4952,12 +4976,12 @@ static int lfsr_shrub_compact(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this is needed to sneak shrub commits into mdir commits
|
// this is needed to sneak shrub commits into mdir commits
|
||||||
typedef struct lfsr_shrubcommit_t {
|
struct lfsr_shrubcommit {
|
||||||
lfsr_shrub_t *shrub;
|
lfsr_shrub_t *shrub;
|
||||||
lfsr_srid_t rid;
|
lfsr_srid_t rid;
|
||||||
const lfsr_attr_t *attrs;
|
const lfsr_attr_t *attrs;
|
||||||
lfs_size_t attr_count;
|
lfs_size_t attr_count;
|
||||||
} lfsr_shrubcommit_t;
|
};
|
||||||
|
|
||||||
static int lfsr_shrub_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
|
static int lfsr_shrub_commit(lfs_t *lfs, lfsr_rbyd_t *rbyd_,
|
||||||
lfsr_shrub_t *shrub, lfsr_srid_t rid,
|
lfsr_shrub_t *shrub, lfsr_srid_t rid,
|
||||||
@@ -5524,9 +5548,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
|
|
||||||
for (lfs_size_t i = 0; i < attr_count; i++) {
|
for (lfs_size_t i = 0; i < attr_count; i++) {
|
||||||
// we just happen to never split in an mdir commit
|
// we just happen to never split in an mdir commit
|
||||||
LFS_ASSERT(!(i > 0
|
LFS_ASSERT(!(i > 0 && lfsr_attr_isinsert(&attrs[i])));
|
||||||
&& !lfsr_tag_isgrow(attrs[i].tag)
|
|
||||||
&& attrs[i].delta > 0));
|
|
||||||
|
|
||||||
// ignore any gstate tags here, these need to be handled
|
// ignore any gstate tags here, these need to be handled
|
||||||
// specially by upper-layers
|
// specially by upper-layers
|
||||||
@@ -5539,8 +5561,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
} else if (attrs[i].tag == LFSR_TAG_MOVE) {
|
} else if (attrs[i].tag == LFSR_TAG_MOVE) {
|
||||||
// weighted moves are not supported
|
// weighted moves are not supported
|
||||||
LFS_ASSERT(attrs[i].delta == 0);
|
LFS_ASSERT(attrs[i].delta == 0);
|
||||||
const lfsr_mdir_t *mdir__
|
const lfsr_mdir_t *mdir__ = lfsr_attr_mdir(&attrs[i]);
|
||||||
= (const lfsr_mdir_t*)attrs[i].data.u.buf.buffer;
|
|
||||||
|
|
||||||
// skip the name tag, this is always replaced by upper layers
|
// skip the name tag, this is always replaced by upper layers
|
||||||
lfsr_tag_t tag = LFSR_TAG_STRUCT-1;
|
lfsr_tag_t tag = LFSR_TAG_STRUCT-1;
|
||||||
@@ -5665,7 +5686,8 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
} else if (attrs[i].tag == LFSR_TAG_SHRUBALLOC
|
} else if (attrs[i].tag == LFSR_TAG_SHRUBALLOC
|
||||||
|| attrs[i].tag == LFSR_TAG_SHRUBCOMMIT) {
|
|| attrs[i].tag == LFSR_TAG_SHRUBCOMMIT) {
|
||||||
const lfsr_shrubcommit_t *bshrubcommit
|
const lfsr_shrubcommit_t *bshrubcommit
|
||||||
= (const lfsr_shrubcommit_t*)attrs[i].data.u.buf.buffer;
|
= lfsr_attr_shrubcommit(&attrs[i]);
|
||||||
|
|
||||||
// SHRUBALLOC is roughly the same as SHRUBCOMMIT but also
|
// SHRUBALLOC is roughly the same as SHRUBCOMMIT but also
|
||||||
// resets the shrub, we need to do this here so bshrub root
|
// resets the shrub, we need to do this here so bshrub root
|
||||||
// extensions are atomic
|
// extensions are atomic
|
||||||
@@ -5690,8 +5712,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
// TODO should we preserve mode for all of these?
|
// TODO should we preserve mode for all of these?
|
||||||
// TODO should we do the same for sprouts?
|
// TODO should we do the same for sprouts?
|
||||||
} else if (lfsr_tag_key(attrs[i].tag) == LFSR_TAG_SHRUBTRUNK) {
|
} else if (lfsr_tag_key(attrs[i].tag) == LFSR_TAG_SHRUBTRUNK) {
|
||||||
lfsr_shrub_t *shrub
|
lfsr_shrub_t *shrub = lfsr_attr_shrubtrunk(&attrs[i]);
|
||||||
= (lfsr_shrub_t*)attrs[i].data.u.buf.buffer;
|
|
||||||
|
|
||||||
uint8_t shrub_buf[LFSR_SHRUB_DSIZE];
|
uint8_t shrub_buf[LFSR_SHRUB_DSIZE];
|
||||||
int err = lfsr_rbyd_appendattr(lfs, &rbyd_,
|
int err = lfsr_rbyd_appendattr(lfs, &rbyd_,
|
||||||
@@ -5719,7 +5740,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
|
|
||||||
// adjust rid
|
// adjust rid
|
||||||
rid += attrs[i].delta;
|
rid += attrs[i].delta;
|
||||||
if (!lfsr_tag_isgrow(attrs[i].tag) && attrs[i].delta > 0) {
|
if (lfsr_attr_isinsert(&attrs[i])) {
|
||||||
rid -= 1;
|
rid -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6388,7 +6409,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
// xored with on-disk gdeltas in lower-level functions
|
// xored with on-disk gdeltas in lower-level functions
|
||||||
if (attrs[i].tag == LFSR_TAG_GRM) {
|
if (attrs[i].tag == LFSR_TAG_GRM) {
|
||||||
// encode to disk
|
// encode to disk
|
||||||
lfsr_grm_t *grm = (lfsr_grm_t*)attrs[i].data.u.buf.buffer;
|
lfsr_grm_t *grm = lfsr_attr_grm(&attrs[i]);
|
||||||
lfsr_data_fromgrm(grm, lfs->grm_d);
|
lfsr_data_fromgrm(grm, lfs->grm_d);
|
||||||
|
|
||||||
// xor with our current gstate to find our initial gdelta
|
// xor with our current gstate to find our initial gdelta
|
||||||
@@ -6564,7 +6585,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
//
|
//
|
||||||
// gd' = gd xor (grm' xor grm)
|
// gd' = gd xor (grm' xor grm)
|
||||||
//
|
//
|
||||||
lfsr_grm_t *grm = (lfsr_grm_t*)attrs[i].data.u.buf.buffer;
|
lfsr_grm_t *grm = lfsr_attr_grm(&attrs[i]);
|
||||||
uint8_t grm_buf[LFSR_GRM_DSIZE];
|
uint8_t grm_buf[LFSR_GRM_DSIZE];
|
||||||
err = lfsr_grm_xor(lfs, lfs->grm_d,
|
err = lfsr_grm_xor(lfs, lfs->grm_d,
|
||||||
lfsr_data_fromgrm(grm, grm_buf));
|
lfsr_data_fromgrm(grm, grm_buf));
|
||||||
@@ -6668,7 +6689,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
//
|
//
|
||||||
// gd' = gd xor (grm' xor grm)
|
// gd' = gd xor (grm' xor grm)
|
||||||
//
|
//
|
||||||
lfsr_grm_t *grm = (lfsr_grm_t*)attrs[i].data.u.buf.buffer;
|
lfsr_grm_t *grm = lfsr_attr_grm(&attrs[i]);
|
||||||
uint8_t grm_buf[LFSR_GRM_DSIZE];
|
uint8_t grm_buf[LFSR_GRM_DSIZE];
|
||||||
err = lfsr_grm_xor(lfs, lfs->grm_d,
|
err = lfsr_grm_xor(lfs, lfs->grm_d,
|
||||||
lfsr_data_fromgrm(grm, grm_buf));
|
lfsr_data_fromgrm(grm, grm_buf));
|
||||||
@@ -6749,7 +6770,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
for (lfs_size_t i = 0; i < attr_count; i++) {
|
for (lfs_size_t i = 0; i < attr_count; i++) {
|
||||||
// update any gstate
|
// update any gstate
|
||||||
if (attrs[i].tag == LFSR_TAG_GRM) {
|
if (attrs[i].tag == LFSR_TAG_GRM) {
|
||||||
lfs->grm = *(lfsr_grm_t*)attrs[i].data.u.buf.buffer;
|
lfs->grm = *lfsr_attr_grm(&attrs[i]);
|
||||||
|
|
||||||
// keep track of the exact encoding on-disk
|
// keep track of the exact encoding on-disk
|
||||||
lfsr_data_fromgrm(&lfs->grm, lfs->grm_g);
|
lfsr_data_fromgrm(&lfs->grm, lfs->grm_g);
|
||||||
@@ -6809,7 +6830,7 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
|
|
||||||
// adjust mid
|
// adjust mid
|
||||||
mid += attrs[i].delta;
|
mid += attrs[i].delta;
|
||||||
if (!lfsr_tag_isgrow(attrs[i].tag) && attrs[i].delta > 0) {
|
if (lfsr_attr_isinsert(&attrs[i])) {
|
||||||
mid -= 1;
|
mid -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user