@@ -135,6 +135,9 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
135135 }
136136
137137#ifndef CONFIG_SETTINGS_ZMS_NO_LL_DELETE
138+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
139+ cf -> ll_has_changed = true;
140+ #endif
138141 rc = settings_zms_unlink_ll_node (cf , name_hash );
139142 if (rc < 0 ) {
140143 return rc ;
@@ -220,16 +223,28 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
220223 }
221224#endif /* CONFIG_SETTINGS_ZMS_LOAD_SUBTREE_PATH */
222225
226+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
227+ uint32_t ll_cache_index = 0 ;
228+
229+ if (cf -> ll_has_changed ) {
230+ /* reload the linked list in cache */
231+ ret = settings_zms_get_last_hash_ids (cf );
232+ if (ret < 0 ) {
233+ return ret ;
234+ }
235+ }
236+ settings_element = cf -> ll_cache [ll_cache_index ++ ];
237+ #else
223238 ret = zms_read (& cf -> cf_zms , ZMS_LL_HEAD_HASH_ID , & settings_element ,
224239 sizeof (struct settings_hash_linked_list ));
225240 if (ret < 0 ) {
226241 return ret ;
227242 }
243+ #endif /* CONFIG_SETTINGS_ZMS_LL_CACHE */
228244 ll_hash_id = settings_element .next_hash ;
229245
230246 /* If subtree is NULL then we must load all found Settings */
231247 while (ll_hash_id ) {
232-
233248 /* In the ZMS backend, each setting item is stored in two ZMS
234249 * entries one for the setting's name and one with the
235250 * setting's value.
@@ -254,12 +269,24 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
254269 return ret ;
255270 }
256271#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
257-
258- ret = zms_read (& cf -> cf_zms , ll_hash_id , & settings_element ,
259- sizeof (struct settings_hash_linked_list ));
260- if (ret < 0 ) {
261- return ret ;
272+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
273+ if (ll_cache_index < cf -> ll_cache_next ) {
274+ settings_element = cf -> ll_cache [ll_cache_index ++ ];
275+ } else if (ll_hash_id == cf -> second_to_last_hash_id ) {
276+ /* The last ll node is not stored in the cache as it is already
277+ * in the cf->last_hash_id.
278+ */
279+ settings_element .next_hash = cf -> last_hash_id ;
280+ } else {
281+ #endif
282+ ret = zms_read (& cf -> cf_zms , ll_hash_id , & settings_element ,
283+ sizeof (struct settings_hash_linked_list ));
284+ if (ret < 0 ) {
285+ return ret ;
286+ }
287+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
262288 }
289+ #endif
263290 /* update next ll_hash_id */
264291 ll_hash_id = settings_element .next_hash ;
265292 continue ;
@@ -276,12 +303,22 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
276303 break ;
277304 }
278305
279- /* update next ll_hash_id */
280- ret = zms_read (& cf -> cf_zms , ll_hash_id , & settings_element ,
281- sizeof (struct settings_hash_linked_list ));
282- if (ret < 0 ) {
283- return ret ;
306+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
307+ if (ll_cache_index < cf -> ll_cache_next ) {
308+ settings_element = cf -> ll_cache [ll_cache_index ++ ];
309+ } else if (ll_hash_id == cf -> second_to_last_hash_id ) {
310+ settings_element .next_hash = cf -> last_hash_id ;
311+ } else {
312+ #endif
313+ ret = zms_read (& cf -> cf_zms , ll_hash_id , & settings_element ,
314+ sizeof (struct settings_hash_linked_list ));
315+ if (ret < 0 ) {
316+ return ret ;
317+ }
318+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
284319 }
320+ #endif
321+ /* update next ll_hash_id */
285322 ll_hash_id = settings_element .next_hash ;
286323 }
287324
@@ -418,6 +455,7 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
418455 if (rc < 0 ) {
419456 return rc ;
420457 }
458+
421459 /* Now update the previous linked list element */
422460 settings_element .next_hash = name_hash | 1 ;
423461 settings_element .previous_hash = cf -> second_to_last_hash_id ;
@@ -428,6 +466,12 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
428466 }
429467 cf -> second_to_last_hash_id = cf -> last_hash_id ;
430468 cf -> last_hash_id = name_hash | 1 ;
469+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
470+ if (cf -> ll_cache_next < CONFIG_SETTINGS_ZMS_LL_CACHE_SIZE ) {
471+ cf -> ll_cache [cf -> ll_cache_next ] = settings_element ;
472+ cf -> ll_cache_next = cf -> ll_cache_next + 1 ;
473+ }
474+ #endif
431475 }
432476#ifdef CONFIG_SETTINGS_ZMS_NO_LL_DELETE
433477no_ll_update :
@@ -441,6 +485,9 @@ static int settings_zms_get_last_hash_ids(struct settings_zms *cf)
441485 uint32_t ll_last_hash_id = ZMS_LL_HEAD_HASH_ID ;
442486 int rc = 0 ;
443487
488+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
489+ cf -> ll_cache_next = 0 ;
490+ #endif
444491 cf -> hash_collision_num = 0 ;
445492 do {
446493 rc = zms_read (& cf -> cf_zms , ll_last_hash_id , & settings_element ,
@@ -461,6 +508,13 @@ static int settings_zms_get_last_hash_ids(struct settings_zms *cf)
461508 return rc ;
462509 }
463510
511+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
512+ if ((cf -> ll_cache_next < CONFIG_SETTINGS_ZMS_LL_CACHE_SIZE ) &&
513+ (settings_element .next_hash )) {
514+ cf -> ll_cache [cf -> ll_cache_next ] = settings_element ;
515+ cf -> ll_cache_next = cf -> ll_cache_next + 1 ;
516+ }
517+ #endif
464518 /* increment hash collision number if necessary */
465519 if (ZMS_COLLISION_NUM (ll_last_hash_id ) > cf -> hash_collision_num ) {
466520 cf -> hash_collision_num = ZMS_COLLISION_NUM (ll_last_hash_id );
@@ -470,6 +524,9 @@ static int settings_zms_get_last_hash_ids(struct settings_zms *cf)
470524 ll_last_hash_id = settings_element .next_hash ;
471525 } while (settings_element .next_hash );
472526
527+ #ifdef CONFIG_SETTINGS_ZMS_LL_CACHE
528+ cf -> ll_has_changed = false;
529+ #endif
473530 return 0 ;
474531}
475532
0 commit comments