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);