Added lfs_rbyd_get, bumped hint back up to full during lookup
The idea behind the full hint is that we may stay on the current search path, benefiting from a loaded cache. Though this should probably be benchmarked eventually.
This commit is contained in:
@@ -1172,7 +1172,7 @@ tryagain:;
|
|||||||
lfs_rtag_t alt;
|
lfs_rtag_t alt;
|
||||||
lfs_off_t jump;
|
lfs_off_t jump;
|
||||||
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
||||||
&lfs->pcache, &lfs->rcache, 2*4,
|
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
|
||||||
rbyd->block, branch, &alt, &jump, NULL);
|
rbyd->block, branch, &alt, &jump, NULL);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
@@ -1216,6 +1216,34 @@ tryagain:;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static lfs_ssize_t lfs_rbyd_get(lfs_t *lfs, const lfs_rbyd_t *rbyd,
|
||||||
|
lfs_rtag_t tag, void *buffer, lfs_size_t size) {
|
||||||
|
lfs_off_t found_off;
|
||||||
|
lfs_size_t found_size;
|
||||||
|
lfs_srtag_t found_tag = lfs_rbyd_lookup(lfs, rbyd, tag,
|
||||||
|
&found_off, &found_size);
|
||||||
|
if (found_tag < 0) {
|
||||||
|
return found_tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookup finds the next-smallest tag, here we fail if it's not
|
||||||
|
// an exact match
|
||||||
|
if ((lfs_tag_t)found_tag != tag) {
|
||||||
|
return LFS_ERR_NOENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note that it's highly likely the data is in our cache now
|
||||||
|
lfs_size_t delta = lfs_min(size, found_size);
|
||||||
|
int err = lfs_bd_read(lfs,
|
||||||
|
&lfs->pcache, &lfs->rcache, delta,
|
||||||
|
rbyd->block, found_off, buffer, delta);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found_size;
|
||||||
|
}
|
||||||
|
|
||||||
static int lfs_rbyd_prog(lfs_t *lfs,
|
static int lfs_rbyd_prog(lfs_t *lfs,
|
||||||
lfs_cache_t *pcache, lfs_cache_t *rcache,
|
lfs_cache_t *pcache, lfs_cache_t *rcache,
|
||||||
lfs_block_t block, lfs_off_t off,
|
lfs_block_t block, lfs_off_t off,
|
||||||
@@ -1438,7 +1466,7 @@ static int lfs_rbyd_commit(lfs_t *lfs, lfs_rbyd_t *rbyd,
|
|||||||
lfs_rtag_t alt;
|
lfs_rtag_t alt;
|
||||||
lfs_off_t jump;
|
lfs_off_t jump;
|
||||||
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
lfs_ssize_t delta = lfs_rbyd_readtag(lfs,
|
||||||
&lfs->pcache, &lfs->rcache, 2*4,
|
&lfs->pcache, &lfs->rcache, lfs->cfg->block_size,
|
||||||
block, branch, &alt, &jump, NULL);
|
block, branch, &alt, &jump, NULL);
|
||||||
if (delta < 0) {
|
if (delta < 0) {
|
||||||
return delta;
|
return delta;
|
||||||
|
|||||||
@@ -230,6 +230,151 @@ code = '''
|
|||||||
=> LFS_ERR_NOENT;
|
=> LFS_ERR_NOENT;
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
[cases.test_rbyd_get]
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_t init_rbyd = {
|
||||||
|
.block = 0,
|
||||||
|
.trunk = 0,
|
||||||
|
.off = 0,
|
||||||
|
.rev = 1,
|
||||||
|
.crc = 0,
|
||||||
|
.count = 0,
|
||||||
|
.erased = true,
|
||||||
|
};
|
||||||
|
lfs_rbyd_t rbyd;
|
||||||
|
uint8_t buffer[4];
|
||||||
|
|
||||||
|
// try an empty commit
|
||||||
|
rbyd = init_rbyd;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
// commit with one attribute
|
||||||
|
rbyd = init_rbyd;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
assert(memcmp(buffer, &(uint32_t){0xaaaaaaaa}, 4) == 0);
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
assert(memcmp(buffer, &(uint32_t){0xaaaaaaaa}, 4) == 0);
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
// commit with two attributes
|
||||||
|
rbyd = init_rbyd;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4,
|
||||||
|
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL))) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
'''
|
||||||
|
|
||||||
|
[cases.test_rbyd_multi_get]
|
||||||
|
in = 'lfs.c'
|
||||||
|
code = '''
|
||||||
|
lfs_t lfs;
|
||||||
|
lfs_init(&lfs, cfg) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_t init_rbyd = {
|
||||||
|
.block = 0,
|
||||||
|
.trunk = 0,
|
||||||
|
.off = 0,
|
||||||
|
.rev = 1,
|
||||||
|
.crc = 0,
|
||||||
|
.count = 0,
|
||||||
|
.erased = true,
|
||||||
|
};
|
||||||
|
lfs_rbyd_t rbyd;
|
||||||
|
uint8_t buffer[4];
|
||||||
|
|
||||||
|
// try an empty commit
|
||||||
|
rbyd = init_rbyd;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd, NULL) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
// commit with one attribute
|
||||||
|
rbyd = init_rbyd;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
assert(memcmp(buffer, &(uint32_t){0xaaaaaaaa}, 4) == 0);
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
assert(memcmp(buffer, &(uint32_t){0xaaaaaaaa}, 4) == 0);
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
// commit with two attributes
|
||||||
|
rbyd = init_rbyd;
|
||||||
|
lfs_bd_erase(&lfs, rbyd.block) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, 1, 0, &(uint32_t){0xaaaaaaaa}, 4, NULL)) => 0;
|
||||||
|
lfs_rbyd_commit(&lfs, &rbyd,
|
||||||
|
LFS_MKRATTR(UATTR, 2, 0, &(uint32_t){0xbbbbbbbb}, 4, NULL)) => 0;
|
||||||
|
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
|
||||||
|
lfs_rbyd_fetch(&lfs, &rbyd, rbyd.block, NULL) => 0;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 1, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 2, 0), buffer, 4)
|
||||||
|
=> 4;
|
||||||
|
lfs_rbyd_get(&lfs, &rbyd, LFS_MKRTAG(UATTR, 3, 0), buffer, 4)
|
||||||
|
=> LFS_ERR_NOENT;
|
||||||
|
'''
|
||||||
|
|
||||||
[cases.test_rbyd_traverse]
|
[cases.test_rbyd_traverse]
|
||||||
in = 'lfs.c'
|
in = 'lfs.c'
|
||||||
code = '''
|
code = '''
|
||||||
|
|||||||
Reference in New Issue
Block a user