added functions to iterate through hash table and remove hash entries
authorHolger Schemel <info@artsoft.org>
Fri, 23 Feb 2024 14:25:19 +0000 (15:25 +0100)
committerHolger Schemel <info@artsoft.org>
Fri, 23 Feb 2024 14:27:21 +0000 (15:27 +0100)
src/libgame/hash.c
src/libgame/hash.h

index 89c7134f5906aa06d8a6cb24813eebf84f2d42af..2b856f6810df38cc739c62e7b2695b5586b1cc69 100644 (file)
@@ -483,3 +483,106 @@ hashtable_iterator_advance(struct hashtable_itr *itr)
 
   return -1;
 }
+
+/*****************************************************************************/
+/* call function for all hashtable entries */
+void
+hashtable_foreach(struct hashtable *h, hashtable_fn fn, void *userdata)
+{
+  if (h == NULL)
+    return;
+
+  if (hashtable_count(h) == 0)
+    return;
+
+  struct hashtable_itr *itr = hashtable_iterator(h);
+
+  do
+  {
+    fn(hashtable_iterator_key(itr), hashtable_iterator_value(itr), userdata);
+  }
+  while (hashtable_iterator_advance(itr));
+
+  free(itr);
+}
+
+/*****************************************************************************/
+/* call function for all hashtable entries and remove them, if function returned 1 */
+unsigned int
+hashtable_foreach_remove(struct hashtable *h, hashtable_remove_fn fn, void *userdata)
+{
+  if (h == NULL)
+    return 0;
+
+  if (hashtable_count(h) == 0)
+    return 0;
+
+  struct hashtable *remove = create_hashtable(h->hashfn, h->eqfn, NULL, NULL);
+  struct hashtable_itr *itr = hashtable_iterator(h);
+
+  do
+  {
+    if (fn(hashtable_iterator_key(itr), hashtable_iterator_value(itr), userdata))
+      hashtable_insert(remove, hashtable_iterator_key(itr), "1");
+  }
+  while (hashtable_iterator_advance(itr));
+
+  free(itr);
+
+  struct hashtable_itr *itr_remove = hashtable_iterator(remove);
+  unsigned int num_removed = 0;
+
+  do
+  {
+    hashtable_remove(h, hashtable_iterator_key(itr_remove));
+    num_removed++;
+  }
+  while (hashtable_iterator_advance(itr_remove));
+
+  free(itr_remove);
+
+  hashtable_destroy(remove);
+
+  return num_removed;
+}
+
+/*****************************************************************************/
+/* remove_all hashtable entries */
+unsigned int
+hashtable_remove_all(struct hashtable *h)
+{
+  /* TODO: this function should directly remove all hashtable entries */
+
+  if (h == NULL)
+    return 0;
+
+  if (hashtable_count(h) == 0)
+    return 0;
+
+  struct hashtable *remove = create_hashtable(h->hashfn, h->eqfn, NULL, NULL);
+  struct hashtable_itr *itr = hashtable_iterator(h);
+
+  do
+  {
+    hashtable_insert(remove, hashtable_iterator_key(itr), "1");
+  }
+  while (hashtable_iterator_advance(itr));
+
+  free(itr);
+
+  struct hashtable_itr *itr_remove = hashtable_iterator(remove);
+  unsigned int num_removed = 0;
+
+  do
+  {
+    hashtable_remove(h, hashtable_iterator_key(itr_remove));
+    num_removed++;
+  }
+  while (hashtable_iterator_advance(itr_remove));
+
+  free(itr_remove);
+
+  hashtable_destroy(remove);
+
+  return num_removed;
+}
index 8fe6f7fabbd4ab0c8861ba9f077c4a6f4c3d6064..50806d449e94ac85d0de77c8bedd21b6e72e3d1e 100644 (file)
@@ -297,4 +297,64 @@ hashtable_iterator_value(struct hashtable_itr *i);
 int
 hashtable_iterator_advance(struct hashtable_itr *itr);
 
+
+/*****************************************************************************/
+/* hashtable_fn - prototype of function to call for hashtable entry
+
+ * @name        hashtable_fn
+ * @param   k   the key of the current hash entry
+ * @param   v   the value of the current hash entry
+ * @param   u   additional user data
+ */
+
+typedef void (*hashtable_fn) (void *k, void *v, void *u);
+
+/*****************************************************************************/
+/* hashtable_foreach - call function for all hashtable entries
+
+ * @name        hashtable_foreach
+ * @param   h   the hashtable to iterate through
+ * @param   fn  the function to call for each entry
+ */
+
+void
+hashtable_foreach(struct hashtable *h, hashtable_fn fn, void *userdata);
+
+/*****************************************************************************/
+/* hashtable_remove_fn - prototype of function to call for hashtable entry
+
+ * @name        hashtable_remove_fn
+ * @param   k   the key of the current hash entry
+ * @param   v   the value of the current hash entry
+ * @param   u   additional user data
+ * @return      non-zero if entry should be removed, else zero
+ */
+
+typedef int (*hashtable_remove_fn) (void *k, void *v, void *u);
+
+/*****************************************************************************/
+/* hashtable_foreach_remove - call function for all hashtable entries and remove them,
+ *                            if function returned 1
+ *                            returns the number of removed entries
+
+ * @name        hashtable_foreach_remove
+ * @param   h   the hashtable to iterate through
+ * @param   fn  the function to call for each entry
+ * @return      the number of removed entries
+ */
+
+unsigned int
+hashtable_foreach_remove(struct hashtable *h, hashtable_remove_fn fn, void *userdata);
+
+/*****************************************************************************/
+/* hashtable_remove_all - remove_all hashtable entries
+
+ * @name        hashtable_remove
+ * @param   h   the hashtable to remove all entries from
+ * @return      the number of removed entries
+ */
+
+unsigned int
+hashtable_remove_all(struct hashtable *h);
+
 #endif