Settings: NVS: Add cache for nvs name lookup
Add cache for name id lookup. Signed-off-by: Lingao Meng <menglingao@xiaomi.com>
This commit is contained in:
parent
51e4d7bc56
commit
9cb1ff7fce
3 changed files with 110 additions and 17 deletions
|
@ -63,6 +63,24 @@ config SETTINGS_NVS
|
|||
help
|
||||
Enables NVS storage support
|
||||
|
||||
if SETTINGS_NVS
|
||||
|
||||
config SETTINGS_NVS_NAME_CACHE
|
||||
bool "NVS name lookup cache"
|
||||
help
|
||||
Enable NVS name lookup cache, used to reduce the Settings name
|
||||
lookup time.
|
||||
|
||||
config SETTINGS_NVS_NAME_CACHE_SIZE
|
||||
int "NVS name lookup cache size"
|
||||
default 128
|
||||
range 1 65535
|
||||
depends on SETTINGS_NVS_NAME_CACHE
|
||||
help
|
||||
Number of entries in Settings NVS name cache.
|
||||
|
||||
endif # SETTINGS_NVS
|
||||
|
||||
config SETTINGS_CUSTOM
|
||||
bool "CUSTOM"
|
||||
help
|
||||
|
|
|
@ -38,6 +38,14 @@ struct settings_nvs {
|
|||
struct nvs_fs cf_nvs;
|
||||
uint16_t last_name_id;
|
||||
const struct device *flash_dev;
|
||||
#if CONFIG_SETTINGS_NVS_NAME_CACHE
|
||||
struct {
|
||||
uint16_t name_hash;
|
||||
uint16_t name_id;
|
||||
} cache[CONFIG_SETTINGS_NVS_NAME_CACHE_SIZE];
|
||||
|
||||
uint16_t cache_next;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* register nvs to be a source of settings */
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <zephyr/settings/settings.h>
|
||||
#include "settings/settings_nvs.h"
|
||||
#include <zephyr/sys/crc.h>
|
||||
#include "settings_priv.h"
|
||||
#include <zephyr/storage/flash_map.h>
|
||||
|
||||
|
@ -72,6 +73,51 @@ int settings_nvs_dst(struct settings_nvs *cf)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if CONFIG_SETTINGS_NVS_NAME_CACHE
|
||||
static void settings_nvs_cache_add(struct settings_nvs *cf, const char *name,
|
||||
uint16_t name_id)
|
||||
{
|
||||
uint16_t name_hash = crc16_ccitt(0xffff, name, strlen(name));
|
||||
|
||||
cf->cache[cf->cache_next].name_hash = name_hash;
|
||||
cf->cache[cf->cache_next++].name_id = name_id;
|
||||
|
||||
cf->cache_next %= CONFIG_SETTINGS_NVS_NAME_CACHE_SIZE;
|
||||
}
|
||||
|
||||
static uint16_t settings_nvs_cache_match(struct settings_nvs *cf, const char *name,
|
||||
char *rdname, size_t len)
|
||||
{
|
||||
uint16_t name_hash = crc16_ccitt(0xffff, name, strlen(name));
|
||||
int rc;
|
||||
|
||||
for (int i = 0; i < CONFIG_SETTINGS_NVS_NAME_CACHE_SIZE; i++) {
|
||||
if (cf->cache[i].name_hash != name_hash) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cf->cache[i].name_id <= NVS_NAMECNT_ID) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = nvs_read(&cf->cf_nvs, cf->cache[i].name_id, rdname, len);
|
||||
if (rc < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rdname[rc] = '\0';
|
||||
|
||||
if (strcmp(name, rdname)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return cf->cache[i].name_id;
|
||||
}
|
||||
|
||||
return NVS_NAMECNT_ID;
|
||||
}
|
||||
#endif /* CONFIG_SETTINGS_NVS_NAME_CACHE */
|
||||
|
||||
static int settings_nvs_load(struct settings_store *cs,
|
||||
const struct settings_load_arg *arg)
|
||||
{
|
||||
|
@ -125,6 +171,10 @@ static int settings_nvs_load(struct settings_store *cs,
|
|||
read_fn_arg.fs = &cf->cf_nvs;
|
||||
read_fn_arg.id = name_id + NVS_NAME_ID_OFFSET;
|
||||
|
||||
#if CONFIG_SETTINGS_NVS_NAME_CACHE
|
||||
settings_nvs_cache_add(cf, name, name_id);
|
||||
#endif
|
||||
|
||||
ret = settings_call_set_handler(
|
||||
name, rc2,
|
||||
settings_nvs_read_fn, &read_fn_arg,
|
||||
|
@ -152,6 +202,15 @@ static int settings_nvs_save(struct settings_store *cs, const char *name,
|
|||
/* Find out if we are doing a delete */
|
||||
delete = ((value == NULL) || (val_len == 0));
|
||||
|
||||
#if CONFIG_SETTINGS_NVS_NAME_CACHE
|
||||
name_id = settings_nvs_cache_match(cf, name, rdname, sizeof(rdname));
|
||||
if (name_id != NVS_NAMECNT_ID) {
|
||||
write_name_id = name_id;
|
||||
write_name = false;
|
||||
goto found;
|
||||
}
|
||||
#endif
|
||||
|
||||
name_id = cf->last_name_id + 1;
|
||||
write_name_id = cf->last_name_id + 1;
|
||||
write_name = true;
|
||||
|
@ -178,7 +237,24 @@ static int settings_nvs_save(struct settings_store *cs, const char *name,
|
|||
continue;
|
||||
}
|
||||
|
||||
if ((delete) && (name_id == cf->last_name_id)) {
|
||||
if (!delete) {
|
||||
#if CONFIG_SETTINGS_NVS_NAME_CACHE
|
||||
settings_nvs_cache_add(cf, name, name_id);
|
||||
#endif
|
||||
write_name_id = name_id;
|
||||
write_name = false;
|
||||
}
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
found:
|
||||
if (delete) {
|
||||
if (name_id == NVS_NAMECNT_ID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (name_id == cf->last_name_id) {
|
||||
cf->last_name_id--;
|
||||
rc = nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID,
|
||||
&cf->last_name_id, sizeof(uint16_t));
|
||||
|
@ -190,26 +266,17 @@ static int settings_nvs_save(struct settings_store *cs, const char *name,
|
|||
}
|
||||
}
|
||||
|
||||
if (delete) {
|
||||
rc = nvs_delete(&cf->cf_nvs, name_id);
|
||||
rc = nvs_delete(&cf->cf_nvs, name_id);
|
||||
|
||||
if (rc >= 0) {
|
||||
rc = nvs_delete(&cf->cf_nvs, name_id +
|
||||
if (rc >= 0) {
|
||||
rc = nvs_delete(&cf->cf_nvs, name_id +
|
||||
NVS_NAME_ID_OFFSET);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
write_name_id = name_id;
|
||||
write_name = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (delete) {
|
||||
if (rc < 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue