Skip to content

Commit 476ad66

Browse files
rghaddabanangl
authored andcommitted
[nrf noup] zms: add lookup cache hash function for legacy ZMS
ZMS legacy enabled by CONFIG_SETTINGS_ZMS_LEGACY uses a different lookup cache function that is optimized for Settings subsystem. Signed-off-by: Riadh Ghaddab <[email protected]> (cherry picked from commit 491354b) (cherry picked from commit 15cd2f6) (cherry picked from commit 8ccb986)
1 parent 9311d96 commit 476ad66

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

subsys/fs/zms/zms.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@
1313
#include <zephyr/sys/crc.h>
1414
#include "zms_priv.h"
1515
#ifdef CONFIG_ZMS_LOOKUP_CACHE_FOR_SETTINGS
16+
#ifdef CONFIG_SETTINGS_ZMS_LEGACY
17+
#include <settings/settings_zms_legacy.h>
18+
#else
1619
#include <settings/settings_zms.h>
1720
#endif
21+
#endif
1822

1923
#include <zephyr/logging/log.h>
2024
LOG_MODULE_REGISTER(fs_zms, CONFIG_ZMS_LOG_LEVEL);
@@ -32,6 +36,40 @@ static int zms_ate_valid_different_sector(struct zms_fs *fs, const struct zms_at
3236
static inline size_t zms_lookup_cache_pos(zms_id_t id)
3337
{
3438
#ifdef CONFIG_ZMS_LOOKUP_CACHE_FOR_SETTINGS
39+
#ifdef CONFIG_SETTINGS_ZMS_LEGACY
40+
/*
41+
* 1. The ZMS settings backend uses up to (ZMS_NAME_ID_OFFSET - 1) ZMS IDs to
42+
store keys and equal number of ZMS IDs to store values.
43+
* 2. For each key-value pair, the value is stored at ZMS ID greater by exactly
44+
* ZMS_NAME_ID_OFFSET than ZMS ID that holds the key.
45+
* 3. The backend tries to minimize the range of ZMS IDs used to store keys.
46+
* That is, ZMS IDs are allocated sequentially, and freed ZMS IDs are reused
47+
* before allocating new ones.
48+
*
49+
* Therefore, to assure the least number of collisions in the lookup cache,
50+
* the least significant bit of the hash indicates whether the given ZMS ID
51+
* represents a key or a value, and remaining bits of the hash are set to
52+
* the ordinal number of the key-value pair. Consequently, the hash function
53+
* provides the following mapping:
54+
*
55+
* 1st settings key => hash 0
56+
* 1st settings value => hash 1
57+
* 2nd settings key => hash 2
58+
* 2nd settings value => hash 3
59+
* ...
60+
*/
61+
BUILD_ASSERT(IS_POWER_OF_TWO(ZMS_NAMECNT_ID), "ZMS_NAMECNT_ID is not power of 2");
62+
BUILD_ASSERT(IS_POWER_OF_TWO(ZMS_NAME_ID_OFFSET), "ZMS_NAME_ID_OFFSET is not power of 2");
63+
64+
uint32_t key_value_bit;
65+
uint32_t key_value_ord;
66+
uint32_t hash;
67+
68+
key_value_bit = (id >> LOG2(ZMS_NAME_ID_OFFSET)) & 1;
69+
key_value_ord = id & (ZMS_NAME_ID_OFFSET - 1);
70+
71+
hash = ((key_value_ord << 1) | key_value_bit);
72+
#else
3573
/*
3674
* 1. Settings subsystem is storing the name ID and the linked list node ID
3775
* with only one bit difference at BIT(0).
@@ -57,6 +95,7 @@ static inline size_t zms_lookup_cache_pos(zms_id_t id)
5795
key_value_ll = id & BIT(0);
5896

5997
hash = (key_value_hash << 2) | (key_value_bit << 1) | key_value_ll;
98+
#endif /* CONFIG_SETTINGS_ZMS_LEGACY */
6099

61100
#elif defined(CONFIG_ZMS_ID_64BIT)
62101
/* 64-bit integer hash function found by https://github.com/skeeto/hash-prospector. */

0 commit comments

Comments
 (0)