Changed lfsr_data_t internals, added LFSR_DATA_CAT

The main purpose of this change is to introduce LFSR_DATA_CAT, a
generalized way to concatenated various data references internally.

As a side-effect lfsr_data_t has been completely restructured. Now,
lfsr_data_t can be in one of 4 modes:

If the size field's sign bit=0, the lfsr_data_t points in-device. A new,
count field, determines the encoding:

  sign(size)=0, count=0 => inlined:

    .---+---+---+---.
    |     size      |
    |---+---+---+---|
    |c=0| inlined d |  note inlined data is just enough to hold
    |---+           |  one encoded leb128
    | ata...        |
    '---------------'

  sign(size)=1, count=1 => direct:

    .---+---+---+---.   .---+---+---+---.
    |     size      | .>| data...       |
    |---+---+---+---| | |       .       |
    |c=1|           | | .       .       .
    |---+---+---+---| | .       .       .
    | direct ptr -----' .               .
    '---------------'

  sign(size)=1, count>=2 => indirect:

    .---+---+---+---.   .---+---+---+---.   .---+---+---+---.
    |     size      | .>|     size      | .>| data...       |
    |---+---+---+---| | |---+---+---+---| | |       .       |
    |c>1|           | | |c=1|           | | .       .       .
    |---+---+---+---| | |---+---+---+---| | .       .       .
    | indirect ptr ---' | direct ptr -----' .               .
    '---------------'   '---------------'   .---+---+---+---.
                        |     size      | .>| data...       |
                        |---+---+---+---| | |       .       |
                        |c=1|           | | .       .       .
                        |---+---+---+---| | .       .       .
                        | direct ptr -----' .               .
                        '---+---+---+---'
                        |       .       |
                        |       .       |
                        .       .       .
                        .               .
                        .               .

  note only one indirect layer is allowed due to no recursion

