@@ -146,6 +146,79 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
146146 return rc ;
147147}
148148
149+ #if CONFIG_SETTINGS_ZMS_NAME_CACHE
150+ static void settings_zms_cache_add (struct settings_zms * cf , uint32_t name_hash , uint8_t flags )
151+ {
152+ cf -> cache [cf -> cache_next ].name_hash = name_hash ;
153+ cf -> cache [cf -> cache_next ++ ].flags = flags ;
154+
155+ cf -> cache_next %= CONFIG_SETTINGS_ZMS_NAME_CACHE_SIZE ;
156+ }
157+
158+ static uint8_t settings_zms_cache_match (struct settings_zms * cf , uint32_t name_hash )
159+ {
160+ int cache_index ;
161+
162+ if (!cf -> cache_next ) {
163+ cache_index = CONFIG_SETTINGS_ZMS_NAME_CACHE_SIZE - 1 ;
164+ } else {
165+ cache_index = cf -> cache_next - 1 ;
166+ }
167+
168+ for (int i = 0 ; i < CONFIG_SETTINGS_ZMS_NAME_CACHE_SIZE ; i ++ ) {
169+ /* we check cache from recent values to old values */
170+ if (cf -> cache [cache_index ].name_hash != name_hash ) {
171+ cache_index -- ;
172+ if (cache_index < 0 ) {
173+ cache_index = CONFIG_SETTINGS_ZMS_NAME_CACHE_SIZE - 1 ;
174+ }
175+ continue ;
176+ }
177+
178+ /* set the BIT(0) to indicate that the name_hash exist in cache */
179+ return ZMS_CACHE_FLAG_SET_EXIST (cf -> cache [cache_index ].flags );
180+ }
181+
182+ return 0 ;
183+ }
184+ #endif /* CONFIG_SETTINGS_ZMS_NAME_CACHE */
185+
186+ static int settings_zms_delete (struct settings_zms * cf , uint32_t name_hash )
187+ {
188+ int rc = 0 ;
189+
190+ rc = zms_delete (& cf -> cf_zms , name_hash );
191+ if (rc >= 0 ) {
192+ rc = zms_delete (& cf -> cf_zms , name_hash + ZMS_DATA_ID_OFFSET );
193+ }
194+ if (rc < 0 ) {
195+ return rc ;
196+ }
197+ rc = settings_zms_unlink_ll_node (cf , name_hash );
198+ if (rc < 0 ) {
199+ return rc ;
200+ }
201+
202+ /* Now delete the current linked list element */
203+ rc = zms_delete (& cf -> cf_zms , name_hash | 1 );
204+ if (rc < 0 ) {
205+ return rc ;
206+ }
207+
208+ #ifdef CONFIG_SETTINGS_ZMS_NAME_CACHE
209+ /* Update the flag of the Settings entry in cache. */
210+ uint8_t cache_flags = 0 ;
211+
212+ if (ZMS_COLLISION_NUM (name_hash ) > 0 ) {
213+ cache_flags = ZMS_CACHE_FLAG_SET_COLLISION (cache_flags );
214+ }
215+ /* set the delete BIT(2) indicating that the entry is deleted. */
216+ cache_flags = ZMS_CACHE_FLAG_SET_DELETED (cache_flags );
217+ settings_zms_cache_add (cf , name_hash & ZMS_HASH_MASK , cache_flags );
218+ #endif
219+ return rc ;
220+ }
221+
149222static int settings_zms_load (struct settings_store * cs , const struct settings_load_arg * arg )
150223{
151224 int ret = 0 ;
@@ -194,6 +267,16 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
194267 read_fn_arg .fs = & cf -> cf_zms ;
195268 read_fn_arg .id = ZMS_NAME_ID_FROM_LL_NODE (ll_hash_id ) + ZMS_DATA_ID_OFFSET ;
196269
270+ #if CONFIG_SETTINGS_ZMS_NAME_CACHE
271+ /* Add the linked list node to cache */
272+ uint8_t cache_flags = 0 ;
273+
274+ if (ZMS_COLLISION_NUM (ll_hash_id ) > 0 ) {
275+ cache_flags = ZMS_CACHE_FLAG_SET_COLLISION (cache_flags );
276+ }
277+ settings_zms_cache_add (cf , ll_hash_id & ZMS_HASH_MASK , cache_flags );
278+ #endif
279+
197280 ret = settings_call_set_handler (name , rc2 , settings_zms_read_fn , & read_fn_arg ,
198281 (void * )arg );
199282 if (ret ) {
@@ -222,7 +305,6 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
222305 uint32_t collision_num = 0 ;
223306 bool delete ;
224307 bool write_name ;
225- bool hash_collision ;
226308 int rc = 0 ;
227309 int first_available_hash_index = -1 ;
228310
@@ -237,9 +319,22 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
237319 /* MSB is always 1 */
238320 name_hash |= BIT (31 );
239321
240- /* Let's find out if there are hash collisions in the storage */
322+ #ifdef CONFIG_SETTINGS_ZMS_NAME_CACHE
323+ uint8_t cache_flags = 0 ;
324+
325+ cache_flags = settings_zms_cache_match (cf , name_hash & ZMS_HASH_MASK );
326+ if (ZMS_CACHE_EXIST (cache_flags ) && !ZMS_CACHE_HAS_COLLISION (cache_flags )) {
327+ if (ZMS_CACHE_IS_DELETED (cache_flags )) {
328+ write_name = true;
329+ } else {
330+ write_name = false;
331+ }
332+ goto no_hash_collision ;
333+ }
334+ #endif
335+
336+ /* Let's find out if there is no hash collisions in the storage */
241337 write_name = true;
242- hash_collision = true;
243338
244339 for (int i = 0 ; i <= cf -> hash_collision_num ; i ++ ) {
245340 rc = zms_read (& cf -> cf_zms , name_hash + i * LSB_GET (ZMS_COLLISIONS_MASK ), & rdname ,
@@ -296,7 +391,6 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
296391 /* hash doesn't exist, do not write anything here */
297392 return 0 ;
298393 }
299-
300394 rc = settings_zms_delete (cf , name_hash );
301395 return rc ;
302396 }
@@ -342,6 +436,14 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
342436 cf -> second_to_last_hash_id = cf -> last_hash_id ;
343437 cf -> last_hash_id = name_hash | 1 ;
344438 }
439+ #ifdef CONFIG_SETTINGS_ZMS_NAME_CACHE
440+ /* Add the flags of the written settings entry in cache */
441+ cache_flags = 0 ;
442+ if (ZMS_COLLISION_NUM (name_hash ) > 0 ) {
443+ cache_flags = ZMS_CACHE_FLAG_SET_COLLISION (cache_flags );
444+ }
445+ settings_zms_cache_add (cf , name_hash & ZMS_HASH_MASK , cache_flags );
446+ #endif /* CONFIG_SETTINGS_ZMS_NAME_CACHE */
345447
346448 return 0 ;
347449}
0 commit comments