@@ -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 cf -> cache [cache_index ].flags | BIT (0 );
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 |= BIT (1 );
214+ }
215+ /* set the delete BIT(1) indicating that the entry is deleted. */
216+ cache_flags |= BIT (2 );
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 ;
@@ -199,6 +272,15 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
199272 break ;
200273 }
201274
275+ #if CONFIG_SETTINGS_ZMS_NAME_CACHE
276+ uint8_t cache_flags = 0 ;
277+
278+ if (ZMS_COLLISION_NUM (ll_hash_id ) > 0 ) {
279+ cache_flags |= BIT (1 );
280+ }
281+ settings_zms_cache_add (cf , ll_hash_id & ZMS_HASH_MASK , cache_flags );
282+ #endif
283+
202284 /* update next ll_hash_id */
203285 ret = zms_read (& cf -> cf_zms , ll_hash_id , & settings_element ,
204286 sizeof (struct settings_hash_linked_list ));
@@ -221,7 +303,6 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
221303 uint32_t collision_num = 0 ;
222304 bool delete ;
223305 bool write_name ;
224- bool hash_collision ;
225306 int rc = 0 ;
226307 int first_available_hash_index = -1 ;
227308
@@ -236,9 +317,22 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
236317 /* MSB is always 1 */
237318 name_hash |= BIT (31 );
238319
320+ #ifdef CONFIG_SETTINGS_ZMS_NAME_CACHE
321+ uint8_t cache_flags = 0 ;
322+
323+ cache_flags = settings_zms_cache_match (cf , name_hash & ZMS_HASH_MASK );
324+ if (ZMS_CACHE_EXIST (cache_flags ) && !ZMS_CACHE_HAS_COLLISION (cache_flags )) {
325+ if (ZMS_CACHE_IS_DELETED (cache_flags )) {
326+ write_name = true;
327+ } else {
328+ write_name = false;
329+ }
330+ goto no_hash_collision ;
331+ }
332+ #endif
333+
239334 /* Let's find out if there is no hash collisions in the storage */
240335 write_name = true;
241- hash_collision = true;
242336
243337 for (int i = 0 ; i <= cf -> hash_collision_num ; i ++ ) {
244338 rc = zms_read (& cf -> cf_zms , name_hash + i * LSB_GET (ZMS_COLLISIONS_MASK ), & rdname ,
@@ -295,7 +389,6 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
295389 /* hash doesn't exist, do not write anything here */
296390 return 0 ;
297391 }
298-
299392 rc = settings_zms_delete (cf , name_hash );
300393 return rc ;
301394 }
@@ -341,6 +434,14 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
341434 cf -> second_to_last_hash_id = cf -> last_hash_id ;
342435 cf -> last_hash_id = name_hash | 1 ;
343436 }
437+ #ifdef CONFIG_SETTINGS_ZMS_NAME_CACHE
438+ /* Add the flags of the written settings entry in cache */
439+ cache_flags = 0 ;
440+ if (ZMS_COLLISION_NUM (name_hash ) > 0 ) {
441+ cache_flags |= BIT (1 );
442+ }
443+ settings_zms_cache_add (cf , name_hash & ZMS_HASH_MASK , cache_flags );
444+ #endif /* CONFIG_SETTINGS_ZMS_NAME_CACHE */
344445
345446 return 0 ;
346447}
0 commit comments