Skip to content

Commit c0a75da

Browse files
rghaddabkartben
authored andcommitted
settings: zms: add option to disable updating linked list
When deleting a settings entry the linked list is updated by removing the deleted node. This operation is time consuming and add some delays. For applications that use almost the same set of Setting entries, add an option to make this operation faster at a cost of having some empty nodes in the linked list. These empty nodes can be used later when the deleted entry is written again. Each empty node occupies 16B of storage. Signed-off-by: Riadh Ghaddab <[email protected]>
1 parent 6ee55e4 commit c0a75da

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

subsys/settings/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,17 @@ config SETTINGS_ZMS_MAX_COLLISIONS_BITS
171171
The maximum number of hash collisions needs to be well sized depending
172172
on the data that is going to be stored in ZMS and its hash values
173173

174+
config SETTINGS_ZMS_NO_LL_DELETE
175+
bool "Disable deletion of Linked list hashes"
176+
help
177+
For some applications, the Settings delete operation is too long for
178+
ZMS because of the linked list update.
179+
As a tradeoff for performance the linked list is not updated. As a
180+
result, some nodes will be unused and will occupy some space in the
181+
storage.
182+
These nodes will be used again when the same Settings element that has
183+
been deleted is created again.
184+
174185
config SETTINGS_SHELL
175186
bool "Settings shell"
176187
depends on SHELL

subsys/settings/src/settings_zms.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ static int settings_zms_dst(struct settings_zms *cf)
6161
return 0;
6262
}
6363

64+
#ifndef CONFIG_SETTINGS_ZMS_NO_LL_DELETE
6465
static int settings_zms_unlink_ll_node(struct settings_zms *cf, uint32_t name_hash)
6566
{
6667
int rc = 0;
@@ -119,6 +120,7 @@ static int settings_zms_unlink_ll_node(struct settings_zms *cf, uint32_t name_ha
119120

120121
return rc;
121122
}
123+
#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
122124

123125
static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
124126
{
@@ -132,6 +134,7 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
132134
return rc;
133135
}
134136

137+
#ifndef CONFIG_SETTINGS_ZMS_NO_LL_DELETE
135138
rc = settings_zms_unlink_ll_node(cf, name_hash);
136139
if (rc < 0) {
137140
return rc;
@@ -143,6 +146,7 @@ static int settings_zms_delete(struct settings_zms *cf, uint32_t name_hash)
143146
return rc;
144147
}
145148

149+
#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
146150
return rc;
147151
}
148152

@@ -177,15 +181,27 @@ static int settings_zms_load(struct settings_store *cs, const struct settings_lo
177181
ZMS_DATA_ID_OFFSET);
178182

179183
if ((rc1 <= 0) || (rc2 <= 0)) {
180-
/* Settings item is not stored correctly in the ZMS.
181-
* ZMS entry for its name or value is either missing
182-
* or deleted. Clean dirty entries to make space for
183-
* future settings item.
184+
/* In case we are not updating the linked list, this is an empty mode
185+
* Just continue
186+
*/
187+
#ifndef CONFIG_SETTINGS_ZMS_NO_LL_DELETE
188+
/* Otherwise, Settings item is not stored correctly in the ZMS.
189+
* ZMS entry's name or value is either missing or deleted.
190+
* Clean dirty entries to make space for future settings items.
184191
*/
185192
ret = settings_zms_delete(cf, ZMS_NAME_ID_FROM_LL_NODE(ll_hash_id));
186193
if (ret < 0) {
187194
return ret;
188195
}
196+
#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
197+
198+
ret = zms_read(&cf->cf_zms, ll_hash_id, &settings_element,
199+
sizeof(struct settings_hash_linked_list));
200+
if (ret < 0) {
201+
return ret;
202+
}
203+
/* update next ll_hash_id */
204+
ll_hash_id = settings_element.next_hash;
189205
continue;
190206
}
191207

@@ -313,6 +329,17 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
313329
if (rc < 0) {
314330
return rc;
315331
}
332+
#ifdef CONFIG_SETTINGS_ZMS_NO_LL_DELETE
333+
/* verify that the ll_node doesn't exist otherwise do not update it */
334+
rc = zms_read(&cf->cf_zms, name_hash | 1, &settings_element,
335+
sizeof(struct settings_hash_linked_list));
336+
if (rc >= 0) {
337+
goto no_ll_update;
338+
} else if (rc != -ENOENT) {
339+
return rc;
340+
}
341+
/* else the LL node doesn't exist let's update it */
342+
#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
316343
/* write linked list structure element */
317344
settings_element.next_hash = 0;
318345
/* Verify first that the linked list last element is not broken.
@@ -342,7 +369,9 @@ static int settings_zms_save(struct settings_store *cs, const char *name, const
342369
cf->second_to_last_hash_id = cf->last_hash_id;
343370
cf->last_hash_id = name_hash | 1;
344371
}
345-
372+
#ifdef CONFIG_SETTINGS_ZMS_NO_LL_DELETE
373+
no_ll_update:
374+
#endif /* CONFIG_SETTINGS_ZMS_NO_LL_DELETE */
346375
return 0;
347376
}
348377

0 commit comments

Comments
 (0)