Skip to content

Commit

Permalink
Modified robekras's optimization to avoid flush for all seeks in cache
Browse files Browse the repository at this point in the history
The basic idea is simple, if we seek to a position in the currently
loaded cache, don't flush the cache. Notably this ensures that seek is
always as fast or faster than just reading the data.

This is a bit tricky since we need to check that our new block and
offset match the cache, fortunately we can skip the block check by
reevaluating the block index for both the current and new positions.

Note this only works whene reading, for writing we need to always flush
the cache, or else we will lose the pending write data.
  • Loading branch information
geky committed Apr 10, 2022
1 parent a6f01b7 commit 425dc81
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions lfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3091,17 +3091,23 @@ static lfs_soff_t lfs_file_rawseek(lfs_t *lfs, lfs_file_t *file,
return npos;
}

// Get the difference between new and current file position
// If new position is after the current file position
// If new position belongs to the currently cached data
// Set new file position,
// and update also the block related position
int offset = npos - file->pos;
if (offset > 0) {
if ((file->off + offset) < lfs->cfg->block_size) {
file->pos = npos;
file->off += offset;

// if we're only reading and our new offset is still in the file's cache
// we can avoid flushing and needing to reread the data
if (
#ifndef LFS_READONLY
!(file->flags & LFS_F_WRITING)
#else
true
#endif
) {
int oindex = lfs_ctz_index(lfs, &(lfs_off_t){file->pos});
lfs_off_t noff = npos;
int nindex = lfs_ctz_index(lfs, &noff);
if (oindex == nindex
&& noff >= file->cache.off
&& noff < file->cache.off + file->cache.size) {
file->pos = npos;
file->off = noff;
return npos;
}
}
Expand Down

0 comments on commit 425dc81

Please sign in to comment.