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
+23 -91
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, static int lfsr_shrub_readnext(lfs_t *lfs, const lfsr_shrub_t *shrub,
lfs_off_t pos, lfs_off_t size, 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_rid_t rid;
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_rid_t weight; 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( lfs_off_t d = lfs_min32(
size, size,
lfsr_data_size(&data) - (pos - (rid-(weight-1)))); lfsr_data_size(&data) - (pos - (rid-(weight-1))));
if (weight_) {
*weight_ = d;
}
if (data_) { if (data_) {
*data_ = LFSR_DATA_DISK( *data_ = LFSR_DATA_DISK(
data.u.disk.block, 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 // found a hole, just make sure next leaf takes priority
lfs_off_t d = lfs_min32(size, rid+1 - pos); 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_) { if (data_) {
*data_ = LFSR_DATA_NULL; *data_ = LFSR_DATA_HOLE(d);
} }
return 0; 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, static int lfsr_tree_readnext(lfs_t *lfs, const lfsr_tree_t *tree,
lfs_off_t pos, lfs_off_t size, 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_bid_t bid;
lfsr_tag_t tag; lfsr_tag_t tag;
lfsr_bid_t weight; 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( lfs_off_t d = lfs_min32(
size, size,
lfsr_data_size(&data) - (pos - (bid-(weight-1)))); lfsr_data_size(&data) - (pos - (bid-(weight-1))));
if (weight_) {
*weight_ = d;
}
if (data_) { if (data_) {
*data_ = LFSR_DATA_DISK( *data_ = LFSR_DATA_DISK(
data.u.disk.block, 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 // found a hole, just make sure next leaf takes priority
lfs_off_t d = lfs_min32(size, bid+1 - pos); 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_) { if (data_) {
*data_ = LFSR_DATA_NULL; *data_ = LFSR_DATA_HOLE(d);
} }
return 0; return 0;
} }
static int lfsr_file_readnext(lfs_t *lfs, const lfsr_file_t *file, static int lfsr_file_readnext(lfs_t *lfs, const lfsr_file_t *file,
lfs_off_t pos, lfs_off_t size, lfs_off_t pos, lfs_off_t size,
lfs_off_t *weight_, lfsr_data_t *data_) { lfsr_data_t *data_) {
// past end of file? // past end of file?
if (pos >= file->size) { if (pos >= file->size) {
return LFS_ERR_NOENT; 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 = lfs_min32(
d, d,
file->buffer_size - (pos - file->buffer_pos)); file->buffer_size - (pos - file->buffer_pos));
if (weight_) {
*weight_ = d;
}
if (data_) { if (data_) {
*data_ = LFSR_DATA_BUF( *data_ = LFSR_DATA_BUF(
&file->buffer[pos - file->buffer_pos], &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? // any data in our shrub?
if (pos < lfsr_shrub_size(&file->shrub)) { if (pos < lfsr_shrub_size(&file->shrub)) {
lfs_off_t weight;
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_shrub_readnext(lfs, &file->shrub, pos, d, int err = lfsr_shrub_readnext(lfs, &file->shrub, pos, d,
&weight, &data); &data);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
return err; return err;
} }
// found data? // found data?
if (lfsr_data_size(&data) > 0) { if (!lfsr_data_ishole(&data)) {
if (weight_) {
*weight_ = weight;
}
if (data_) { if (data_) {
*data_ = 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 // 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? // any data in our tree?
if (pos < lfsr_tree_size(&file->tree)) { if (pos < lfsr_tree_size(&file->tree)) {
lfs_off_t weight;
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_tree_readnext(lfs, &file->tree, pos, d, int err = lfsr_tree_readnext(lfs, &file->tree, pos, d,
&weight, &data); &data);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
return err; return err;
} }
// found data? // found data?
if (lfsr_data_size(&data) > 0) { if (!lfsr_data_ishole(&data)) {
if (weight_) {
*weight_ = weight;
}
if (data_) { if (data_) {
*data_ = 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 // 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? // found a hole?
if (weight_) {
*weight_ = d;
}
if (data_) { if (data_) {
*data_ = LFSR_DATA_NULL; *data_ = LFSR_DATA_HOLE(d);
} }
return 0; 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; lfs_off_t pos = file->pos;
uint8_t *buffer_ = buffer; uint8_t *buffer_ = buffer;
while (size > 0) { while (size > 0) {
// read each data/hole // find a data/hole
lfs_off_t weight;
lfsr_data_t data; lfsr_data_t data;
int err = lfsr_file_readnext(lfs, file, pos, size, int err = lfsr_file_readnext(lfs, file, pos, size,
&weight, &data); &data);
if (err) { if (err) {
// hit end of file? // hit end of file?
if (err == LFS_ERR_NOENT) { if (err == LFS_ERR_NOENT) {
@@ -9309,10 +9269,9 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
} }
return err; return err;
} }
LFS_ASSERT(weight > 0); LFS_ASSERT(lfsr_data_size(&data) > 0);
// found data? // read from disk
if (lfsr_data_size(&data) > 0) {
lfs_ssize_t d = lfsr_data_read(lfs, &data, lfs_ssize_t d = lfsr_data_read(lfs, &data,
buffer_, size); buffer_, size);
if (d < 0) { if (d < 0) {
@@ -9322,15 +9281,6 @@ lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
pos += d; pos += d;
buffer_ += d; buffer_ += d;
size -= d; size -= d;
// found a hole? just fill with zeros
} else {
memset(buffer_, 0, weight);
pos += weight;
buffer_ += weight;
size -= weight;
}
} }
lfs_size_t read = pos - file->pos; 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? // any data in our shrub?
if (pos < lfsr_shrub_size(&file->shrub)) { if (pos < lfsr_shrub_size(&file->shrub)) {
lfs_off_t weight;
int err = lfsr_shrub_readnext(lfs, &file->shrub, pos, d, int err = lfsr_shrub_readnext(lfs, &file->shrub, pos, d,
&weight, &data); &data);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT); LFS_ASSERT(err != LFS_ERR_NOENT);
return err; return err;
} }
// found data? // found data?
if (lfsr_data_size(&data) > 0) { if (!lfsr_data_ishole(&data)) {
d = lfsr_data_size(&data); d = lfsr_data_size(&data);
goto flush; goto flush;
} }
// found a hole, just make sure next leaf takes priority // 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 // 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 // copy any data underneath our block into our block
lfs_off_t pos_ = left_align; lfs_off_t pos_ = left_align;
while (pos_ < right_align) { while (pos_ < right_align) {
lfs_off_t weight;
lfsr_data_t data; lfsr_data_t data;
err = lfsr_file_readnext(lfs, file, pos_, right_align - pos_, err = lfsr_file_readnext(lfs, file, pos_, right_align - pos_,
&weight, &data); &data);
if (err) { if (err) {
// end of file? // end of file?
if (err == LFS_ERR_NOENT) { if (err == LFS_ERR_NOENT) {
@@ -10094,10 +10042,9 @@ static int lfsr_file_flushshrub(lfs_t *lfs, lfsr_file_t *file) {
} }
return err; return err;
} }
LFS_ASSERT(weight > 0); LFS_ASSERT(lfsr_data_size(&data) > 0);
// found data? prog // prog data/hole
if (lfsr_data_size(&data) > 0) {
err = lfsr_bd_progdata(lfs, block, pos_ - left_align, err = lfsr_bd_progdata(lfs, block, pos_ - left_align,
data, data,
NULL); NULL);
@@ -10105,22 +10052,7 @@ static int lfsr_file_flushshrub(lfs_t *lfs, lfsr_file_t *file) {
return err; return err;
} }
// TODO can we do this more efficiently? lfsr_bd_progzero? pos_ += lfsr_data_size(&data);
// 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;
}
}
}
pos_ += weight;
} }
// TODO validate? // TODO validate?