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
|
help
|
||||||
Enables NVS storage support
|
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
|
config SETTINGS_CUSTOM
|
||||||
bool "CUSTOM"
|
bool "CUSTOM"
|
||||||
help
|
help
|
||||||
|
|
|
@ -38,6 +38,14 @@ struct settings_nvs {
|
||||||
struct nvs_fs cf_nvs;
|
struct nvs_fs cf_nvs;
|
||||||
uint16_t last_name_id;
|
uint16_t last_name_id;
|
||||||
const struct device *flash_dev;
|
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 */
|
/* register nvs to be a source of settings */
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
#include <zephyr/settings/settings.h>
|
#include <zephyr/settings/settings.h>
|
||||||
#include "settings/settings_nvs.h"
|
#include "settings/settings_nvs.h"
|
||||||
|
#include <zephyr/sys/crc.h>
|
||||||
#include "settings_priv.h"
|
#include "settings_priv.h"
|
||||||
#include <zephyr/storage/flash_map.h>
|
#include <zephyr/storage/flash_map.h>
|
||||||
|
|
||||||
|
@ -72,6 +73,51 @@ int settings_nvs_dst(struct settings_nvs *cf)
|
||||||
return 0;
|
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,
|
static int settings_nvs_load(struct settings_store *cs,
|
||||||
const struct settings_load_arg *arg)
|
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.fs = &cf->cf_nvs;
|
||||||
read_fn_arg.id = name_id + NVS_NAME_ID_OFFSET;
|
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(
|
ret = settings_call_set_handler(
|
||||||
name, rc2,
|
name, rc2,
|
||||||
settings_nvs_read_fn, &read_fn_arg,
|
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 */
|
/* Find out if we are doing a delete */
|
||||||
delete = ((value == NULL) || (val_len == 0));
|
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;
|
name_id = cf->last_name_id + 1;
|
||||||
write_name_id = cf->last_name_id + 1;
|
write_name_id = cf->last_name_id + 1;
|
||||||
write_name = true;
|
write_name = true;
|
||||||
|
@ -178,7 +237,24 @@ static int settings_nvs_save(struct settings_store *cs, const char *name,
|
||||||
continue;
|
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--;
|
cf->last_name_id--;
|
||||||
rc = nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID,
|
rc = nvs_write(&cf->cf_nvs, NVS_NAMECNT_ID,
|
||||||
&cf->last_name_id, sizeof(uint16_t));
|
&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) {
|
if (rc >= 0) {
|
||||||
rc = nvs_delete(&cf->cf_nvs, name_id +
|
rc = nvs_delete(&cf->cf_nvs, name_id +
|
||||||
NVS_NAME_ID_OFFSET);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue