Reworked lfsr_file_read a bit
- Merged lfsr_file_read_ back into lfsr_file_read, I don't think we need stateless reads in the end. - Tweaked reads to use conservative hints instead of just filling all cache lines with whatever is in the retrieved datas. - Switched to if/else for sprout/shrub and bptr/btree checks. Though this had no affect on code size, which isn't too surprising.
This commit is contained in:
@@ -1458,9 +1458,6 @@ static int lfsr_bd_progdata(lfs_t *lfs,
|
|||||||
while (pos - lfsr_data_pos(&data) < size) {
|
while (pos - lfsr_data_pos(&data) < size) {
|
||||||
lfs_off_t d = size - (pos - lfsr_data_pos(&data));
|
lfs_off_t d = size - (pos - lfsr_data_pos(&data));
|
||||||
|
|
||||||
// TODO can we take this iteration of our read loop and update
|
|
||||||
// lfsr_file_read_ with lessons learned?
|
|
||||||
|
|
||||||
// TODO deduplicate this into some sort of data-returning
|
// TODO deduplicate this into some sort of data-returning
|
||||||
// lfsr_file_iter?
|
// lfsr_file_iter?
|
||||||
|
|
||||||
@@ -9019,12 +9016,17 @@ int lfsr_file_close(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// direct read function without state updates
|
lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
|
||||||
int lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
void *buffer, lfs_size_t size) {
|
||||||
lfs_off_t pos, void *buffer, lfs_size_t size) {
|
LFS_ASSERT(lfsr_file_isreadable(file));
|
||||||
LFS_ASSERT(pos <= 0x7fffffff);
|
LFS_ASSERT(file->pos + size <= 0x7fffffff);
|
||||||
LFS_ASSERT(size <= 0x7fffffff);
|
|
||||||
|
|
||||||
|
// limit to our file size
|
||||||
|
size = lfs_min32(
|
||||||
|
size,
|
||||||
|
file->size - lfs_min32(file->pos, file->size));
|
||||||
|
|
||||||
|
lfs_off_t pos = file->pos;
|
||||||
uint8_t *buffer_ = buffer;
|
uint8_t *buffer_ = buffer;
|
||||||
while (size > 0) {
|
while (size > 0) {
|
||||||
lfs_ssize_t d = size;
|
lfs_ssize_t d = size;
|
||||||
@@ -9047,25 +9049,29 @@ int lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
|||||||
d = lfs_min32(d, file->buffer_pos - pos);
|
d = lfs_min32(d, file->buffer_pos - pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the data in a sprout?
|
// has a sprout?
|
||||||
if (lfsr_file_hassprout(file) && pos < lfsr_file_inlinedsize(file)) {
|
if (lfsr_file_hassprout(file)
|
||||||
// TODO these probably shouldn't be using lfsr_data_read, it's
|
&& pos < lfsr_file_inlinedsize(file)) {
|
||||||
// providing the wrong read hint
|
// note we use bd read directly to provide a strict hint
|
||||||
lfsr_data_t data = file->inlined.u.data;
|
d = lfs_min32(
|
||||||
lfsr_data_add(&data, pos);
|
d,
|
||||||
d = lfsr_data_read(lfs, &data, buffer_, d);
|
lfsr_data_size(&file->inlined.u.data));
|
||||||
if (d < 0) {
|
int err = lfsr_bd_read(lfs,
|
||||||
return d;
|
file->inlined.u.data.u.disk.block,
|
||||||
|
file->inlined.u.data.u.disk.off + pos, d,
|
||||||
|
buffer_, d);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += d;
|
pos += d;
|
||||||
buffer_ += d;
|
buffer_ += d;
|
||||||
size -= d;
|
size -= d;
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// is the data in a shrub?
|
// has a shrub?
|
||||||
if (lfsr_file_hasshrub(file) && pos < lfsr_file_inlinedsize(file)) {
|
} else if (lfsr_file_hasshrub(file)
|
||||||
|
&& pos < lfsr_file_inlinedsize(file)) {
|
||||||
lfsr_srid_t rid;
|
lfsr_srid_t rid;
|
||||||
lfsr_tag_t tag;
|
lfsr_tag_t tag;
|
||||||
lfsr_rid_t weight;
|
lfsr_rid_t weight;
|
||||||
@@ -9080,12 +9086,16 @@ int lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
|||||||
LFS_ASSERT(lfsr_data_size(&data) <= weight);
|
LFS_ASSERT(lfsr_data_size(&data) <= weight);
|
||||||
|
|
||||||
if (pos < rid-(weight-1) + lfsr_data_size(&data)) {
|
if (pos < rid-(weight-1) + lfsr_data_size(&data)) {
|
||||||
// TODO these probably shouldn't be using lfsr_data_read, it's
|
// note we use bd read directly to provide a strict hint
|
||||||
// providing the wrong read hint
|
d = lfs_min32(
|
||||||
lfsr_data_add(&data, pos - (rid-(weight-1)));
|
d,
|
||||||
d = lfsr_data_read(lfs, &data, buffer_, d);
|
lfsr_data_size(&data) - (pos - (rid-(weight-1))));
|
||||||
if (d < 0) {
|
int err = lfsr_bd_read(lfs,
|
||||||
return d;
|
data.u.disk.block,
|
||||||
|
data.u.disk.off + (pos - (rid-(weight-1))), d,
|
||||||
|
buffer_, d);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += d;
|
pos += d;
|
||||||
@@ -9098,9 +9108,12 @@ int lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
|||||||
d = lfs_min32(d, rid+1 - pos);
|
d = lfs_min32(d, rid+1 - pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the data in a block?
|
// has a direct block?
|
||||||
if (lfsr_file_hasbptr(file) && pos < lfsr_file_bsize(file)) {
|
if (lfsr_file_hasbptr(file)
|
||||||
d = lfs_min32(d, file->u.bptr.size - pos);
|
&& pos < lfsr_file_bsize(file)) {
|
||||||
|
d = lfs_min32(
|
||||||
|
d,
|
||||||
|
file->u.bptr.size - pos);
|
||||||
int err = lfsr_bd_read(lfs, file->u.bptr.block,
|
int err = lfsr_bd_read(lfs, file->u.bptr.block,
|
||||||
file->u.bptr.off + pos, d,
|
file->u.bptr.off + pos, d,
|
||||||
buffer_, d);
|
buffer_, d);
|
||||||
@@ -9112,10 +9125,10 @@ int lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
|||||||
buffer_ -= d;
|
buffer_ -= d;
|
||||||
size -= d;
|
size -= d;
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// is the data in a btree?
|
// has an indirect btree?
|
||||||
if (lfsr_file_hasbtree(file) && pos < lfsr_file_bsize(file)) {
|
} else if (lfsr_file_hasbtree(file)
|
||||||
|
&& pos < lfsr_file_bsize(file)) {
|
||||||
lfsr_bid_t bid;
|
lfsr_bid_t bid;
|
||||||
lfsr_tag_t tag;
|
lfsr_tag_t tag;
|
||||||
lfsr_bid_t weight;
|
lfsr_bid_t weight;
|
||||||
@@ -9130,12 +9143,16 @@ int lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
|||||||
if (tag == LFSR_TAG_INLINED) {
|
if (tag == LFSR_TAG_INLINED) {
|
||||||
LFS_ASSERT(lfsr_data_size(&data) <= weight);
|
LFS_ASSERT(lfsr_data_size(&data) <= weight);
|
||||||
if (pos < bid-(weight-1) + lfsr_data_size(&data)) {
|
if (pos < bid-(weight-1) + lfsr_data_size(&data)) {
|
||||||
// TODO these probably shouldn't be using lfsr_data_read,
|
// note we use bd read directly to provide a strict hint
|
||||||
// it's providing the wrong read hint
|
d = lfs_min32(
|
||||||
lfsr_data_add(&data, pos - (bid-(weight-1)));
|
d,
|
||||||
d = lfsr_data_read(lfs, &data, buffer_, d);
|
lfsr_data_size(&data) - (pos - (bid-(weight-1))));
|
||||||
if (d < 0) {
|
int err = lfsr_bd_read(lfs,
|
||||||
return d;
|
data.u.disk.block,
|
||||||
|
data.u.disk.off + (pos - (bid-(weight-1))), d,
|
||||||
|
buffer_, d);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += d;
|
pos += d;
|
||||||
@@ -9181,23 +9198,9 @@ int lfsr_file_read_(lfs_t *lfs, const lfsr_file_t *file,
|
|||||||
size -= d;
|
size -= d;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
lfs_size_t read = pos - file->pos;
|
||||||
}
|
file->pos = pos;
|
||||||
|
return read;
|
||||||
lfs_ssize_t lfsr_file_read(lfs_t *lfs, lfsr_file_t *file,
|
|
||||||
void *buffer, lfs_size_t size) {
|
|
||||||
LFS_ASSERT(lfsr_file_isreadable(file));
|
|
||||||
|
|
||||||
lfs_ssize_t d = lfs_min32(
|
|
||||||
size,
|
|
||||||
file->size - lfs_min32(file->pos, file->size));
|
|
||||||
int err = lfsr_file_read_(lfs, file, file->pos, buffer, d);
|
|
||||||
if (err < 0) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->pos += d;
|
|
||||||
return d;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO deduplicate carveshrub and flushinlined
|
// TODO deduplicate carveshrub and flushinlined
|
||||||
@@ -10158,7 +10161,9 @@ static int lfsr_file_flushbuffer(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
|
lfs_ssize_t lfsr_file_write(lfs_t *lfs, lfsr_file_t *file,
|
||||||
const void *buffer, lfs_size_t size) {
|
const void *buffer, lfs_size_t size) {
|
||||||
LFS_ASSERT(lfsr_file_iswriteable(file));
|
LFS_ASSERT(lfsr_file_iswriteable(file));
|
||||||
LFS_ASSERT(size <= 0x7fffffff);
|
// TODO wait, this conflicts with the EFBIG below... should this be
|
||||||
|
// an assert or error?
|
||||||
|
LFS_ASSERT(file->pos + size <= 0x7fffffff);
|
||||||
|
|
||||||
// would this write make our file larger than our size limit?
|
// would this write make our file larger than our size limit?
|
||||||
if (size > lfs->size_limit - file->pos) {
|
if (size > lfs->size_limit - file->pos) {
|
||||||
|
|||||||
Reference in New Issue
Block a user