If the size field's sign bit=1, the lfsr_data_t points on-disk:

  sign(size)=0 => on-disk:

    .---+---+---+---.          .....
    |     size      |      ..''     ''..
    |---+---+---+---|     :    :        :
    |     block ------+->|            ..:|
    |---+---+---+---| |  |......( )::::::|
    |      off -------'  |:::'    :      |
    '---------------'     :'       :    :
                           ''..     :.''
                               '''''

My goal with this commit was to test the new implementation and see how
it would impact code/RAM size before adopting it in the actual file
handling code, and the results are... not great...

            code          stack
  before:  24668           1840
  after:   25552 (+3.5%)   1920 (+4.2%)

I think most of the new cost comes from the now correct handling of
read/cmp with concatentated datas, which previously would just assert.
This change gives us LFSR_DATA_CAT, so I will be working with it for
now, but this may be worth looking at again in the future. Maybe the
correct handling of read/cmp should just be reverted to an assert...
This commit is contained in:
Christopher Haster
2023-09-22 22:19:37 -05:00
parent da2a4b45f7
commit 02ae6050de
5 changed files with 510 additions and 276 deletions
+312 -99
View File
@@ -980,20 +980,23 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
// use the sign bit to indicate on-disk vs in-device // use the sign bit to indicate on-disk vs in-device
#define LFSR_DATA_ONDISK 0x80000000 #define LFSR_DATA_ONDISK 0x80000000
// the most common use is to pass a buffer with explicit size
#define LFSR_DATA(_buffer, _size) \
((lfsr_data_t){ \
.u.buffer.size=_size, \
.u.buffer.leb128=0, \
.u.buffer.buffer=(const void*)(_buffer)})
// LFSR_DATA_DATA just provides and escape hatch to pass raw datas // LFSR_DATA_DATA just provides and escape hatch to pass raw datas
// through the LFSR_ATTR macro // through the LFSR_ATTR macro
#define LFSR_DATA_DATA(_data) (_data) #define LFSR_DATA_DATA(_data) (_data)
#define LFSR_DATA_NULL LFSR_DATA(NULL, 0) #define LFSR_DATA_NULL LFSR_DATA_BUF(NULL, 0)
#define LFSR_DATA_BUF(_buffer, _size) LFSR_DATA(_buffer, _size) #define LFSR_DATA_IMM(_buffer, _size) \
lfsr_data_fromimm(_buffer, _size)
#define LFSR_DATA_LEB128(_word) \
lfsr_data_fromleb128(_word)
#define LFSR_DATA_BUF(_buffer, _size) \
((lfsr_data_t){ \
.u.direct.size=_size, \
.u.direct.count=1, \
.u.direct.buffer=(const void*)(_buffer)})
#define LFSR_DATA_DISK(_block, _off, _size) \ #define LFSR_DATA_DISK(_block, _off, _size) \
((lfsr_data_t){ \ ((lfsr_data_t){ \
@@ -1001,17 +1004,11 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
.u.disk.block=_block, \ .u.disk.block=_block, \
.u.disk.off=_off}) .u.disk.off=_off})
#define LFSR_DATA_LEB128(_leb) \ // these rely on temporary allocations which is a bit precarious...
((lfsr_data_t){ \ #define LFSR_DATA_CAT(...) \
.u.buffer.size=lfs_sizeleb128(_leb), \ lfsr_data_fromcat( \
.u.buffer.leb128=(0x80000000 | (_leb)), \ (const lfsr_data_t[]){__VA_ARGS__}, \
.u.buffer.buffer=NULL}) sizeof((const lfsr_data_t[]){__VA_ARGS__}) / sizeof(lfsr_data_t))
#define LFSR_DATA_NAME(_did, _buffer, _size) \
((lfsr_data_t){ \
.u.buffer.size=lfs_sizeleb128(_did) + (_size), \
.u.buffer.leb128=(0x80000000 | (_did)), \
.u.buffer.buffer=(const void*)(_buffer)})
// These aren't true runtime-typed datas, but allows some special cases to // These aren't true runtime-typed datas, but allows some special cases to
// bypass data encoding. External context is required to access these // bypass data encoding. External context is required to access these
@@ -1019,16 +1016,16 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
// a move of all attrs from an mdir entry // a move of all attrs from an mdir entry
#define LFSR_DATA_MOVE(_mdir) \ #define LFSR_DATA_MOVE(_mdir) \
((lfsr_data_t){.u.buffer.buffer=(const void*)(const lfsr_mdir_t*){_mdir}}) ((lfsr_data_t){.u.direct.buffer=(const void*)(const lfsr_mdir_t*){_mdir}})
// a grm update, note this is mutable! we may update the grm during // a grm update, note this is mutable! we may update the grm during
// mdir commits // mdir commits
#define LFSR_DATA_GRM(_grm) \ #define LFSR_DATA_GRM(_grm) \
((lfsr_data_t){.u.buffer.buffer=(const void*)(lfsr_grm_t*){_grm}}) ((lfsr_data_t){.u.direct.buffer=(const void*)(lfsr_grm_t*){_grm}})
// writing to an unrelated trunk in the rbyd // writing to an unrelated trunk in the rbyd
#define LFSR_DATA_SHRUBATTRS(_rbyd, ...) \ #define LFSR_DATA_SHRUBATTRS(_rbyd, ...) \
((lfsr_data_t){.u.buffer.buffer=(const void*)&(const lfsr_shrubattrs_t){ \ ((lfsr_data_t){.u.direct.buffer=(const void*)&(const lfsr_shrubattrs_t){ \
.rbyd=_rbyd, \ .rbyd=_rbyd, \
.attrs=(const lfsr_attr_t[]){__VA_ARGS__}, \ .attrs=(const lfsr_attr_t[]){__VA_ARGS__}, \
.attr_count=sizeof((const lfsr_attr_t[]){__VA_ARGS__}) \ .attr_count=sizeof((const lfsr_attr_t[]){__VA_ARGS__}) \
@@ -1037,7 +1034,7 @@ static lfs_ssize_t lfsr_bd_progtag(lfs_t *lfs,
// the reason for lazily encoding inlined trunks is because they can change // the reason for lazily encoding inlined trunks is because they can change
// underneath us during mdir compaction, the horror // underneath us during mdir compaction, the horror
#define LFSR_DATA_TRUNK(_rbyd) \ #define LFSR_DATA_TRUNK(_rbyd) \
((lfsr_data_t){.u.buffer.buffer=(const void*)(lfsr_rbyd_t*){_rbyd}}) ((lfsr_data_t){.u.direct.buffer=(const void*)(lfsr_rbyd_t*){_rbyd}})
static inline bool lfsr_data_ondisk(const lfsr_data_t *data) { static inline bool lfsr_data_ondisk(const lfsr_data_t *data) {
return data->u.size & LFSR_DATA_ONDISK; return data->u.size & LFSR_DATA_ONDISK;
@@ -1047,12 +1044,44 @@ static inline lfs_size_t lfsr_data_size(const lfsr_data_t *data) {
return data->u.size & ~LFSR_DATA_ONDISK; return data->u.size & ~LFSR_DATA_ONDISK;
} }
static inline bool lfsr_data_hasleb128(const lfsr_data_t *data) { // some data initializers just can't be macros, we at least make these inline
return data->u.buffer.leb128; // so most of the internal logic gets elided
static inline lfsr_data_t lfsr_data_fromimm(
const void *buffer, lfs_size_t size) {
LFS_ASSERT(size <= 5);
lfsr_data_t data;
memcpy(data.u.inlined.buf, buffer, size);
data.u.inlined.size = size;
data.u.inlined.count = 0;
return data;
} }
static inline int32_t lfsr_data_leb128(const lfsr_data_t *data) { static inline lfsr_data_t lfsr_data_fromleb128(int32_t word) {
return data->u.buffer.leb128 & 0x7fffffff; lfsr_data_t data;
lfs_ssize_t size = lfs_toleb128(word, data.u.inlined.buf, 5);
LFS_ASSERT(size >= 0);
LFS_ASSERT(size <= 5);
data.u.inlined.size = size;
data.u.inlined.count = 0;
return data;
}
static inline lfsr_data_t lfsr_data_fromcat(
const lfsr_data_t *datas, lfs_size_t count) {
LFS_ASSERT(count >= 2);
LFS_ASSERT(count <= 255);
// find total size
lfs_size_t size = 0;
for (uint8_t i = 0; i < count; i++) {
size += lfsr_data_size(&datas[i]);
}
return (lfsr_data_t){
.u.indirect.size=size,
.u.indirect.count=count,
.u.indirect.datas=datas};
} }
static void lfsr_data_add(lfsr_data_t *data, lfs_size_t off) { static void lfsr_data_add(lfsr_data_t *data, lfs_size_t off) {
@@ -1060,14 +1089,26 @@ static void lfsr_data_add(lfsr_data_t *data, lfs_size_t off) {
// limit our off to data range // limit our off to data range
lfs_size_t off_ = lfs_min32(off, lfsr_data_size(&data_)); lfs_size_t off_ = lfs_min32(off, lfsr_data_size(&data_));
// note both these paths are the same! though I'm not sure the compiler // on-disk? increment
// is able to notice this...
if (lfsr_data_ondisk(&data_)) { if (lfsr_data_ondisk(&data_)) {
data_.u.disk.off += off_; data_.u.disk.off += off_;
data_.u.disk.size -= off_; data_.u.disk.size -= off_;
// inlined? internal memmove
} else if (data_.u.indirect.count == 0) {
memmove(data_.u.inlined.buf,
data_.u.inlined.buf + off_,
data_.u.inlined.size - off_);
data_.u.inlined.size -= off_;
// direct? increment
} else if (data_.u.indirect.count == 1) {
data_.u.direct.buffer += off_;
data_.u.direct.size -= off_;
// indirect? just update size, more on how this works in lfsr_data_read
} else { } else {
data_.u.buffer.buffer += off_; data_.u.indirect.size -= off_;
data_.u.buffer.size -= off_;
} }
*data = data_; *data = data_;
@@ -1077,25 +1118,91 @@ static void lfsr_data_add(lfsr_data_t *data, lfs_size_t off) {
// lfsr_data_read* operations update the lfsr_data_t, effectively // lfsr_data_read* operations update the lfsr_data_t, effectively
// consuming the data // consuming the data
static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t *data,
static lfs_ssize_t lfsr_data_read_(lfs_t *lfs, const lfsr_data_t *data,
void *buffer, lfs_size_t size) { void *buffer, lfs_size_t size) {
// limit our size to data range // limit our size to data range
lfsr_data_t data_ = *data; lfs_size_t d = lfs_min32(size, lfsr_data_size(data));
lfs_size_t d = lfs_min32(size, lfsr_data_size(&data_));
if (lfsr_data_ondisk(&data_)) { // on-disk?
int err = lfsr_bd_read(lfs, data_.u.disk.block, data_.u.disk.off, if (lfsr_data_ondisk(data)) {
int err = lfsr_bd_read(lfs, data->u.disk.block, data->u.disk.off,
// note our hint includes the full data range // note our hint includes the full data range
lfsr_data_size(&data_), lfsr_data_size(data),
buffer, d); buffer, d);
if (err) { if (err) {
return err; return err;
} }
} else {
// leb128 prefixes not supported here
LFS_ASSERT(!lfsr_data_hasleb128(&data_));
memcpy(buffer, data_.u.buffer.buffer, d); // inlined?
} else if (data->u.indirect.count == 0) {
memcpy(buffer, data->u.inlined.buf, d);
// direct?
} else if (data->u.indirect.count == 1) {
memcpy(buffer, data->u.direct.buffer, d);
// indirect? we shouldn't handle this here
} else {
LFS_UNREACHABLE();
}
return d;
}
static lfs_size_t lfsr_data_indirectoff(const lfsr_data_t *data) {
LFS_ASSERT(!lfsr_data_ondisk(data));
LFS_ASSERT(data->u.indirect.count >= 2);
lfs_size_t indirect_size = 0;
for (uint8_t i = 0; i < data->u.indirect.count; i++) {
indirect_size += lfsr_data_size(&data->u.indirect.datas[i]);
}
return indirect_size - data->u.indirect.size;
}
static lfs_ssize_t lfsr_data_read(lfs_t *lfs, lfsr_data_t *data,
void *buffer, lfs_size_t size) {
// handle indirect data specially to avoid recursion
lfs_ssize_t d;
if (!lfsr_data_ondisk(data) && data->u.indirect.count >= 2) {
// Indirect data is a bit complicated because we don't want to modify
// the indirect datas themselves. It's tempting to just make them
// mutable, but this breaks the common pattern of using shallow copies
// of lfsr_data_t to cheaply track progress.
//
// The solution here is to use the redundant sizes to figure out what
// we've read so far. This risks O(n^2) performance, but we usually
// only have a couple indirect datas at most
//
lfs_size_t indirect_off = lfsr_data_indirectoff(data);
uint8_t *buffer_ = buffer;
d = 0;
for (uint8_t i = 0; i < data->u.indirect.count && size > 0; i++) {
// skip consumed data
lfsr_data_t indirect_data = data->u.indirect.datas[i];
lfsr_data_add(&indirect_data, indirect_off);
indirect_off -= lfs_min32(
lfsr_data_size(&indirect_data),
indirect_off);
// read unconsumed data
lfs_ssize_t d_ = lfsr_data_read_(lfs, &indirect_data,
buffer_, size);
if (d_ < 0) {
return d_;
}
buffer_ += d_;
size -= d_;
d += d_;
}
} else {
d = lfsr_data_read_(lfs, data, buffer, size);
if (d < 0) {
return d;
}
} }
lfsr_data_add(data, d); lfsr_data_add(data, d);
@@ -1141,28 +1248,40 @@ static int lfsr_data_readleb128(lfs_t *lfs, lfsr_data_t *data,
return 0; return 0;
} }
static lfs_scmp_t lfsr_data_cmp(lfs_t *lfs, const lfsr_data_t *data, static lfs_scmp_t lfsr_data_cmp_(lfs_t *lfs, const lfsr_data_t *data,
const void *buffer, lfs_size_t size) { const void *buffer, lfs_size_t size) {
// limit our off/size to data range // limit our size to data range
lfs_size_t d = lfs_min32(size, lfsr_data_size(data)); lfs_size_t d = lfs_min32(size, lfsr_data_size(data));
// compare our data // on-disk?
if (lfsr_data_ondisk(data)) { if (lfsr_data_ondisk(data)) {
int cmp = lfsr_bd_cmp(lfs, data->u.disk.block, data->u.disk.off, 0, int cmp = lfsr_bd_cmp(lfs, data->u.disk.block, data->u.disk.off, 0,
buffer, d); buffer, d);
if (cmp != LFS_CMP_EQ) { if (cmp != LFS_CMP_EQ) {
return cmp; return cmp;
} }
} else {
// leb128 prefixes not supported here
LFS_ASSERT(!lfsr_data_hasleb128(data));
int cmp = memcmp(data->u.buffer.buffer, buffer, d); // inlined?
} else if (data->u.indirect.count == 0) {
int cmp = memcmp(data->u.inlined.buf, buffer, d);
if (cmp < 0) { if (cmp < 0) {
return LFS_CMP_LT; return LFS_CMP_LT;
} else if (cmp > 0) { } else if (cmp > 0) {
return LFS_CMP_GT; return LFS_CMP_GT;
} }
// direct?
} else if (data->u.indirect.count == 1) {
int cmp = memcmp(data->u.direct.buffer, buffer, d);
if (cmp < 0) {
return LFS_CMP_LT;
} else if (cmp > 0) {
return LFS_CMP_GT;
}
// indirect? we shouldn't handle this here
} else {
LFS_UNREACHABLE();
} }
// if data is equal, check for size mismatch // if data is equal, check for size mismatch
@@ -1175,6 +1294,52 @@ static lfs_scmp_t lfsr_data_cmp(lfs_t *lfs, const lfsr_data_t *data,
} }
} }
static lfs_scmp_t lfsr_data_cmp(lfs_t *lfs, const lfsr_data_t *data,
const void *buffer, lfs_size_t size) {
// handle indirect data specially to avoid recursion
if (!lfsr_data_ondisk(data) && data->u.indirect.count >= 2) {
// Indirect data is a bit complicated because we don't want to modify
// the indirect datas themselves. It's tempting to just make them
// mutable, but this breaks the common pattern of using shallow copies
// of lfsr_data_t to cheaply track progress.
//
// The solution here is to use the redundant sizes to figure out what
// we've read so far. This risks O(n^2) performance, but we usually
// only have a couple indirect datas at most
//
lfs_size_t indirect_off = lfsr_data_indirectoff(data);
const uint8_t *buffer_ = buffer;
for (uint8_t i = 0; i < data->u.indirect.count && size > 0; i++) {
// skip consumed data
lfsr_data_t indirect_data = data->u.indirect.datas[i];
lfsr_data_add(&indirect_data, indirect_off);
indirect_off -= lfs_min32(
lfsr_data_size(&indirect_data),
indirect_off);
// compare against unconsumed data
lfs_size_t d = lfs_min32(size, lfsr_data_size(&indirect_data));
lfs_scmp_t cmp = lfsr_data_cmp_(lfs, &indirect_data, buffer_, d);
if (cmp != LFS_CMP_EQ) {
return cmp;
}
buffer_ += d;
size -= d;
}
// data is equal, the only remaining condition to check for is size
// remaining
if (size > 0) {
return LFS_CMP_LT;
} else {
return LFS_CMP_EQ;
}
} else {
return lfsr_data_cmp_(lfs, data, buffer, size);
}
}
static lfs_scmp_t lfsr_data_namecmp(lfs_t *lfs, const lfsr_data_t *data, static lfs_scmp_t lfsr_data_namecmp(lfs_t *lfs, const lfsr_data_t *data,
lfsr_did_t did, const char *name, lfs_size_t name_size) { lfsr_did_t did, const char *name, lfs_size_t name_size) {
// first compare the did // first compare the did
@@ -1191,13 +1356,14 @@ static lfs_scmp_t lfsr_data_namecmp(lfs_t *lfs, const lfsr_data_t *data,
return LFS_CMP_GT; return LFS_CMP_GT;
} }
// next compare the actual name // then compare the actual name
return lfsr_data_cmp(lfs, &data_, name, name_size); return lfsr_data_cmp(lfs, &data_, name, name_size);
} }
static int lfsr_bd_progdata(lfs_t *lfs, static int lfsr_bd_progdata_(lfs_t *lfs,
lfs_block_t block, lfs_size_t off, lfsr_data_t data, lfs_block_t block, lfs_size_t off, lfsr_data_t data,
uint32_t *cksum_) { uint32_t *cksum_) {
// on-disk?
if (lfsr_data_ondisk(&data)) { if (lfsr_data_ondisk(&data)) {
// TODO byte-level copies have been a pain point, works for prototyping // TODO byte-level copies have been a pain point, works for prototyping
// but can this be better? configurable? leverage // but can this be better? configurable? leverage
@@ -1219,32 +1385,66 @@ static int lfsr_bd_progdata(lfs_t *lfs,
} }
} }
} else { // inlined?
// This is a bit of a hack, but lfsr_data_t can inject a single leb128 } else if (data.u.indirect.count == 0) {
// into lfsr_bd_progdata. This is needed for directory-id prefixes, int err = lfsr_bd_prog(lfs, block, off,
// but can also be used for programming single leb128s cheaply. data.u.inlined.buf, data.u.inlined.size,
if (lfsr_data_hasleb128(&data)) { cksum_);
uint8_t leb_buf[5]; if (err) {
lfs_ssize_t leb_dsize = lfs_toleb128( return err;
lfsr_data_leb128(&data), }
leb_buf, 5);
if (leb_dsize < 0) {
return leb_dsize;
}
int err = lfsr_bd_prog(lfs, block, off, // direct?
leb_buf, leb_dsize, cksum_); } else if (data.u.indirect.count == 1) {
int err = lfsr_bd_prog(lfs, block, off,
data.u.direct.buffer, data.u.direct.size,
cksum_);
if (err) {
return err;
}
// indirect? we shouldn't handle this here
} else {
LFS_UNREACHABLE();
}
return 0;
}
static int lfsr_bd_progdata(lfs_t *lfs,
lfs_block_t block, lfs_size_t off, lfsr_data_t data,
uint32_t *cksum_) {
// handle indirect data specially to avoid recursion
if (!lfsr_data_ondisk(&data) && data.u.indirect.count >= 2) {
// Indirect data is a bit complicated because we don't want to modify
// the indirect datas themselves. It's tempting to just make them
// mutable, but this breaks the common pattern of using shallow copies
// of lfsr_data_t to cheaply track progress.
//
// The solution here is to use the redundant sizes to figure out what
// we've read so far. This risks O(n^2) performance, but we usually
// only have a couple indirect datas at most
//
lfs_size_t indirect_off = lfsr_data_indirectoff(&data);
for (uint8_t i = 0; i < data.u.indirect.count; i++) {
// skip consumed data
lfsr_data_t indirect_data = data.u.indirect.datas[i];
lfsr_data_add(&indirect_data, indirect_off);
indirect_off -= lfs_min32(
lfsr_data_size(&indirect_data),
indirect_off);
// prog unconsumed data
int err = lfsr_bd_progdata_(lfs, block, off, indirect_data,
cksum_);
if (err) { if (err) {
return err; return err;
} }
off += leb_dsize; off += lfsr_data_size(&indirect_data);
LFS_ASSERT(data.u.buffer.size >= leb_dsize);
data.u.buffer.size -= leb_dsize;
} }
} else {
int err = lfsr_bd_prog(lfs, block, off, int err = lfsr_bd_progdata_(lfs, block, off, data,
data.u.buffer.buffer, lfsr_data_size(&data),
cksum_); cksum_);
if (err) { if (err) {
return err; return err;
@@ -3132,7 +3332,7 @@ static int lfsr_rbyd_appendgdelta(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
} }
} }
err = lfsr_grm_xor(lfs, grm_buf, LFSR_DATA( err = lfsr_grm_xor(lfs, grm_buf, LFSR_DATA_BUF(
&lfs->dgrm, LFSR_GRM_DSIZE)); &lfs->dgrm, LFSR_GRM_DSIZE));
if (err) { if (err) {
return err; return err;
@@ -3143,7 +3343,7 @@ static int lfsr_rbyd_appendgdelta(lfs_t *lfs, lfsr_rbyd_t *rbyd) {
err = lfsr_rbyd_appendattr(lfs, rbyd, -1, err = lfsr_rbyd_appendattr(lfs, rbyd, -1,
// opportunistically remove this tag if delta is all zero // opportunistically remove this tag if delta is all zero
(size == 0 ? LFSR_TAG_RM(GRM) : LFSR_TAG_GRM), 0, (size == 0 ? LFSR_TAG_RM(GRM) : LFSR_TAG_GRM), 0,
LFSR_DATA(grm_buf, size)); LFSR_DATA_BUF(grm_buf, size));
if (err) { if (err) {
return err; return err;
} }
@@ -3521,7 +3721,7 @@ static int lfsr_btree_lookupnext_(lfs_t *lfs,
*weight_ = lfsr_btree_weight(btree); *weight_ = lfsr_btree_weight(btree);
} }
if (data_) { if (data_) {
*data_ = LFSR_DATA(btree->u.inlined.buf, btree->u.inlined.size); *data_ = LFSR_DATA_BUF(btree->u.inlined.buf, btree->u.inlined.size);
} }
return 0; return 0;
} }
@@ -4314,7 +4514,7 @@ static int lfsr_btree_namelookup(lfs_t *lfs, const lfsr_btree_t *btree,
*weight_ = lfsr_btree_weight(btree); *weight_ = lfsr_btree_weight(btree);
} }
if (data_) { if (data_) {
*data_ = LFSR_DATA(btree->u.inlined.buf, btree->u.inlined.size); *data_ = LFSR_DATA_BUF(btree->u.inlined.buf, btree->u.inlined.size);
} }
return 0; return 0;
} }
@@ -4416,7 +4616,9 @@ static int lfsr_btree_traversal_next(lfs_t *lfs, const lfsr_btree_t *btree,
*weight_ = lfsr_btree_weight(btree); *weight_ = lfsr_btree_weight(btree);
} }
if (data_) { if (data_) {
*data_ = LFSR_DATA(btree->u.inlined.buf, btree->u.inlined.size); *data_ = LFSR_DATA_BUF(
btree->u.inlined.buf,
btree->u.inlined.size);
} }
return 0; return 0;
} }
@@ -4440,7 +4642,9 @@ static int lfsr_btree_traversal_next(lfs_t *lfs, const lfsr_btree_t *btree,
} }
if (data_) { if (data_) {
// note btrees are returned decoded // note btrees are returned decoded
*data_ = LFSR_DATA(&traversal->branch, sizeof(lfsr_rbyd_t)); *data_ = LFSR_DATA_BUF(
&traversal->branch,
sizeof(lfsr_rbyd_t));
} }
return 0; return 0;
} }
@@ -4499,7 +4703,9 @@ static int lfsr_btree_traversal_next(lfs_t *lfs, const lfsr_btree_t *btree,
} }
if (data_) { if (data_) {
// note btrees are returned decoded // note btrees are returned decoded
*data_ = LFSR_DATA(&traversal->branch, sizeof(lfsr_rbyd_t)); *data_ = LFSR_DATA_BUF(
&traversal->branch,
sizeof(lfsr_rbyd_t));
} }
return 0; return 0;
} }
@@ -5005,7 +5211,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
// 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__
= (const lfsr_mdir_t*)attrs[i].data.u.buffer.buffer; = (const lfsr_mdir_t*)attrs[i].data.u.direct.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;
@@ -5035,7 +5241,7 @@ static int lfsr_mdir_commit__(lfs_t *lfs, lfsr_mdir_t *mdir,
} else if (attrs[i].tag == LFSR_TAG_SHRUBATTRS) { } else if (attrs[i].tag == LFSR_TAG_SHRUBATTRS) {
const lfsr_shrubattrs_t *shrubattrs const lfsr_shrubattrs_t *shrubattrs
= (const lfsr_shrubattrs_t*) = (const lfsr_shrubattrs_t*)
attrs[i].data.u.buffer.buffer; attrs[i].data.u.direct.buffer;
// swap out our trunk/weight temporarily, note we're operating // swap out our trunk/weight temporarily, note we're operating
// on a copy so if this fails not _too_ many things will get // on a copy so if this fails not _too_ many things will get
@@ -5072,7 +5278,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?
} else if (lfsr_tag_key(attrs[i].tag) == LFSR_TAG_SHRUBTRUNK) { } else if (lfsr_tag_key(attrs[i].tag) == LFSR_TAG_SHRUBTRUNK) {
lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)attrs[i].data.u.buffer.buffer; lfsr_rbyd_t *rbyd = (lfsr_rbyd_t*)attrs[i].data.u.direct.buffer;
uint8_t trunk_buf[LFSR_TRUNK_DSIZE]; uint8_t trunk_buf[LFSR_TRUNK_DSIZE];
int err = lfsr_rbyd_appendattr(lfs, &mdir_.u.rbyd, int err = lfsr_rbyd_appendattr(lfs, &mdir_.u.rbyd,
@@ -5435,12 +5641,12 @@ 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++) {
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.buffer.buffer; lfsr_grm_t *grm = (lfsr_grm_t*)attrs[i].data.u.direct.buffer;
lfsr_data_fromgrm(grm, lfs->dgrm); lfsr_data_fromgrm(grm, lfs->dgrm);
// xor with our current gstate to find our initial gdelta // xor with our current gstate to find our initial gdelta
int err = lfsr_grm_xor(lfs, lfs->dgrm, int err = lfsr_grm_xor(lfs, lfs->dgrm,
LFSR_DATA(lfs->ggrm, LFSR_GRM_DSIZE)); LFSR_DATA_BUF(lfs->ggrm, LFSR_GRM_DSIZE));
if (err) { if (err) {
return err; return err;
} }
@@ -5687,7 +5893,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.buffer.buffer; lfsr_grm_t *grm = (lfsr_grm_t*)attrs[i].data.u.direct.buffer;
uint8_t grm_buf[LFSR_GRM_DSIZE]; uint8_t grm_buf[LFSR_GRM_DSIZE];
err = lfsr_grm_xor(lfs, lfs->dgrm, err = lfsr_grm_xor(lfs, lfs->dgrm,
lfsr_data_fromgrm(grm, grm_buf)); lfsr_data_fromgrm(grm, grm_buf));
@@ -5862,7 +6068,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 gstate // update gstate
if (attrs[i].tag == LFSR_TAG_GRM) { if (attrs[i].tag == LFSR_TAG_GRM) {
lfs->grm = *(lfsr_grm_t*)attrs[i].data.u.buffer.buffer; lfs->grm = *(lfsr_grm_t*)attrs[i].data.u.direct.buffer;
// keep track of the exact encoding on-disk // keep track of the exact encoding on-disk
lfsr_data_fromgrm(&lfs->grm, lfs->ggrm); lfsr_data_fromgrm(&lfs->grm, lfs->ggrm);
@@ -6284,7 +6490,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
*tag_ = LFSR_TAG_MDIR; *tag_ = LFSR_TAG_MDIR;
} }
if (data_) { if (data_) {
*data_ = LFSR_DATA(&traversal->mdir, sizeof(lfsr_mdir_t)); *data_ = LFSR_DATA_BUF(&traversal->mdir, sizeof(lfsr_mdir_t));
} }
return 0; return 0;
@@ -6348,7 +6554,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
*tag_ = LFSR_TAG_MDIR; *tag_ = LFSR_TAG_MDIR;
} }
if (data_) { if (data_) {
*data_ = LFSR_DATA(&traversal->mdir, sizeof(lfsr_mdir_t)); *data_ = LFSR_DATA_BUF(&traversal->mdir, sizeof(lfsr_mdir_t));
} }
return 0; return 0;
@@ -6398,7 +6604,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
// validate our btree nodes if requested, this just means we need // validate our btree nodes if requested, this just means we need
// to do a full rbyd fetch and make sure the checksums match // to do a full rbyd fetch and make sure the checksums match
if (traversal->flags & LFSR_MTREE_TRAVERSAL_VALIDATE) { if (traversal->flags & LFSR_MTREE_TRAVERSAL_VALIDATE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t*)data.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t*)data.u.direct.buffer;
lfsr_rbyd_t branch_; lfsr_rbyd_t branch_;
err = lfsr_rbyd_fetch(lfs, &branch_, err = lfsr_rbyd_fetch(lfs, &branch_,
branch->block, branch->trunk); branch->block, branch->trunk);
@@ -6468,7 +6674,7 @@ static int lfsr_mtree_traversal_next(lfs_t *lfs,
*tag_ = tag; *tag_ = tag;
} }
if (data_) { if (data_) {
*data_ = LFSR_DATA(&traversal->mdir, sizeof(lfsr_mdir_t)); *data_ = LFSR_DATA_BUF(&traversal->mdir, sizeof(lfsr_mdir_t));
} }
return 0; return 0;
@@ -6594,7 +6800,7 @@ static int lfsr_mountinited(lfs_t *lfs) {
continue; continue;
} }
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.u.direct.buffer;
// found an mroot? // found an mroot?
if (mdir->mid == -1) { if (mdir->mid == -1) {
// has magic string? // has magic string?
@@ -6943,7 +7149,7 @@ static int lfsr_mountinited(lfs_t *lfs) {
memcpy(lfs->ggrm, lfs->dgrm, LFSR_GRM_DSIZE); memcpy(lfs->ggrm, lfs->dgrm, LFSR_GRM_DSIZE);
// decode grm so we can report any removed files as missing // decode grm so we can report any removed files as missing
int err = lfsr_data_readgrm(lfs, &LFSR_DATA(lfs->ggrm, LFSR_GRM_DSIZE), int err = lfsr_data_readgrm(lfs, &LFSR_DATA_BUF(lfs->ggrm, LFSR_GRM_DSIZE),
&lfs->grm); &lfs->grm);
if (err) { if (err) {
return err; return err;
@@ -6992,7 +7198,7 @@ static int lfsr_formatinited(lfs_t *lfs) {
// - the root's bookmark tag, which reserves did = 0 for the root // - the root's bookmark tag, which reserves did = 0 for the root
err = lfsr_rbyd_commit(lfs, &rbyd, LFSR_ATTRS( err = lfsr_rbyd_commit(lfs, &rbyd, LFSR_ATTRS(
LFSR_ATTR(-1, MAGIC, 0, BUF("littlefs", 8)), LFSR_ATTR(-1, MAGIC, 0, BUF("littlefs", 8)),
LFSR_ATTR(-1, VERSION, 0, BUF(((const uint8_t[2]){ LFSR_ATTR(-1, VERSION, 0, IMM(((const uint8_t[2]){
LFS_DISK_VERSION_MAJOR, LFS_DISK_VERSION_MAJOR,
LFS_DISK_VERSION_MINOR}), 2)), LFS_DISK_VERSION_MINOR}), 2)),
LFSR_ATTR(-1, BLOCKLIMIT, 0, LEB128(lfs->cfg->block_size-1)), LFSR_ATTR(-1, BLOCKLIMIT, 0, LEB128(lfs->cfg->block_size-1)),
@@ -7000,7 +7206,7 @@ static int lfsr_formatinited(lfs_t *lfs) {
LFSR_ATTR(-1, MLEAFLIMIT, 0, LEB128(lfsr_mleafweight(lfs)-1)), LFSR_ATTR(-1, MLEAFLIMIT, 0, LEB128(lfsr_mleafweight(lfs)-1)),
LFSR_ATTR(-1, SIZELIMIT, 0, LEB128(0x7fffffff)), LFSR_ATTR(-1, SIZELIMIT, 0, LEB128(0x7fffffff)),
LFSR_ATTR(-1, NAMELIMIT, 0, LEB128(0xff)), LFSR_ATTR(-1, NAMELIMIT, 0, LEB128(0xff)),
LFSR_ATTR(0, BOOKMARK, +1, NAME(0, NULL, 0)))); LFSR_ATTR(0, BOOKMARK, +1, LEB128(0))));
if (err) { if (err) {
return err; return err;
} }
@@ -7161,12 +7367,12 @@ static int lfs_alloc(lfs_t *lfs, lfs_block_t *block) {
// mark any blocks we see at in-use, including any btree/mdir blocks // mark any blocks we see at in-use, including any btree/mdir blocks
if (tag == LFSR_TAG_MDIR) { if (tag == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data.u.direct.buffer;
lfs_alloc_setinuse(lfs, mdir->u.m.blocks[1]); lfs_alloc_setinuse(lfs, mdir->u.m.blocks[1]);
lfs_alloc_setinuse(lfs, mdir->u.m.blocks[0]); lfs_alloc_setinuse(lfs, mdir->u.m.blocks[0]);
} else if (tag == LFSR_TAG_BTREE) { } else if (tag == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t*)data.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t*)data.u.direct.buffer;
lfs_alloc_setinuse(lfs, branch->block); lfs_alloc_setinuse(lfs, branch->block);
} }
} }
@@ -7344,7 +7550,10 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
// commit our new directory into our parent, creating a grm to self-remove // commit our new directory into our parent, creating a grm to self-remove
// in case of powerloss // in case of powerloss
err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS( err = lfsr_mdir_commit(lfs, &mdir, LFSR_ATTRS(
LFSR_ATTR(mdir.mid, DIR, +1, NAME(did, name, name_size)), LFSR_ATTR(mdir.mid,
DIR, +1, CAT(
LFSR_DATA_LEB128(did),
LFSR_DATA_BUF(name, name_size))),
LFSR_ATTR(mdir.mid, DID, 0, LEB128(did_)), LFSR_ATTR(mdir.mid, DID, 0, LEB128(did_)),
LFSR_ATTR(-1, GRM, 0, GRM(&((lfsr_grm_t){{mdir.mid, -1}}))))); LFSR_ATTR(-1, GRM, 0, GRM(&((lfsr_grm_t){{mdir.mid, -1}})))));
if (err) { if (err) {
@@ -7356,7 +7565,7 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
// commit our bookmark and zero the grm, the bookmark tag is an empty // commit our bookmark and zero the grm, the bookmark tag is an empty
// entry that marks our did as allocated // entry that marks our did as allocated
err = lfsr_mdir_commit(lfs, &bookmark.mdir, LFSR_ATTRS( err = lfsr_mdir_commit(lfs, &bookmark.mdir, LFSR_ATTRS(
LFSR_ATTR(bookmark.mdir.mid, BOOKMARK, +1, NAME(did_, NULL, 0)), LFSR_ATTR(bookmark.mdir.mid, BOOKMARK, +1, LEB128(did_)),
LFSR_ATTR(-1, GRM, 0, GRM(&((lfsr_grm_t){{-1, -1}}))))); LFSR_ATTR(-1, GRM, 0, GRM(&((lfsr_grm_t){{-1, -1}})))));
if (err) { if (err) {
return err; return err;
@@ -7578,7 +7787,9 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
? LFSR_ATTR(new_mdir.mid, RM, -1, NULL) ? LFSR_ATTR(new_mdir.mid, RM, -1, NULL)
: LFSR_ATTR_NOOP), : LFSR_ATTR_NOOP),
LFSR_ATTR(new_mdir.mid, LFSR_ATTR(new_mdir.mid,
TAG(old_tag), +1, NAME(new_did, new_name, new_name_size)), TAG(old_tag), +1, CAT(
LFSR_DATA_LEB128(new_did),
LFSR_DATA_BUF(new_name, new_name_size))),
LFSR_ATTR(new_mdir.mid, MOVE, 0, MOVE(&old_mdir)), LFSR_ATTR(new_mdir.mid, MOVE, 0, MOVE(&old_mdir)),
LFSR_ATTR(-1, GRM, 0, GRM(&grm)))); LFSR_ATTR(-1, GRM, 0, GRM(&grm))));
if (err) { if (err) {
@@ -7941,7 +8152,9 @@ int lfsr_file_opencfg(lfs_t *lfs, lfsr_file_t *file,
// TODO or is it? ;) // TODO or is it? ;)
err = lfsr_mdir_commit(lfs, &file->m.mdir, LFSR_ATTRS( err = lfsr_mdir_commit(lfs, &file->m.mdir, LFSR_ATTRS(
LFSR_ATTR(file->m.mdir.mid, LFSR_ATTR(file->m.mdir.mid,
REG, +1, NAME(did, name, name_size)))); REG, +1, CAT(
LFSR_DATA_LEB128(did),
LFSR_DATA_BUF(name, name_size)))));
if (err) { if (err) {
return err; return err;
} }
+24 -7
View File
@@ -432,19 +432,36 @@ typedef struct lfsr_data {
// After removing the sign bit, the size always encodes the resulting // After removing the sign bit, the size always encodes the resulting
// size on-disk. // size on-disk.
// //
// After this the count field indicates the in-device representation,
// which has a few forms:
// - count == 0 => data inlined in data struct
// - count == 1 => direct pointer to data
// - count >= 2 => indirect pointer to array of datas
//
// The indirect pointer can point to inlined/direct datas or even
// on-disk datas, but not more indirect datas as that would require
// recursion.
//
lfs_ssize_t size; lfs_ssize_t size;
struct { struct {
lfs_ssize_t size; lfs_ssize_t size;
// This leb128 field is a bit of a hack that allows a single leb128 uint8_t count;
// to be injected into lfsr_bd_progdata. Outside of uint8_t buf[5];
// lfsr_bd_progdata, this field is invalid! } inlined;
int32_t leb128; struct {
const uint8_t *buffer; lfs_ssize_t size;
} buffer; uint8_t count;
const uint8_t *buffer;
} direct;
struct {
lfs_ssize_t size;
uint8_t count;
const struct lfsr_data *datas;
} indirect;
struct { struct {
lfs_ssize_t size; lfs_ssize_t size;
lfs_size_t off;
lfs_block_t block; lfs_block_t block;
lfs_size_t off;
} disk; } disk;
} u; } u;
} lfsr_data_t; } lfsr_data_t;
-5
View File
@@ -344,11 +344,6 @@ ssize_t lfs_toleb128(int32_t word, void *buffer, size_t size);
ssize_t lfs_fromleb128(int32_t *word, const void *buffer, size_t size); ssize_t lfs_fromleb128(int32_t *word, const void *buffer, size_t size);
static inline size_t lfs_sizeleb128(int32_t word) {
// this is the size of the leb128 after encoding
return (lfs_nlog2(word+1)+7-1) / 7;
}
// Calculate CRC-32 with polynomial = 0x04c11db7 // Calculate CRC-32 with polynomial = 0x04c11db7
+160 -151
View File
@@ -147,7 +147,7 @@ code = '''
// create a single-entry tree // create a single-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -186,9 +186,9 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -232,9 +232,9 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -279,11 +279,11 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1,
LFSR_DATA("c", 1)) => 0; LFSR_DATA_BUF("c", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -333,11 +333,11 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("c", 1)) => 0; LFSR_DATA_BUF("c", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -393,7 +393,7 @@ code = '''
lfs_size_t n = 0; lfs_size_t n = 0;
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -445,7 +445,7 @@ code = '''
lfs_size_t n = 0; lfs_size_t n = 0;
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[(N-1-i) % 26], 1)); LFSR_DATA_BUF(&alphas[(N-1-i) % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -512,7 +512,7 @@ code = '''
// add to btree // add to btree
int err = lfsr_btree_push(&lfs, &btree, bid, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, bid, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -583,7 +583,7 @@ code = '''
lfs_size_t n = 0; lfs_size_t n = 0;
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W, int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -678,7 +678,7 @@ code = '''
// add to btree // add to btree
int err = lfsr_btree_push(&lfs, &btree, int err = lfsr_btree_push(&lfs, &btree,
weighted_bid, LFSR_TAG_INLINED, weight, weighted_bid, LFSR_TAG_INLINED, weight,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -790,10 +790,10 @@ code = '''
// create a single-entry tree // create a single-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
// update the tree // update the tree
lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("A", 1)) => 0; LFSR_DATA_BUF("A", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -831,14 +831,14 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
// update the tree // update the tree
lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("A", 1)) => 0; LFSR_DATA_BUF("A", 1)) => 0;
lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("B", 1)) => 0; LFSR_DATA_BUF("B", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -882,18 +882,18 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1,
LFSR_DATA("c", 1)) => 0; LFSR_DATA_BUF("c", 1)) => 0;
// update the tree // update the tree
lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("A", 1)) => 0; LFSR_DATA_BUF("A", 1)) => 0;
lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("B", 1)) => 0; LFSR_DATA_BUF("B", 1)) => 0;
lfsr_btree_set(&lfs, &btree, 2, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 2, LFSR_TAG_INLINED, 1,
LFSR_DATA("C", 1)) => 0; LFSR_DATA_BUF("C", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -947,7 +947,7 @@ code = '''
const char *uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -961,7 +961,7 @@ code = '''
// update the tree // update the tree
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_set(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_set(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&uppers[i % 26], 1)); LFSR_DATA_BUF(&uppers[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1019,7 +1019,7 @@ code = '''
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1047,7 +1047,7 @@ code = '''
// update btree // update btree
int err = lfsr_btree_set(&lfs, &btree, bid, LFSR_TAG_INLINED, 1, int err = lfsr_btree_set(&lfs, &btree, bid, LFSR_TAG_INLINED, 1,
LFSR_DATA(&uppers[i % 26], 1)); LFSR_DATA_BUF(&uppers[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -1115,7 +1115,7 @@ code = '''
const char *uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char *uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W, int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1129,7 +1129,7 @@ code = '''
// update the tree // update the tree
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_set(&lfs, &btree, i*W+W-1, LFSR_TAG_INLINED, W, int err = lfsr_btree_set(&lfs, &btree, i*W+W-1, LFSR_TAG_INLINED, W,
LFSR_DATA(&uppers[i % 26], 1)); LFSR_DATA_BUF(&uppers[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1203,7 +1203,7 @@ code = '''
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W, int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1242,7 +1242,7 @@ code = '''
// update btree // update btree
int err = lfsr_btree_set(&lfs, &btree, int err = lfsr_btree_set(&lfs, &btree,
weighted_bid+sim_weights[bid]-1, LFSR_TAG_INLINED, weight, weighted_bid+sim_weights[bid]-1, LFSR_TAG_INLINED, weight,
LFSR_DATA(&uppers[i % 26], 1)); LFSR_DATA_BUF(&uppers[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -1351,7 +1351,7 @@ code = '''
// create a single-entry tree // create a single-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
// pop! // pop!
lfsr_btree_pop(&lfs, &btree, 0) => 0; lfsr_btree_pop(&lfs, &btree, 0) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1370,7 +1370,7 @@ code = '''
// try to putting it back to see if things still work // try to putting it back to see if things still work
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("A", 1)) => 0; LFSR_DATA_BUF("A", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -1404,9 +1404,9 @@ code = '''
// create a single-entry tree // create a single-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
// pop! // pop!
lfsr_btree_pop(&lfs, &btree, 1) => 0; lfsr_btree_pop(&lfs, &btree, 1) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1431,7 +1431,7 @@ code = '''
// try to putting it back to see if things still work // try to putting it back to see if things still work
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("B", 1)) => 0; LFSR_DATA_BUF("B", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -1471,9 +1471,9 @@ code = '''
// create a single-entry tree // create a single-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
// pop! // pop!
lfsr_btree_pop(&lfs, &btree, 0) => 0; lfsr_btree_pop(&lfs, &btree, 0) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1498,7 +1498,7 @@ code = '''
// try to putting it back to see if things still work // try to putting it back to see if things still work
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("A", 1)) => 0; LFSR_DATA_BUF("A", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -1538,11 +1538,11 @@ code = '''
// create a single-entry tree // create a single-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1,
LFSR_DATA("c", 1)) => 0; LFSR_DATA_BUF("c", 1)) => 0;
// pop! // pop!
lfsr_btree_pop(&lfs, &btree, 2) => 0; lfsr_btree_pop(&lfs, &btree, 2) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1573,7 +1573,7 @@ code = '''
// try to putting it back to see if things still work // try to putting it back to see if things still work
lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 2, LFSR_TAG_INLINED, 1,
LFSR_DATA("C", 1)) => 0; LFSR_DATA_BUF("C", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -1624,7 +1624,7 @@ code = '''
const char *alphas = "abcdefghijklmnopqrstuvwxyz"; const char *alphas = "abcdefghijklmnopqrstuvwxyz";
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1674,7 +1674,7 @@ code = '''
// try recovering // try recovering
lfsr_btree_push(&lfs, &btree, REMAINING, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, REMAINING, LFSR_TAG_INLINED, 1,
LFSR_DATA("R", 1)) => 0; LFSR_DATA_BUF("R", 1)) => 0;
for (lfs_size_t i = 0; i < REMAINING; i++) { for (lfs_size_t i = 0; i < REMAINING; i++) {
lfsr_btree_get(&lfs, &btree, i, lfsr_btree_get(&lfs, &btree, i,
@@ -1715,7 +1715,7 @@ code = '''
const char *alphas = "abcdefghijklmnopqrstuvwxyz"; const char *alphas = "abcdefghijklmnopqrstuvwxyz";
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1764,7 +1764,7 @@ code = '''
// try recovering // try recovering
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("R", 1)) => 0; LFSR_DATA_BUF("R", 1)) => 0;
lfsr_btree_get(&lfs, &btree, 0, lfsr_btree_get(&lfs, &btree, 0,
&tag_, &weight_, buffer, 4) => 1; &tag_, &weight_, buffer, 4) => 1;
@@ -1807,7 +1807,7 @@ code = '''
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1905,7 +1905,7 @@ code = '''
const char *alphas = "abcdefghijklmnopqrstuvwxyz"; const char *alphas = "abcdefghijklmnopqrstuvwxyz";
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W, int err = lfsr_btree_push(&lfs, &btree, i*W, LFSR_TAG_INLINED, W,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -1954,7 +1954,7 @@ code = '''
// try recovering // try recovering
lfsr_btree_push(&lfs, &btree, REMAINING*W, LFSR_TAG_INLINED, W, lfsr_btree_push(&lfs, &btree, REMAINING*W, LFSR_TAG_INLINED, W,
LFSR_DATA("R", 1)) => 0; LFSR_DATA_BUF("R", 1)) => 0;
for (lfs_size_t i = 0; i < REMAINING; i++) { for (lfs_size_t i = 0; i < REMAINING; i++) {
lfsr_btree_get(&lfs, &btree, i*W+W-1, lfsr_btree_get(&lfs, &btree, i*W+W-1,
@@ -2045,7 +2045,7 @@ code = '''
int err = lfsr_btree_push(&lfs, &btree, int err = lfsr_btree_push(&lfs, &btree,
weighted_bid, LFSR_TAG_INLINED, weight, weighted_bid, LFSR_TAG_INLINED, weight,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
@@ -2183,12 +2183,12 @@ code = '''
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
const char *alphas = "abcdefghijklmnopqrstuvwxyz"; const char *alphas = "abcdefghijklmnopqrstuvwxyz";
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[0 % 26], 1)) => 0; LFSR_DATA_BUF(&alphas[0 % 26], 1)) => 0;
lfs_size_t n = 1; lfs_size_t n = 1;
for (lfs_size_t i = 1; i < N; i++) { for (lfs_size_t i = 1; i < N; i++) {
int err = lfsr_btree_split(&lfs, &btree, i-1, LFSR_DATA_NULL, int err = lfsr_btree_split(&lfs, &btree, i-1, LFSR_DATA_NULL,
LFSR_TAG_INLINED, 1, LFSR_DATA(&alphas[(i-1) % 26], 1), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&alphas[(i-1) % 26], 1),
LFSR_TAG_INLINED, 1, LFSR_DATA(&alphas[(i-0) % 26], 1)); LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&alphas[(i-0) % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -2241,7 +2241,7 @@ code = '''
// create a btree // create a btree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
// set up a simulation to compare against // set up a simulation to compare against
// //
@@ -2259,8 +2259,8 @@ code = '''
// split btree // split btree
int err = lfsr_btree_split(&lfs, &btree, bid, LFSR_DATA_NULL, int err = lfsr_btree_split(&lfs, &btree, bid, LFSR_DATA_NULL,
LFSR_TAG_INLINED, 1, LFSR_DATA(&alphas[i % 26], 1), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&alphas[i % 26], 1),
LFSR_TAG_INLINED, 1, LFSR_DATA(&uppers[i % 26], 1)); LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&uppers[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -2330,12 +2330,12 @@ code = '''
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
const char *alphas = "abcdefghijklmnopqrstuvwxyz"; const char *alphas = "abcdefghijklmnopqrstuvwxyz";
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W,
LFSR_DATA(&alphas[0 % 26], 1)) => 0; LFSR_DATA_BUF(&alphas[0 % 26], 1)) => 0;
lfs_size_t n = 1; lfs_size_t n = 1;
for (lfs_size_t i = 1; i < N; i++) { for (lfs_size_t i = 1; i < N; i++) {
int err = lfsr_btree_split(&lfs, &btree, (i-1)*W+W-1, LFSR_DATA_NULL, int err = lfsr_btree_split(&lfs, &btree, (i-1)*W+W-1, LFSR_DATA_NULL,
LFSR_TAG_INLINED, W, LFSR_DATA(&alphas[(i-1) % 26], 1), LFSR_TAG_INLINED, W, LFSR_DATA_BUF(&alphas[(i-1) % 26], 1),
LFSR_TAG_INLINED, W, LFSR_DATA(&alphas[(i-0) % 26], 1)); LFSR_TAG_INLINED, W, LFSR_DATA_BUF(&alphas[(i-0) % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -2389,7 +2389,7 @@ code = '''
// create a btree // create a btree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
// set up a simulation to compare against // set up a simulation to compare against
// //
@@ -2421,9 +2421,9 @@ code = '''
int err = lfsr_btree_split(&lfs, &btree, int err = lfsr_btree_split(&lfs, &btree,
weighted_bid+sim_weights[bid]-1, LFSR_DATA_NULL, weighted_bid+sim_weights[bid]-1, LFSR_DATA_NULL,
LFSR_TAG_INLINED, weight1, LFSR_TAG_INLINED, weight1,
LFSR_DATA(&alphas[i % 26], 1), LFSR_DATA_BUF(&alphas[i % 26], 1),
LFSR_TAG_INLINED, weight2, LFSR_TAG_INLINED, weight2,
LFSR_DATA(&uppers[i % 26], 1)); LFSR_DATA_BUF(&uppers[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -2566,19 +2566,19 @@ code = '''
// the extra push here avoids trying to inline the big entry // the extra push here avoids trying to inline the big entry
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
uint8_t buf1[SIZE]; uint8_t buf1[SIZE];
memset(buf1, 'a', SIZE); memset(buf1, 'a', SIZE);
uint8_t buf2[SIZE]; uint8_t buf2[SIZE];
memset(buf2, 'b', SIZE); memset(buf2, 'b', SIZE);
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL, lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL,
LFSR_TAG_INLINED, 1, LFSR_DATA(buf1, SIZE), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf1, SIZE),
LFSR_TAG_INLINED, 1, LFSR_DATA(buf2, SIZE)) => 0; LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf2, SIZE)) => 0;
// force compaction // force compaction
btree.u.rbyd.eoff = -1; btree.u.rbyd.eoff = -1;
memset(buf2, 'b', SIZE); memset(buf2, 'b', SIZE);
lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA(buf2, SIZE)) => 0; LFSR_DATA_BUF(buf2, SIZE)) => 0;
assert(lfsr_btree_weight(&btree) == 2); assert(lfsr_btree_weight(&btree) == 2);
// now remove one entry, since this brings the rbyd down to zero, // now remove one entry, since this brings the rbyd down to zero,
@@ -2628,19 +2628,19 @@ code = '''
// the extra push here avoids trying to inline the big entry // the extra push here avoids trying to inline the big entry
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
uint8_t buf1[SIZE]; uint8_t buf1[SIZE];
memset(buf1, 'a', SIZE); memset(buf1, 'a', SIZE);
uint8_t buf2[SIZE]; uint8_t buf2[SIZE];
memset(buf2, 'b', SIZE); memset(buf2, 'b', SIZE);
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL, lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL,
LFSR_TAG_INLINED, 1, LFSR_DATA(buf1, SIZE), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf1, SIZE),
LFSR_TAG_INLINED, 1, LFSR_DATA(buf2, SIZE)) => 0; LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf2, SIZE)) => 0;
// force compaction // force compaction
btree.u.rbyd.eoff = -1; btree.u.rbyd.eoff = -1;
memset(buf2, 'b', SIZE); memset(buf2, 'b', SIZE);
lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA(buf2, SIZE)) => 0; LFSR_DATA_BUF(buf2, SIZE)) => 0;
assert(lfsr_btree_weight(&btree) == 2); assert(lfsr_btree_weight(&btree) == 2);
// now remove one entry, since this brings the rbyd down this zero, // now remove one entry, since this brings the rbyd down this zero,
@@ -2693,14 +2693,14 @@ code = '''
// the extra push here avoids trying to inline the big entry // the extra push here avoids trying to inline the big entry
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
uint8_t buf1[SIZE]; uint8_t buf1[SIZE];
memset(buf1, 'a', SIZE); memset(buf1, 'a', SIZE);
uint8_t buf2[SIZE]; uint8_t buf2[SIZE];
memset(buf2, 'b', SIZE); memset(buf2, 'b', SIZE);
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL, lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL,
LFSR_TAG_INLINED, 1, LFSR_DATA(buf1, SIZE), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf1, SIZE),
LFSR_TAG_INLINED, 1, LFSR_DATA(buf2, SIZE)) => 0; LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf2, SIZE)) => 0;
// force compaction, causing a split, but while we're splitting, // force compaction, causing a split, but while we're splitting,
// also remove an entry, bringing the split rbyd down to zero mid split // also remove an entry, bringing the split rbyd down to zero mid split
@@ -2753,26 +2753,26 @@ code = '''
// the extra push here avoids trying to inline the big entry // the extra push here avoids trying to inline the big entry
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
uint8_t buf1[SIZE]; uint8_t buf1[SIZE];
memset(buf1, 'a', SIZE); memset(buf1, 'a', SIZE);
uint8_t buf2[SIZE]; uint8_t buf2[SIZE];
memset(buf2, 'b', SIZE); memset(buf2, 'b', SIZE);
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL, lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NULL,
LFSR_TAG_INLINED, 1, LFSR_DATA(buf1, SIZE), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf1, SIZE),
LFSR_TAG_INLINED, 1, LFSR_DATA(buf2, SIZE)) => 0; LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(buf2, SIZE)) => 0;
// force compaction // force compaction
btree.u.rbyd.eoff = -1; btree.u.rbyd.eoff = -1;
memset(buf2, 'b', SIZE); memset(buf2, 'b', SIZE);
lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA(buf2, SIZE)) => 0; LFSR_DATA_BUF(buf2, SIZE)) => 0;
assert(lfsr_btree_weight(&btree) == 2); assert(lfsr_btree_weight(&btree) == 2);
// now make both entries small so they should be merged if either compacts // now make both entries small so they should be merged if either compacts
lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("a", 1)) => 0; LFSR_DATA_BUF("a", 1)) => 0;
lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1, lfsr_btree_set(&lfs, &btree, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA("b", 1)) => 0; LFSR_DATA_BUF("b", 1)) => 0;
// force compaction, while removing one entry, this drops the rbyd // force compaction, while removing one entry, this drops the rbyd
// down to zero while also triggering a merge // down to zero while also triggering a merge
@@ -2840,7 +2840,7 @@ code = '''
// push to btree // push to btree
int err = lfsr_btree_push(&lfs, &btree, bid, int err = lfsr_btree_push(&lfs, &btree, bid,
LFSR_TAG_INLINED, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -2856,7 +2856,7 @@ code = '''
// update btree // update btree
int err = lfsr_btree_set(&lfs, &btree, bid, int err = lfsr_btree_set(&lfs, &btree, bid,
LFSR_TAG_INLINED, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -2967,7 +2967,7 @@ code = '''
// push to btree // push to btree
int err = lfsr_btree_push(&lfs, &btree, weighted_bid, int err = lfsr_btree_push(&lfs, &btree, weighted_bid,
LFSR_TAG_INLINED, weight, LFSR_TAG_INLINED, weight,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -2986,7 +2986,7 @@ code = '''
// update btree // update btree
int err = lfsr_btree_set(&lfs, &btree, int err = lfsr_btree_set(&lfs, &btree,
weighted_bid+sim_weights[bid]-1, LFSR_TAG_INLINED, weight, weighted_bid+sim_weights[bid]-1, LFSR_TAG_INLINED, weight,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3142,7 +3142,7 @@ code = '''
// create a single-entry tree // create a single-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("0", 1)) => 0; LFSR_DATA_BUF("0", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -3191,10 +3191,11 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("0", 1)) => 0; LFSR_DATA_BUF("0", 1)) => 0;
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NAME(0, "aab", 3), lfsr_btree_split(&lfs, &btree, 0,
LFSR_TAG_INLINED, 1, LFSR_DATA("0", 1), LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF("aab", 3)),
LFSR_TAG_INLINED, 1, LFSR_DATA("1", 1)) => 0; LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("0", 1),
LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("1", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -3251,13 +3252,15 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("0", 1)) => 0; LFSR_DATA_BUF("0", 1)) => 0;
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NAME(1*DID, "aab", 3), lfsr_btree_split(&lfs, &btree, 0,
LFSR_TAG_INLINED, 1, LFSR_DATA("0", 1), LFSR_DATA_CAT(LFSR_DATA_LEB128(1*DID), LFSR_DATA_BUF("aab", 3)),
LFSR_TAG_INLINED, 1, LFSR_DATA("1", 1)) => 0; LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("0", 1),
lfsr_btree_split(&lfs, &btree, 1, LFSR_DATA_NAME(2*DID, "aac", 3), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("1", 1)) => 0;
LFSR_TAG_INLINED, 1, LFSR_DATA("1", 1), lfsr_btree_split(&lfs, &btree, 1,
LFSR_TAG_INLINED, 1, LFSR_DATA("2", 1)) => 0; LFSR_DATA_CAT(LFSR_DATA_LEB128(2*DID), LFSR_DATA_BUF("aac", 3)),
LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("1", 1),
LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("2", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -3322,13 +3325,15 @@ code = '''
// create a two-entry tree // create a two-entry tree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("0", 1)) => 0; LFSR_DATA_BUF("0", 1)) => 0;
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NAME(2*DID, "aac", 3), lfsr_btree_split(&lfs, &btree, 0,
LFSR_TAG_INLINED, 1, LFSR_DATA("1", 1), LFSR_DATA_CAT(LFSR_DATA_LEB128(2*DID), LFSR_DATA_BUF("aac", 3)),
LFSR_TAG_INLINED, 1, LFSR_DATA("2", 1)) => 0; LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("1", 1),
lfsr_btree_split(&lfs, &btree, 0, LFSR_DATA_NAME(1*DID, "aab", 3), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("2", 1)) => 0;
LFSR_TAG_INLINED, 1, LFSR_DATA("0", 1), lfsr_btree_split(&lfs, &btree, 0,
LFSR_TAG_INLINED, 1, LFSR_DATA("1", 1)) => 0; LFSR_DATA_CAT(LFSR_DATA_LEB128(1*DID), LFSR_DATA_BUF("aab", 3)),
LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("0", 1),
LFSR_TAG_INLINED, 1, LFSR_DATA_BUF("1", 1)) => 0;
printf("btree: w%d 0x%x.%x\n", printf("btree: w%d 0x%x.%x\n",
btree.u.rbyd.weight, btree.u.rbyd.weight,
btree.u.rbyd.block, btree.u.rbyd.block,
@@ -3396,16 +3401,16 @@ code = '''
const char *alphas = "abcdefghijklmnopqrstuvwxyz"; const char *alphas = "abcdefghijklmnopqrstuvwxyz";
const char *nums = "0123456789"; const char *nums = "0123456789";
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA(&nums[0 % 10], 1)) => 0; LFSR_DATA_BUF(&nums[0 % 10], 1)) => 0;
lfs_size_t n = 1; lfs_size_t n = 1;
for (lfs_size_t i = 1; i < N; i++) { for (lfs_size_t i = 1; i < N; i++) {
char name[3] = { char name[3] = {
alphas[(i/26/26) % 26], alphas[(i/26) % 26], alphas[i % 26] alphas[(i/26/26) % 26], alphas[(i/26) % 26], alphas[i % 26]
}; };
int err = lfsr_btree_split(&lfs, &btree, i-1, int err = lfsr_btree_split(&lfs, &btree, i-1,
LFSR_DATA_NAME(i*DID, name, 3), LFSR_DATA_CAT(LFSR_DATA_LEB128(i*DID), LFSR_DATA_BUF(name, 3)),
LFSR_TAG_INLINED, 1, LFSR_DATA(&nums[(i-1) % 10], 1), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&nums[(i-1) % 10], 1),
LFSR_TAG_INLINED, 1, LFSR_DATA(&nums[(i-0) % 10], 1)); LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&nums[(i-0) % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3462,7 +3467,7 @@ code = '''
// create a btree // create a btree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
// set up a simulation to compare against // set up a simulation to compare against
// //
@@ -3496,9 +3501,9 @@ code = '''
// split btree // split btree
int err = lfsr_btree_split(&lfs, &btree, bid, int err = lfsr_btree_split(&lfs, &btree, bid,
LFSR_DATA_NAME(0, name, 3), LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF(name, 3)),
LFSR_TAG_INLINED, 1, LFSR_DATA(&nums[i % 10], 1), LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&nums[i % 10], 1),
LFSR_TAG_INLINED, 1, LFSR_DATA(&nums[i % 10], 1)); LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&nums[i % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3574,16 +3579,16 @@ code = '''
const char *alphas = "abcdefghijklmnopqrstuvwxyz"; const char *alphas = "abcdefghijklmnopqrstuvwxyz";
const char *nums = "0123456789"; const char *nums = "0123456789";
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W,
LFSR_DATA(&nums[0 % 10], 1)) => 0; LFSR_DATA_BUF(&nums[0 % 10], 1)) => 0;
lfs_size_t n = 1; lfs_size_t n = 1;
for (lfs_size_t i = 1; i < N; i++) { for (lfs_size_t i = 1; i < N; i++) {
char name[3] = { char name[3] = {
alphas[(i/26/26) % 26], alphas[(i/26) % 26], alphas[i % 26] alphas[(i/26/26) % 26], alphas[(i/26) % 26], alphas[i % 26]
}; };
int err = lfsr_btree_split(&lfs, &btree, int err = lfsr_btree_split(&lfs, &btree, (i-1)*W+W-1,
(i-1)*W+W-1, LFSR_DATA_NAME(i*DID, name, 3), LFSR_DATA_CAT(LFSR_DATA_LEB128(i*DID), LFSR_DATA_BUF(name, 3)),
LFSR_TAG_INLINED, W, LFSR_DATA(&nums[(i-1) % 10], 1), LFSR_TAG_INLINED, W, LFSR_DATA_BUF(&nums[(i-1) % 10], 1),
LFSR_TAG_INLINED, W, LFSR_DATA(&nums[(i-0) % 10], 1)); LFSR_TAG_INLINED, W, LFSR_DATA_BUF(&nums[(i-0) % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3641,7 +3646,7 @@ code = '''
// create a btree // create a btree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
// set up a simulation to compare against // set up a simulation to compare against
// //
@@ -3688,9 +3693,9 @@ code = '''
// split btree // split btree
int err = lfsr_btree_split(&lfs, &btree, int err = lfsr_btree_split(&lfs, &btree,
weighted_bid+sim_weights[bid]-1, weighted_bid+sim_weights[bid]-1,
LFSR_DATA_NAME(0, name, 3), LFSR_DATA_CAT(LFSR_DATA_LEB128(0), LFSR_DATA_BUF(name, 3)),
LFSR_TAG_INLINED, weight1, LFSR_DATA(&nums[i % 10], 1), LFSR_TAG_INLINED, weight1, LFSR_DATA_BUF(&nums[i % 10], 1),
LFSR_TAG_INLINED, weight2, LFSR_DATA(&nums[i % 10], 1)); LFSR_TAG_INLINED, weight2, LFSR_DATA_BUF(&nums[i % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3792,7 +3797,7 @@ code = '''
// create a btree // create a btree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, 1,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
// set up a simulation to compare against // set up a simulation to compare against
// //
@@ -3841,11 +3846,11 @@ code = '''
if (split_bid > bid) { if (split_bid > bid) {
int err = lfsr_btree_split(&lfs, &btree, int err = lfsr_btree_split(&lfs, &btree,
split_bid, split_bid,
LFSR_DATA_NAME(0, sim_names[bid+1], 3), LFSR_DATA_CAT(
LFSR_TAG_INLINED, 1, LFSR_DATA_LEB128(0),
LFSR_DATA(&nums[i % 10], 1), LFSR_DATA_BUF(sim_names[bid+1], 3)),
LFSR_TAG_INLINED, 1, LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&nums[i % 10], 1),
LFSR_DATA(split_buf, 1)); LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(split_buf, 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3853,11 +3858,11 @@ code = '''
assert(err == 0); assert(err == 0);
} else { } else {
int err = lfsr_btree_split(&lfs, &btree, int err = lfsr_btree_split(&lfs, &btree,
split_bid, LFSR_DATA_NAME(0, name, 3), split_bid, LFSR_DATA_CAT(
LFSR_TAG_INLINED, 1, LFSR_DATA_LEB128(0),
LFSR_DATA(split_buf, 1), LFSR_DATA_BUF(name, 3)),
LFSR_TAG_INLINED, 1, LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(split_buf, 1),
LFSR_DATA(&nums[i % 10], 1)); LFSR_TAG_INLINED, 1, LFSR_DATA_BUF(&nums[i % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3876,7 +3881,7 @@ code = '''
// update btree // update btree
int err = lfsr_btree_set(&lfs, &btree, bid, int err = lfsr_btree_set(&lfs, &btree, bid,
LFSR_TAG_INLINED, 1, LFSR_TAG_INLINED, 1,
LFSR_DATA(&nums[i % 10], 1)); LFSR_DATA_BUF(&nums[i % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -3967,7 +3972,7 @@ code = '''
// create a btree // create a btree
lfsr_btree_t btree = LFSR_BTREE_NULL; lfsr_btree_t btree = LFSR_BTREE_NULL;
lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W, lfsr_btree_push(&lfs, &btree, 0, LFSR_TAG_INLINED, W,
LFSR_DATA("_", 1)) => 0; LFSR_DATA_BUF("_", 1)) => 0;
// set up a simulation to compare against // set up a simulation to compare against
// //
@@ -4033,24 +4038,28 @@ code = '''
uint8_t split_buf[4]; uint8_t split_buf[4];
lfsr_data_read(&lfs, &split_data, split_buf, 4) => 1; lfsr_data_read(&lfs, &split_data, split_buf, 4) => 1;
if (split_bid > weighted_bid+sim_weights[bid]-1) { if (split_bid > weighted_bid+sim_weights[bid]-1) {
int err = lfsr_btree_split(&lfs, &btree, int err = lfsr_btree_split(&lfs, &btree, split_bid,
split_bid, LFSR_DATA_NAME(0, sim_names[bid+1], 3), LFSR_DATA_CAT(
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(sim_names[bid+1], 3)),
LFSR_TAG_INLINED, weight, LFSR_TAG_INLINED, weight,
LFSR_DATA(&nums[i % 10], 1), LFSR_DATA_BUF(&nums[i % 10], 1),
LFSR_TAG_INLINED, split_weight, LFSR_TAG_INLINED, split_weight,
LFSR_DATA(split_buf, 1)); LFSR_DATA_BUF(split_buf, 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
} }
assert(err == 0); assert(err == 0);
} else { } else {
int err = lfsr_btree_split(&lfs, &btree, int err = lfsr_btree_split(&lfs, &btree, split_bid,
split_bid, LFSR_DATA_NAME(0, name, 3), LFSR_DATA_CAT(
LFSR_DATA_LEB128(0),
LFSR_DATA_BUF(name, 3)),
LFSR_TAG_INLINED, split_weight, LFSR_TAG_INLINED, split_weight,
LFSR_DATA(split_buf, 1), LFSR_DATA_BUF(split_buf, 1),
LFSR_TAG_INLINED, weight, LFSR_TAG_INLINED, weight,
LFSR_DATA(&nums[i % 10], 1)); LFSR_DATA_BUF(&nums[i % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -4072,7 +4081,7 @@ code = '''
// update btree // update btree
int err = lfsr_btree_set(&lfs, &btree, int err = lfsr_btree_set(&lfs, &btree,
weighted_bid+sim_weights[bid]-1, LFSR_TAG_INLINED, weight, weighted_bid+sim_weights[bid]-1, LFSR_TAG_INLINED, weight,
LFSR_DATA(&nums[i % 10], 1)); LFSR_DATA_BUF(&nums[i % 10], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -4191,7 +4200,7 @@ code = '''
lfs_size_t n = 0; lfs_size_t n = 0;
for (lfs_size_t i = 0; i < N; i++) { for (lfs_size_t i = 0; i < N; i++) {
int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, i, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -4244,7 +4253,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d 0x%x w%d btree 0x%x.%x\n", printf("traversal: %d 0x%x w%d btree 0x%x.%x\n",
bid_, bid_,
tag_, tag_,
@@ -4324,7 +4333,7 @@ code = '''
// add to btree // add to btree
int err = lfsr_btree_push(&lfs, &btree, bid, LFSR_TAG_INLINED, 1, int err = lfsr_btree_push(&lfs, &btree, bid, LFSR_TAG_INLINED, 1,
LFSR_DATA(&alphas[i % 26], 1)); LFSR_DATA_BUF(&alphas[i % 26], 1));
// ignore space issues // ignore space issues
if (err == LFS_ERR_NOSPC) { if (err == LFS_ERR_NOSPC) {
break; break;
@@ -4392,7 +4401,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d 0x%x w%d btree 0x%x.%x\n", printf("traversal: %d 0x%x w%d btree 0x%x.%x\n",
bid_, bid_,
tag_, tag_,
+14 -14
View File
@@ -3465,7 +3465,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3475,7 +3475,7 @@ code = '''
// keep track of seen blocks // keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8); seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) { } else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3589,7 +3589,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3599,7 +3599,7 @@ code = '''
// keep track of seen blocks // keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8); seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) { } else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3724,7 +3724,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3734,7 +3734,7 @@ code = '''
// keep track of seen blocks // keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8); seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) { } else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3851,7 +3851,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3861,7 +3861,7 @@ code = '''
// keep track of seen blocks // keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8); seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) { } else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3989,7 +3989,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -3999,7 +3999,7 @@ code = '''
// keep track of seen blocks // keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8); seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) { } else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -4159,7 +4159,7 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -4169,7 +4169,7 @@ code = '''
// keep track of seen blocks // keep track of seen blocks
seen[branch->block / 8] |= 1 << (branch->block % 8); seen[branch->block / 8] |= 1 << (branch->block % 8);
} else if (tag_ == LFSR_TAG_MDIR) { } else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
@@ -4267,14 +4267,14 @@ code = '''
} }
if (tag_ == LFSR_TAG_BTREE) { if (tag_ == LFSR_TAG_BTREE) {
lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.buffer.buffer; lfsr_rbyd_t *branch = (lfsr_rbyd_t *)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x btree 0x%x.%x\n", printf("traversal: %d.%d 0x%x btree 0x%x.%x\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),
tag_, tag_,
branch->block, branch->trunk); branch->block, branch->trunk);
} else if (tag_ == LFSR_TAG_MDIR) { } else if (tag_ == LFSR_TAG_MDIR) {
lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.buffer.buffer; lfsr_mdir_t *mdir = (lfsr_mdir_t*)data_.u.direct.buffer;
printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n", printf("traversal: %d.%d 0x%x mdir 0x{%x,%x}\n",
mid_ >> lfs.mleaf_bits, mid_ >> lfs.mleaf_bits,
mid_ & lfsr_midrmask(&lfs), mid_ & lfsr_midrmask(&lfs),