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>
2024LOG_MODULE_REGISTER (fs_zms , CONFIG_ZMS_LOG_LEVEL );
@@ -34,6 +38,39 @@ static inline size_t zms_lookup_cache_pos(uint32_t id)
3438 uint32_t hash = id ;
3539
3640#ifdef CONFIG_ZMS_LOOKUP_CACHE_FOR_SETTINGS
41+ #ifdef CONFIG_SETTINGS_ZMS_LEGACY
42+ /*
43+ * 1. The ZMS settings backend uses up to (ZMS_NAME_ID_OFFSET - 1) ZMS IDs to
44+ store keys and equal number of ZMS IDs to store values.
45+ * 2. For each key-value pair, the value is stored at ZMS ID greater by exactly
46+ * ZMS_NAME_ID_OFFSET than ZMS ID that holds the key.
47+ * 3. The backend tries to minimize the range of ZMS IDs used to store keys.
48+ * That is, ZMS IDs are allocated sequentially, and freed ZMS IDs are reused
49+ * before allocating new ones.
50+ *
51+ * Therefore, to assure the least number of collisions in the lookup cache,
52+ * the least significant bit of the hash indicates whether the given ZMS ID
53+ * represents a key or a value, and remaining bits of the hash are set to
54+ * the ordinal number of the key-value pair. Consequently, the hash function
55+ * provides the following mapping:
56+ *
57+ * 1st settings key => hash 0
58+ * 1st settings value => hash 1
59+ * 2nd settings key => hash 2
60+ * 2nd settings value => hash 3
61+ * ...
62+ */
63+ BUILD_ASSERT (IS_POWER_OF_TWO (ZMS_NAMECNT_ID ), "ZMS_NAMECNT_ID is not power of 2" );
64+ BUILD_ASSERT (IS_POWER_OF_TWO (ZMS_NAME_ID_OFFSET ), "ZMS_NAME_ID_OFFSET is not power of 2" );
65+
66+ uint32_t key_value_bit ;
67+ uint32_t key_value_ord ;
68+
69+ key_value_bit = (id >> LOG2 (ZMS_NAME_ID_OFFSET )) & 1 ;
70+ key_value_ord = id & (ZMS_NAME_ID_OFFSET - 1 );
71+
72+ hash = ((key_value_ord << 1 ) | key_value_bit );
73+ #else
3774 /*
3875 * 1. Settings subsystem is storing the name ID and the linked list node ID
3976 * with only one bit difference at BIT(0).
@@ -58,6 +95,7 @@ static inline size_t zms_lookup_cache_pos(uint32_t id)
5895 key_value_ll = id & BIT (0 );
5996
6097 hash = (key_value_hash << 2 ) | (key_value_bit << 1 ) | key_value_ll ;
98+ #endif /* CONFIG_SETTINGS_ZMS_LEGACY */
6199#else
62100 /* 32-bit integer hash function found by https://github.com/skeeto/hash-prospector. */
63101 hash ^= hash >> 16 ;
0 commit comments