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:
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user