Adopted lfsr_data_t hole representation in readnext functions

This avoids needing to return the mostly-redundant weight in the
readnext functions, and allows passing the returned data directly to
lfsr_data_read/lfsr_bd_progdata when needed.

            code          stack
  before:  31396           2064
  after:   31316 (-0.3%)   2064 (+0.0%)
This commit is contained in:
Christopher Haster
2023-10-25 23:59:19 -05:00
parent 13192f3f6b
commit e6d736dba9
+36 -104
View File
@@ -9024,7 +9024,7 @@ static int lfsr_shrub_lookupnext(lfs_t *lfs, const lfsr_shrub_t *shrub,
static int lfsr_shrub_readnext(lfs_t *lfs, const lfsr_shrub_t *shrub,
lfs_off_t pos, lfs_off_t size,
lfs_off_t *weight_, lfsr_data_t *data_) {
lfsr_data_t *data_) {
lfsr_rid_t rid;
lfsr_tag_t tag;
lfsr_rid_t weight;
@@ -9041,10 +9041,6 @@ static int lfsr_shrub_readnext(lfs_t *lfs, const lfsr_shrub_t *shrub,
lfs_off_t d = lfs_min32(
size,
lfsr_data_size(&data) - (pos - (rid-(weight-1))));
if (weight_) {
*weight_ = d;
}
if (data_) {
*data_ = LFSR_DATA_DISK(
data.u.disk.block,
@@ -9056,15 +9052,8 @@ static int lfsr_shrub_readnext(lfs_t *lfs, const lfsr_shrub_t *shrub,
// found a hole, just make sure next leaf takes priority
lfs_off_t d = lfs_min32(size, rid+1 - pos);
// TODO should we have a special LFSR_DATA_HOLE representation?
// found a hole?
if (weight_) {
*weight_ = d;
}
if (data_) {
*data_ = LFSR_DATA_NULL;
*data_ = LFSR_DATA_HOLE(d);
}
return 0;
}
@@ -9147,7 +9136,7 @@ static int lfsr_tree_lookupnext(lfs_t *lfs, const lfsr_tree_t *tree,
static int lfsr_tree_readnext(lfs_t *lfs, const lfsr_tree_t *tree,
lfs_off_t pos, lfs_off_t size,
lfs_off_t *weight_, lfsr_data_t *data_) {
lfsr_data_t *data_) {
lfsr_bid_t bid;
lfsr_tag_t tag;
lfsr_bid_t weight;
@@ -9164,10 +9153,6 @@ static int lfsr_tree_readnext(lfs_t *lfs, const lfsr_tree_t *tree,
lfs_off_t d = lfs_min32(
size,
lfsr_data_size(&data) - (pos - (bid-(weight-1))));
if (weight_) {
*weight_ = d;
}
if (data_) {
*data_ = LFSR_DATA_DISK(
data.u.disk.block,
@@ -9179,22 +9164,15 @@ static int lfsr_tree_readnext(lfs_t *lfs, const lfsr_tree_t *tree,
// found a hole, just make sure next leaf takes priority
lfs_off_t d = lfs_min32(size, bid+1 - pos);
// TODO should we have a special LFSR_DATA_HOLE representation?
// found a hole?
if (weight_) {
*weight_ = d;
}
if (data_) {
*data_ = LFSR_DATA_NULL;
*data_ = LFSR_DATA_HOLE(d);
}
return 0;
}
static int lfsr_file_readnext(lfs_t *lfs, const lfsr_file_t *file,
lfs_off_t pos, lfs_off_t size,
lfs_off_t *weight_, lfsr_data_t *data_) {
lfsr_data_t *data_) {
// past end of file?
if (pos >= file->size) {
return LFS_ERR_NOENT;
@@ -9209,10 +9187,6 @@ static int lfsr_file_readnext(lfs_t *lfs, const lfsr_file_t *file,
d = lfs_min32(
d,
file->buffer_size - (pos - file->buffer_pos));
if (weight_) {
*weight_ = d;
}
if (data_) {
*data_ = LFSR_DATA_BUF(
&file->buffer[pos - file->buffer_pos],
@@ -9227,20 +9201,16 @@ static int lfsr_file_readnext(lfs_t *lfs, const lfsr_file_t *file,
// any data in our shrub?
if (pos < lfsr_shrub_size(&file->shrub)) {
lfs_off_t weight;
lfsr_data_t data;
int err = lfsr_shrub_readnext(lfs, &file->shrub, pos, d,
&weight, &data);
&data);
if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err;
}
// found data?
if (lfsr_data_size(&data) > 0) {
if (weight_) {
*weight_ = weight;
}
if (!lfsr_data_ishole(&data)) {
if (data_) {
*data_ = data;
}
@@ -9248,25 +9218,21 @@ static int lfsr_file_readnext(lfs_t *lfs, const lfsr_file_t *file,
}
// found a hole, just make sure next leaf takes priority
d = lfs_min32(d, weight);
d = lfs_min32(d, lfsr_data_size(&data));
}
// any data in our tree?
if (pos < lfsr_tree_size(&file->tree)) {
lfs_off_t weight;
lfsr_data_t data;
int err = lfsr_tree_readnext(lfs, &file->tree, pos, d,
&weight, &data);
&data);
if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err;
}
// found data?
if (lfsr_data_size(&data) > 0) {
if (weight_) {
*weight_ = weight;
}
if (!lfsr_data_ishole(&data)) {
if (data_) {
*data_ = data;
}
@@ -9274,17 +9240,12 @@ static int lfsr_file_readnext(lfs_t *lfs, const lfsr_file_t *file,
}
// found a hole, just make sure next leaf takes priority
d = lfs_min32(d, weight);
d = lfs_min32(d, lfsr_data_size(&data));
}
// TODO should we have a special LFSR_DATA_HOLE representation?
// found a hole?
if (weight_) {
*weight_ = d;
}
if (data_) {
*data_ = LFSR_DATA_NULL;
*data_ = LFSR_DATA_HOLE(d);
}
return 0;
}
@@ -9297,11 +9258,10 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
lfs_off_t pos = file->pos;
uint8_t *buffer_ = buffer;
while (size > 0) {
// read each data/hole
lfs_off_t weight;
// find a data/hole
lfsr_data_t data;
int err = lfsr_file_readnext(lfs, file, pos, size,
&weight, &data);
&data);
if (err) {
// hit end of file?
if (err == LFS_ERR_NOENT) {
@@ -9309,28 +9269,18 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
}
return err;
}
LFS_ASSERT(weight > 0);
LFS_ASSERT(lfsr_data_size(&data) > 0);
// found data?
if (lfsr_data_size(&data) > 0) {
lfs_ssize_t d = lfsr_data_read(lfs, &data,
buffer_, size);
if (d < 0) {
return d;
}
pos += d;
buffer_ += d;
size -= d;
// found a hole? just fill with zeros
} else {
memset(buffer_, 0, weight);
pos += weight;
buffer_ += weight;
size -= weight;
// read from disk
lfs_ssize_t d = lfsr_data_read(lfs, &data,
buffer_, size);
if (d < 0) {
return d;
}
pos += d;
buffer_ += d;
size -= d;
}
lfs_size_t read = pos - file->pos;
@@ -9978,22 +9928,21 @@ static int lfsr_file_flushshrub(lfs_t *lfs, lfsr_file_t *file) {
// any data in our shrub?
if (pos < lfsr_shrub_size(&file->shrub)) {
lfs_off_t weight;
int err = lfsr_shrub_readnext(lfs, &file->shrub, pos, d,
&weight, &data);
&data);
if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err;
}
// found data?
if (lfsr_data_size(&data) > 0) {
if (!lfsr_data_ishole(&data)) {
d = lfsr_data_size(&data);
goto flush;
}
// found a hole, just make sure next leaf takes priority
d = lfs_min32(d, weight);
d = lfs_min32(d, lfsr_data_size(&data));
}
// found a hole? skip
@@ -10083,10 +10032,9 @@ static int lfsr_file_flushshrub(lfs_t *lfs, lfsr_file_t *file) {
// copy any data underneath our block into our block
lfs_off_t pos_ = left_align;
while (pos_ < right_align) {
lfs_off_t weight;
lfsr_data_t data;
err = lfsr_file_readnext(lfs, file, pos_, right_align - pos_,
&weight, &data);
&data);
if (err) {
// end of file?
if (err == LFS_ERR_NOENT) {
@@ -10094,33 +10042,17 @@ static int lfsr_file_flushshrub(lfs_t *lfs, lfsr_file_t *file) {
}
return err;
}
LFS_ASSERT(weight > 0);
LFS_ASSERT(lfsr_data_size(&data) > 0);
// found data? prog
if (lfsr_data_size(&data) > 0) {
err = lfsr_bd_progdata(lfs, block, pos_ - left_align,
data,
NULL);
if (err) {
return err;
}
// TODO can we do this more efficiently? lfsr_bd_progzero?
// use this via lfsr_data_t hole representation?
//
// found a hole? fill with zeros
} else {
for (lfs_size_t j = 0; j < weight; j++) {
err = lfsr_bd_prog(lfs, block, pos_ - left_align + j,
&(uint8_t){0}, 1,
NULL);
if (err) {
return err;
}
}
// prog data/hole
err = lfsr_bd_progdata(lfs, block, pos_ - left_align,
data,
NULL);
if (err) {
return err;
}
pos_ += weight;
pos_ += lfsr_data_size(&data);
}
// TODO validate?