Adopted similar mark-if-truncate-to-zero logic for file caches
It worked well for file leaves, so we might as well adopt the same
post-truncate/fruncate logic for caches.
This moves checks for cache.size==0 from lfs3_file_write into
lfs3_file_truncate/fruncate.
Note that lfs3_file_truncate/fruncate are the only functions (for now)
that can reduce the size of a file.
Adds a bit of code, which is probably why this wasn't adopted earlier,
but it reduces the state we need to worry about and makes things easier
to understand:
code stack ctx
before: 37468 2464 656
after: 37492 (+0.1%) 2464 (+0.0%) 656 (+0.0%)
This commit is contained in:
@@ -13332,8 +13332,7 @@ lfs3_ssize_t lfs3_file_write(lfs3_t *lfs3, lfs3_file_t *file,
|
|||||||
// strictly necessary, but enforces a more intuitive write order
|
// strictly necessary, but enforces a more intuitive write order
|
||||||
// and avoids weird cases with low-level write heuristics
|
// and avoids weird cases with low-level write heuristics
|
||||||
//
|
//
|
||||||
if ((!lfs3_o_isunflush(file->b.o.flags)
|
if (!lfs3_o_isunflush(file->b.o.flags)
|
||||||
|| file->cache.size == 0)
|
|
||||||
&& size >= lfs3_file_cachesize(lfs3, file)) {
|
&& size >= lfs3_file_cachesize(lfs3, file)) {
|
||||||
err = lfs3_file_flush_(lfs3, file,
|
err = lfs3_file_flush_(lfs3, file,
|
||||||
pos, buffer_, size);
|
pos, buffer_, size);
|
||||||
@@ -13369,16 +13368,14 @@ lfs3_ssize_t lfs3_file_write(lfs3_t *lfs3, lfs3_file_t *file,
|
|||||||
// 2. Bypassing the cache above means we only write to the
|
// 2. Bypassing the cache above means we only write to the
|
||||||
// cache once, and flush at most twice.
|
// cache once, and flush at most twice.
|
||||||
//
|
//
|
||||||
if ((!lfs3_o_isunflush(file->b.o.flags)
|
if (!lfs3_o_isunflush(file->b.o.flags)
|
||||||
|| file->cache.size == 0)
|
|
||||||
|| (pos >= file->cache.pos
|
|| (pos >= file->cache.pos
|
||||||
&& pos <= file->cache.pos + file->cache.size
|
&& pos <= file->cache.pos + file->cache.size
|
||||||
&& pos
|
&& pos
|
||||||
< file->cache.pos
|
< file->cache.pos
|
||||||
+ lfs3_file_cachesize(lfs3, file))) {
|
+ lfs3_file_cachesize(lfs3, file))) {
|
||||||
// unused cache? we can move it where we need it
|
// unused cache? we can move it where we need it
|
||||||
if ((!lfs3_o_isunflush(file->b.o.flags)
|
if (!lfs3_o_isunflush(file->b.o.flags)) {
|
||||||
|| file->cache.size == 0)) {
|
|
||||||
file->cache.pos = pos;
|
file->cache.pos = pos;
|
||||||
file->cache.size = 0;
|
file->cache.size = 0;
|
||||||
}
|
}
|
||||||
@@ -14006,6 +14003,10 @@ int lfs3_file_truncate(lfs3_t *lfs3, lfs3_file_t *file, lfs3_off_t size_) {
|
|||||||
file->cache.size,
|
file->cache.size,
|
||||||
size_ - lfs3_min(file->cache.pos, size_));
|
size_ - lfs3_min(file->cache.pos, size_));
|
||||||
file->cache.pos = lfs3_min(file->cache.pos, size_);
|
file->cache.pos = lfs3_min(file->cache.pos, size_);
|
||||||
|
// mark as flushed if this completely truncates our cache
|
||||||
|
if (file->cache.size == 0) {
|
||||||
|
lfs3_file_discardcache(file);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -14102,6 +14103,10 @@ int lfs3_file_fruncate(lfs3_t *lfs3, lfs3_file_t *file, lfs3_off_t size_) {
|
|||||||
file->cache.pos -= lfs3_smin(
|
file->cache.pos -= lfs3_smin(
|
||||||
size - size_,
|
size - size_,
|
||||||
file->cache.pos);
|
file->cache.pos);
|
||||||
|
// mark as flushed if this completely truncates our cache
|
||||||
|
if (file->cache.size == 0) {
|
||||||
|
lfs3_file_discardcache(file);
|
||||||
|
}
|
||||||
|
|
||||||
// fruncate _does_ update pos, to keep the same pos relative to end
|
// fruncate _does_ update pos, to keep the same pos relative to end
|
||||||
// of file, though we can't let pos go negative
|
// of file, though we can't let pos go negative
|
||||||
|
|||||||
Reference in New Issue
Block a user