Switched to using did for dir-is-empty checks, lfsr_grm_pushdid

So instead of looking for another bookmark, we check to see if the next
mid's did matches.

This is in theory more robust, and can handle neighboring
directories/files without bookmarks, but adds a bit of code cost.

Deduplicating these checks into lfsr_grm_pushdid helps reduce this a
bit:

                   code          stack
  before:         34406           2624
  after-no-dedup: 34526 (+0.3%)   2624 (+0.0%)
  after-dedup:    34470 (+0.2%)   2624 (+0.0%)
This commit is contained in:
Christopher Haster
2024-06-21 11:20:46 -05:00
parent ec44831381
commit 2e516d7b68
+55 -73
View File
@@ -9678,6 +9678,56 @@ int lfsr_mkdir(lfs_t *lfs, const char *path) {
return 0; return 0;
} }
// push a did to grm, but only if the directory is empty
static int lfsr_grm_pushdid(lfs_t *lfs, lfsr_grm_t *grm, lfsr_did_t did) {
// first lookup the bookmark entry
lfsr_mdir_t bookmark_mdir;
int err = lfsr_mtree_namelookup(lfs, did, NULL, 0,
&bookmark_mdir, NULL, NULL);
if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err;
}
lfsr_mid_t bookmark_mid = bookmark_mdir.mid;
// check that the directory is empty
bookmark_mdir.mid += 1;
if (lfsr_mid_rid(lfs, bookmark_mdir.mid)
>= (lfsr_srid_t)bookmark_mdir.rbyd.weight) {
err = lfsr_mtree_lookup(lfs,
lfsr_mid_bid(lfs, bookmark_mdir.mid-1) + 1,
&bookmark_mdir);
if (err) {
if (err == LFS_ERR_NOENT) {
goto empty;
}
return err;
}
}
lfsr_data_t data;
err = lfsr_mdir_sublookup(lfs, &bookmark_mdir, LFSR_TAG_NAME,
NULL, &data);
if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err;
}
lfsr_did_t did_;
err = lfsr_data_readleb128(lfs, &data, &did_);
if (err) {
return err;
}
if (did_ == did) {
return LFS_ERR_NOTEMPTY;
}
empty:;
lfsr_grm_push(grm, bookmark_mid);
return 0;
}
// needed in lfsr_remove // needed in lfsr_remove
static inline bool lfsr_f_iszombie(uint32_t flags); static inline bool lfsr_f_iszombie(uint32_t flags);
@@ -9722,45 +9772,11 @@ int lfsr_remove(lfs_t *lfs, const char *path) {
return err; return err;
} }
// then lookup the bookmark entry // mark bookmark for removal with grm
lfsr_mdir_t bookmark_mdir; err = lfsr_grm_pushdid(lfs, &lfs->grm, did_);
err = lfsr_mtree_namelookup(lfs, did_, NULL, 0,
&bookmark_mdir, NULL, NULL);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err; return err;
} }
lfsr_mid_t bookmark_mid = bookmark_mdir.mid;
// check that the directory is empty
bookmark_mdir.mid += 1;
if (lfsr_mid_rid(lfs, bookmark_mdir.mid)
>= (lfsr_srid_t)bookmark_mdir.rbyd.weight) {
err = lfsr_mtree_lookup(lfs,
lfsr_mid_bid(lfs, bookmark_mdir.mid-1) + 1,
&bookmark_mdir);
if (err) {
if (err == LFS_ERR_NOENT) {
goto empty;
}
return err;
}
}
// the next mid should be another bookmark
err = lfsr_mdir_lookup(lfs,
&bookmark_mdir, LFSR_TAG_BOOKMARK,
NULL);
if (err) {
if (err == LFS_ERR_NOENT) {
return LFS_ERR_NOTEMPTY;
}
return err;
}
empty:;
// create a grm to remove the bookmark entry
lfs->grm.mids[0] = bookmark_mid;
} }
// are we removing an opened file? // are we removing an opened file?
@@ -9901,50 +9917,16 @@ int lfsr_rename(lfs_t *lfs, const char *old_path, const char *new_path) {
return err; return err;
} }
// then lookup the bookmark entry // mark bookmark for removal with grm
lfsr_mdir_t bookmark_mdir; err = lfsr_grm_pushdid(lfs, &lfs->grm, new_did_);
err = lfsr_mtree_namelookup(lfs, new_did_, NULL, 0,
&bookmark_mdir, NULL, NULL);
if (err) { if (err) {
LFS_ASSERT(err != LFS_ERR_NOENT);
return err; return err;
} }
lfsr_mid_t bookmark_mid = bookmark_mdir.mid;
// check that the directory is empty
bookmark_mdir.mid += 1;
if (lfsr_mid_rid(lfs, bookmark_mdir.mid)
>= (lfsr_srid_t)bookmark_mdir.rbyd.weight) {
err = lfsr_mtree_lookup(lfs,
lfsr_mid_bid(lfs, bookmark_mdir.mid-1) + 1,
&bookmark_mdir);
if (err) {
if (err == LFS_ERR_NOENT) {
goto empty;
}
return err;
}
}
// the next mid should be another bookmark
err = lfsr_mdir_lookup(lfs,
&bookmark_mdir, LFSR_TAG_BOOKMARK,
NULL);
if (err) {
if (err == LFS_ERR_NOENT) {
return LFS_ERR_NOTEMPTY;
}
return err;
}
empty:;
// mark bookmark entry for removal with a grm
lfs->grm.mids[1] = bookmark_mid;
} }
} }
// mark old entry for removal with a grm // mark old entry for removal with a grm
lfs->grm.mids[0] = old_mdir.mid; lfsr_grm_push(&lfs->grm, old_mdir.mid);
// rename our entry, copying all tags associated with the old rid to the // rename our entry, copying all tags associated with the old rid to the
// new rid, while also marking the old rid for removal // new rid, while also marking the old rid for removal