hash table UPDATE optional cb for HT free
Allows freeing items in the hash table.
diff --git a/src/hash_table.c b/src/hash_table.c
index 4f9dec3..f2e17ef 100644
--- a/src/hash_table.c
+++ b/src/hash_table.c
@@ -87,7 +87,7 @@
}
/* free table and destroy mutex */
- lyht_free(dict->hash_tab);
+ lyht_free(dict->hash_tab, NULL);
pthread_mutex_destroy(&dict->lock);
}
@@ -381,12 +381,25 @@
}
void
-lyht_free(struct hash_table *ht)
+lyht_free(struct hash_table *ht, void (*val_free)(void *val_p))
{
- if (ht) {
- free(ht->recs);
- free(ht);
+ struct ht_rec *rec;
+ uint32_t i;
+
+ if (!ht) {
+ return;
}
+
+ if (val_free) {
+ for (i = 0; i < ht->size; ++i) {
+ rec = lyht_get_rec(ht->recs, ht->rec_size, i);
+ if (rec->hits > 0) {
+ val_free(&rec->val);
+ }
+ }
+ }
+ free(ht->recs);
+ free(ht);
}
/**
diff --git a/src/hash_table.h b/src/hash_table.h
index 91ae63d..6b32672 100644
--- a/src/hash_table.h
+++ b/src/hash_table.h
@@ -167,8 +167,9 @@
* @brief Free a hash table.
*
* @param[in] ht Hash table to be freed.
+ * @param[in] val_free Optional callback for freeing allthe stored values, @p val_p is a pointer to a stored value.
*/
-void lyht_free(struct hash_table *ht);
+void lyht_free(struct hash_table *ht, void (*val_free)(void *val_p));
/**
* @brief Find a value in a hash table.
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
index f898085..dbdb8b0 100644
--- a/src/parser_lyb.c
+++ b/src/parser_lyb.c
@@ -53,7 +53,7 @@
LY_ARRAY_FREE(ctx->models);
LY_ARRAY_FOR(ctx->sib_hts, u) {
- lyht_free(ctx->sib_hts[u].ht);
+ lyht_free(ctx->sib_hts[u].ht, NULL);
}
LY_ARRAY_FREE(ctx->sib_hts);
diff --git a/src/printer_lyb.c b/src/printer_lyb.c
index 686c2d8..5bb6ba6 100644
--- a/src/printer_lyb.c
+++ b/src/printer_lyb.c
@@ -172,7 +172,7 @@
if (lyht_insert(ht, &sibling, lyb_get_hash(sibling, i), NULL)) {
LOGINT(sibling->module->ctx);
lyht_set_cb(ht, lyb_hash_equal_cb);
- lyht_free(ht);
+ lyht_free(ht, NULL);
return LY_EINT;
}
lyht_set_cb(ht, lyb_hash_equal_cb);
@@ -184,7 +184,7 @@
if (i == LYB_HASH_BITS) {
/* wow */
LOGINT(sibling->module->ctx);
- lyht_free(ht);
+ lyht_free(ht, NULL);
return LY_EINT;
}
}
diff --git a/src/tree_data_free.c b/src/tree_data_free.c
index bf17a91..806ad3c 100644
--- a/src/tree_data_free.c
+++ b/src/tree_data_free.c
@@ -166,7 +166,7 @@
ly_free_prefix_data(opaq->format, opaq->val_prefix_data);
} else if (node->schema->nodetype & LYD_NODE_INNER) {
/* remove children hash table in case of inner data node */
- lyht_free(((struct lyd_node_inner *)node)->children_ht);
+ lyht_free(((struct lyd_node_inner *)node)->children_ht, NULL);
((struct lyd_node_inner *)node)->children_ht = NULL;
/* free the children */
diff --git a/src/tree_schema_common.c b/src/tree_schema_common.c
index bbdd676..1f08b13 100644
--- a/src/tree_schema_common.c
+++ b/src/tree_schema_common.c
@@ -496,7 +496,7 @@
}
cleanup:
- lyht_free(ids_global);
+ lyht_free(ids_global, NULL);
return ret;
}
@@ -610,7 +610,7 @@
}
cleanup:
- lyht_free(ids_global);
+ lyht_free(ids_global, NULL);
return ret;
}
@@ -650,7 +650,7 @@
}
cleanup:
- lyht_free(ht);
+ lyht_free(ht, NULL);
return ret;
}
@@ -682,7 +682,7 @@
}
cleanup:
- lyht_free(ht);
+ lyht_free(ht, NULL);
return ret;
}
diff --git a/src/validation.c b/src/validation.c
index 6db020a..3ee600e 100644
--- a/src/validation.c
+++ b/src/validation.c
@@ -1246,7 +1246,7 @@
/* failed when allocating uniquetables[j], following j are not allocated */
break;
}
- lyht_free(uniqtables[v]);
+ lyht_free(uniqtables[v], NULL);
}
free(uniqtables);
diff --git a/src/xpath.c b/src/xpath.c
index ab7921e..578324a 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -748,7 +748,7 @@
(void)r;
if (!set->ht->used) {
- lyht_free(set->ht);
+ lyht_free(set->ht, NULL);
set->ht = NULL;
}
}
@@ -802,10 +802,10 @@
if (set->type == LYXP_SET_NODE_SET) {
free(set->val.nodes);
- lyht_free(set->ht);
+ lyht_free(set->ht, NULL);
} else if (set->type == LYXP_SET_SCNODE_SET) {
free(set->val.scnodes);
- lyht_free(set->ht);
+ lyht_free(set->ht, NULL);
} else {
if (set->type == LYXP_SET_STRING) {
free(set->val.str);