Cleaned up post-file->leaf code a bit
Mostly adding convenience functions to deduplicate code:
- Adopted lfsr_bptr_claim
- Renamed lfsr_file_graft -> lfsr_file_graft_
- Adopted lfsr_file_graft
- Didn't bother with lfsr_file_discardleaf
This saves a bit of code, though not that much in the context of the
file->leaf code cost:
code stack ctx
before cleanup: 37228 2328 636
after: 37180 (-0.1%) 2360 (+1.4%) 636 (+0.0%)
code stack ctx
before file->leaf: 36016 2296 636
after: 37180 (+3.2%) 2360 (+2.8%) 636 (+0.0%)
This commit is contained in:
@@ -2599,6 +2599,14 @@ static void lfsr_bptr_discard(lfsr_bptr_t *bptr) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lfsr_bptr_claim(lfsr_bptr_t *bptr) {
|
||||||
|
#ifdef LFS_CKDATACKSUMS
|
||||||
|
bptr->data.u.disk.cksize &= ~LFSR_BPTR_ISERASED;
|
||||||
|
#else
|
||||||
|
bptr->cksize &= ~LFSR_BPTR_ISERASED;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static inline bool lfsr_bptr_isbptr(const lfsr_bptr_t *bptr) {
|
static inline bool lfsr_bptr_isbptr(const lfsr_bptr_t *bptr) {
|
||||||
return bptr->data.size & LFSR_BPTR_ISBPTR;
|
return bptr->data.size & LFSR_BPTR_ISBPTR;
|
||||||
}
|
}
|
||||||
@@ -9147,11 +9155,9 @@ static int lfsr_mdir_commit(lfs_t *lfs, lfsr_mdir_t *mdir,
|
|||||||
== ((lfsr_bshrub_t*)o)->shrub.blocks[0]
|
== ((lfsr_bshrub_t*)o)->shrub.blocks[0]
|
||||||
&& ((lfsr_bshrub_t*)o)->shrub_.blocks[0]
|
&& ((lfsr_bshrub_t*)o)->shrub_.blocks[0]
|
||||||
!= ((lfsr_bshrub_t*)o)->shrub.blocks[0]) {
|
!= ((lfsr_bshrub_t*)o)->shrub.blocks[0]) {
|
||||||
// TODO lfsr_file_clobberleaf? discardleaf?
|
((lfsr_file_t*)o)->leaf.pos = 0;
|
||||||
lfsr_file_t *file = (lfsr_file_t*)o;
|
((lfsr_file_t*)o)->leaf.weight = 0;
|
||||||
file->leaf.pos = 0;
|
lfsr_bptr_discard(&((lfsr_file_t*)o)->leaf.bptr);
|
||||||
file->leaf.weight = 0;
|
|
||||||
lfsr_bptr_discard(&file->leaf.bptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// update the shrub
|
// update the shrub
|
||||||
@@ -11878,7 +11884,7 @@ static int lfsr_file_commit(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO replace rattr with bptr + delta?
|
// TODO replace rattr with bptr + delta?
|
||||||
static int lfsr_file_graft(lfs_t *lfs, lfsr_file_t *file,
|
static int lfsr_file_graft_(lfs_t *lfs, lfsr_file_t *file,
|
||||||
lfs_off_t pos, lfs_off_t weight, lfsr_rattr_t rattr) {
|
lfs_off_t pos, lfs_off_t weight, lfsr_rattr_t rattr) {
|
||||||
// note! we must never allow our btree size to overflow, even
|
// note! we must never allow our btree size to overflow, even
|
||||||
// temporarily
|
// temporarily
|
||||||
@@ -12131,17 +12137,40 @@ static int lfsr_file_graft(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
|
|
||||||
static int lfsr_file_graftcrystal(lfs_t *lfs, lfsr_file_t *file,
|
static int lfsr_file_graftcrystal(lfs_t *lfs, lfsr_file_t *file,
|
||||||
lfs_off_t pos, lfs_off_t weight, const lfsr_bptr_t *bptr) {
|
lfs_off_t pos, lfs_off_t weight, const lfsr_bptr_t *bptr) {
|
||||||
return lfsr_file_graft(lfs, file, pos, weight,
|
return lfsr_file_graft_(lfs, file, pos, weight,
|
||||||
LFSR_RATTR_BPTR(LFSR_TAG_BLOCK, 0, bptr));
|
LFSR_RATTR_BPTR(LFSR_TAG_BLOCK, 0, bptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lfsr_file_graftfragment(lfs_t *lfs, lfsr_file_t *file,
|
static int lfsr_file_graftfragment(lfs_t *lfs, lfsr_file_t *file,
|
||||||
lfs_off_t pos, lfs_off_t weight,
|
lfs_off_t pos, lfs_off_t weight,
|
||||||
const lfsr_data_t *datas, lfs_size_t data_count) {
|
const lfsr_data_t *datas, lfs_size_t data_count) {
|
||||||
return lfsr_file_graft(lfs, file, pos, weight,
|
return lfsr_file_graft_(lfs, file, pos, weight,
|
||||||
LFSR_RATTR_CAT_(LFSR_TAG_DATA, 0, datas, data_count));
|
LFSR_RATTR_CAT_(LFSR_TAG_DATA, 0, datas, data_count));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lfsr_file_graft(lfs_t *lfs, lfsr_file_t *file) {
|
||||||
|
// do nothing if already grafted
|
||||||
|
if (!lfsr_o_isungraft(file->b.o.flags)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// ungrafted files must be unsynced
|
||||||
|
LFS_ASSERT(lfsr_o_isunsync(file->b.o.flags));
|
||||||
|
// only blocks can be ungrafted
|
||||||
|
LFS_ASSERT(lfsr_bptr_isbptr(&file->leaf.bptr));
|
||||||
|
|
||||||
|
// graft our crystal
|
||||||
|
int err = lfsr_file_graftcrystal(lfs, file,
|
||||||
|
file->leaf.pos, file->leaf.weight,
|
||||||
|
&file->leaf.bptr);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark as grafted
|
||||||
|
file->b.o.flags &= ~LFS_o_UNGRAFT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int lfsr_file_crystallize(lfs_t *lfs, lfsr_file_t *file,
|
static int lfsr_file_crystallize(lfs_t *lfs, lfsr_file_t *file,
|
||||||
lfs_off_t block_pos, lfs_soff_t crystal_size,
|
lfs_off_t block_pos, lfs_soff_t crystal_size,
|
||||||
lfs_off_t pos, const uint8_t *buffer, lfs_size_t size) {
|
lfs_off_t pos, const uint8_t *buffer, lfs_size_t size) {
|
||||||
@@ -12174,12 +12203,7 @@ static int lfsr_file_crystallize(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
&& lfsr_bptr_block(&((lfsr_file_t*)o)->leaf.bptr)
|
&& lfsr_bptr_block(&((lfsr_file_t*)o)->leaf.bptr)
|
||||||
== lfsr_bptr_block(&file->leaf.bptr)
|
== lfsr_bptr_block(&file->leaf.bptr)
|
||||||
&& (lfsr_file_t*)o != file) {
|
&& (lfsr_file_t*)o != file) {
|
||||||
// TODO lfsr_bptr_mkdirty? clobber? claim?
|
lfsr_bptr_claim(&((lfsr_file_t*)o)->leaf.bptr);
|
||||||
// TODO lfsr_rbyd_claim?
|
|
||||||
LFS_IFDEF_CKDATACKSUMS(
|
|
||||||
((lfsr_file_t*)o)->leaf.bptr.data.u.disk.cksize,
|
|
||||||
((lfsr_file_t*)o)->leaf.bptr.cksize)
|
|
||||||
&= ~LFSR_BPTR_ISERASED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12364,6 +12388,7 @@ static int lfsr_file_crystallize(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
|
|
||||||
lfsr_bptr_init(&bptr,
|
lfsr_bptr_init(&bptr,
|
||||||
LFSR_DATA_DISK(block, 0, 0),
|
LFSR_DATA_DISK(block, 0, 0),
|
||||||
|
// mark as erased
|
||||||
LFSR_BPTR_ISERASED | 0,
|
LFSR_BPTR_ISERASED | 0,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
@@ -12565,21 +12590,14 @@ static int lfsr_file_flush_(lfs_t *lfs, lfsr_file_t *file,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// and graft the crystal into our tree
|
// and graft the crystal into our tree
|
||||||
err = lfsr_file_graftcrystal(lfs, file,
|
err = lfsr_file_graft(lfs, file);
|
||||||
file->leaf.pos, file->leaf.weight,
|
|
||||||
&file->leaf.bptr);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark as unerased so lfsr_file_crystallize doesn't try to
|
// mark as unerased so lfsr_file_crystallize doesn't try to
|
||||||
// continue crystallizing this block
|
// continue crystallizing this block
|
||||||
LFS_IFDEF_CKDATACKSUMS(
|
lfsr_bptr_claim(&file->leaf.bptr);
|
||||||
file->leaf.bptr.data.u.disk.cksize,
|
|
||||||
file->leaf.bptr.cksize) &= ~LFSR_BPTR_ISERASED;
|
|
||||||
|
|
||||||
// mark as grafted
|
|
||||||
file->b.o.flags &= ~LFS_o_UNGRAFT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// before we can crystallize we need to figure out the best
|
// before we can crystallize we need to figure out the best
|
||||||
@@ -12647,23 +12665,11 @@ fragment:;
|
|||||||
//
|
//
|
||||||
// but note we're still tracking its erased state for future
|
// but note we're still tracking its erased state for future
|
||||||
// writes!
|
// writes!
|
||||||
if (lfsr_o_isungraft(file->b.o.flags)) {
|
int err = lfsr_file_graft(lfs, file);
|
||||||
// and graft the crystal into our tree
|
|
||||||
int err = lfsr_file_graftcrystal(lfs, file,
|
|
||||||
file->leaf.pos, file->leaf.weight,
|
|
||||||
&file->leaf.bptr);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark as grafted
|
|
||||||
file->b.o.flags &= ~LFS_o_UNGRAFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO NOTE _any_ compaction can affect shrub leaves... so any
|
|
||||||
// shrub updates need to also discard leafs, lfsr_mdir_commit,
|
|
||||||
// lfsr_fs_gc, etc
|
|
||||||
|
|
||||||
// do we need to discard our leaf? we need to discard fragments
|
// do we need to discard our leaf? we need to discard fragments
|
||||||
// in case the underlying rbyd compacts, and we need to discard
|
// in case the underlying rbyd compacts, and we need to discard
|
||||||
// overwritten blocks
|
// overwritten blocks
|
||||||
@@ -12701,7 +12707,7 @@ fragment:;
|
|||||||
lfsr_bid_t bid;
|
lfsr_bid_t bid;
|
||||||
lfsr_bid_t weight;
|
lfsr_bid_t weight;
|
||||||
lfsr_bptr_t bptr;
|
lfsr_bptr_t bptr;
|
||||||
int err = lfsr_file_lookup(lfs, file,
|
err = lfsr_file_lookup(lfs, file,
|
||||||
fragment_start-1,
|
fragment_start-1,
|
||||||
&bid, &weight, &bptr);
|
&bid, &weight, &bptr);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -12748,7 +12754,7 @@ fragment:;
|
|||||||
lfsr_bid_t bid;
|
lfsr_bid_t bid;
|
||||||
lfsr_bid_t weight;
|
lfsr_bid_t weight;
|
||||||
lfsr_bptr_t bptr;
|
lfsr_bptr_t bptr;
|
||||||
int err = lfsr_file_lookup(lfs, file,
|
err = lfsr_file_lookup(lfs, file,
|
||||||
fragment_end,
|
fragment_end,
|
||||||
&bid, &weight, &bptr);
|
&bid, &weight, &bptr);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -12788,7 +12794,7 @@ fragment:;
|
|||||||
|
|
||||||
// once we've figured out what fragment to write, graft it into
|
// once we've figured out what fragment to write, graft it into
|
||||||
// our tree
|
// our tree
|
||||||
int err = lfsr_file_graftfragment(lfs, file,
|
err = lfsr_file_graftfragment(lfs, file,
|
||||||
fragment_start, fragment_end - fragment_start,
|
fragment_start, fragment_end - fragment_start,
|
||||||
datas, data_count);
|
datas, data_count);
|
||||||
if (err) {
|
if (err) {
|
||||||
@@ -13161,8 +13167,6 @@ static int lfsr_file_sync_(lfs_t *lfs, lfsr_file_t *file) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO update leaves?
|
|
||||||
// TODO can other operations, compactions maybe? clobber leaves?
|
|
||||||
int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
|
int lfsr_file_sync(lfs_t *lfs, lfsr_file_t *file) {
|
||||||
LFS_ASSERT(lfsr_omdir_isopen(lfs, &file->b.o));
|
LFS_ASSERT(lfsr_omdir_isopen(lfs, &file->b.o));
|
||||||
// can't write to readonly files, if you want to resync call
|
// can't write to readonly files, if you want to resync call
|
||||||
@@ -13422,26 +13426,18 @@ int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
< lfs_min(
|
< lfs_min(
|
||||||
lfs->cfg->fragment_thresh,
|
lfs->cfg->fragment_thresh,
|
||||||
lfs->cfg->crystal_thresh)) {
|
lfs->cfg->crystal_thresh)) {
|
||||||
// TODO lfsr_file_graft?
|
err = lfsr_file_graft(lfs, file);
|
||||||
if (lfsr_o_isungraft(file->b.o.flags)) {
|
|
||||||
err = lfsr_file_graftcrystal(lfs, file,
|
|
||||||
file->leaf.pos, file->leaf.weight,
|
|
||||||
&file->leaf.bptr);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark as grafted
|
|
||||||
file->b.o.flags &= ~LFS_o_UNGRAFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->leaf.pos = 0;
|
file->leaf.pos = 0;
|
||||||
file->leaf.weight = 0;
|
file->leaf.weight = 0;
|
||||||
lfsr_bptr_discard(&file->leaf.bptr);
|
lfsr_bptr_discard(&file->leaf.bptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// truncate our btree
|
// truncate our btree
|
||||||
err = lfsr_file_graft(lfs, file,
|
err = lfsr_file_graft_(lfs, file,
|
||||||
lfs_min(size, size_), size - lfs_min(size, size_),
|
lfs_min(size, size_), size - lfs_min(size, size_),
|
||||||
LFSR_RATTR(
|
LFSR_RATTR(
|
||||||
LFSR_TAG_DATA, +size_ - size));
|
LFSR_TAG_DATA, +size_ - size));
|
||||||
@@ -13451,9 +13447,7 @@ int lfsr_file_truncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
|
|
||||||
// truncate our leaf
|
// truncate our leaf
|
||||||
if (size_ < file->leaf.pos + lfsr_bptr_size(&file->leaf.bptr)) {
|
if (size_ < file->leaf.pos + lfsr_bptr_size(&file->leaf.bptr)) {
|
||||||
LFS_IFDEF_CKDATACKSUMS(
|
lfsr_bptr_claim(&file->leaf.bptr);
|
||||||
file->leaf.bptr.data.u.disk.cksize,
|
|
||||||
file->leaf.bptr.cksize) &= ~LFSR_BPTR_ISERASED;
|
|
||||||
}
|
}
|
||||||
file->leaf.bptr.data = LFSR_DATA_TRUNCATE(
|
file->leaf.bptr.data = LFSR_DATA_TRUNCATE(
|
||||||
file->leaf.bptr.data,
|
file->leaf.bptr.data,
|
||||||
@@ -13516,26 +13510,18 @@ int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
< lfs_min(
|
< lfs_min(
|
||||||
lfs->cfg->fragment_thresh,
|
lfs->cfg->fragment_thresh,
|
||||||
lfs->cfg->crystal_thresh)) {
|
lfs->cfg->crystal_thresh)) {
|
||||||
// TODO lfsr_file_graft?
|
err = lfsr_file_graft(lfs, file);
|
||||||
if (lfsr_o_isungraft(file->b.o.flags)) {
|
|
||||||
err = lfsr_file_graftcrystal(lfs, file,
|
|
||||||
file->leaf.pos, file->leaf.weight,
|
|
||||||
&file->leaf.bptr);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark as grafted
|
|
||||||
file->b.o.flags &= ~LFS_o_UNGRAFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
file->leaf.pos = 0;
|
file->leaf.pos = 0;
|
||||||
file->leaf.weight = 0;
|
file->leaf.weight = 0;
|
||||||
lfsr_bptr_discard(&file->leaf.bptr);
|
lfsr_bptr_discard(&file->leaf.bptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// fruncate our btree
|
// fruncate our btree
|
||||||
err = lfsr_file_graft(lfs, file,
|
err = lfsr_file_graft_(lfs, file,
|
||||||
0, lfs_smax(size - size_, 0),
|
0, lfs_smax(size - size_, 0),
|
||||||
LFSR_RATTR(
|
LFSR_RATTR(
|
||||||
LFSR_TAG_DATA, +size_ - size));
|
LFSR_TAG_DATA, +size_ - size));
|
||||||
@@ -13547,9 +13533,7 @@ int lfsr_file_fruncate(lfs_t *lfs, lfsr_file_t *file, lfs_off_t size_) {
|
|||||||
if ((lfs_soff_t)(size - size_)
|
if ((lfs_soff_t)(size - size_)
|
||||||
> (lfs_soff_t)(file->leaf.pos
|
> (lfs_soff_t)(file->leaf.pos
|
||||||
+ lfsr_bptr_size(&file->leaf.bptr))) {
|
+ lfsr_bptr_size(&file->leaf.bptr))) {
|
||||||
LFS_IFDEF_CKDATACKSUMS(
|
lfsr_bptr_claim(&file->leaf.bptr);
|
||||||
file->leaf.bptr.data.u.disk.cksize,
|
|
||||||
file->leaf.bptr.cksize) &= ~LFSR_BPTR_ISERASED;
|
|
||||||
}
|
}
|
||||||
file->leaf.bptr.data = LFSR_DATA_FRUNCATE(
|
file->leaf.bptr.data = LFSR_DATA_FRUNCATE(
|
||||||
file->leaf.bptr.data,
|
file->leaf.bptr.data,
|
||||||
|
|||||||
Reference in New Issue
Block a user