]> PatchyGit - patchyircd.git/commitdiff
document map traversal funcs
authorEgor <egor@patchysicp.xyz>
Sun, 22 Oct 2023 21:18:36 +0000 (00:18 +0300)
committerEgor <egor@patchysicp.xyz>
Sun, 22 Oct 2023 21:18:36 +0000 (00:18 +0300)
src/map.h

index fc87a90..4126273 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -29,7 +29,7 @@ struct map_dynarr_find {
        size_t _index;
 };
 typedef struct map_dynarr_find *map_find_t;
-#define map_findfree(f) (free(*(f)))
+#define map_findfree(f) (free(*(f)), *(f) = 0)
 #else
 /* all complexity is in terms of n = strlen(key) and s = size of the character set */
 struct trie_node {
@@ -49,7 +49,7 @@ struct trie_find {
        char key[1];
 };
 typedef struct trie_find *map_find_t;
-#define map_findfree(f) (free(*(f)))
+#define map_findfree(f) (free(*(f)), *(f) = 0)
 #endif
 
 /* A map abstract data type with following properties:
@@ -82,6 +82,37 @@ NODISCARD int map_set(map_t *root, const char *key, const void *value, void **ol
  * Trie   complexity: O(ns)
  * Dynarr complexity: O(n) */
 void map_free(map_t *root);
+/* Traversal functions.
+ * Return 1 on success, 0 on end, -1 on allocation failure.
+ *
+ * Some ground rules:
+ * - map_find_t should be zero-initialized
+ * - map_findfirst and map_findfree are idempotent
+ * - when map_findfirst or map_findnext return 0 or -1, they automatically call
+ *   map_findfree
+ *
+ * Non-modifying traversal:
+ * map_find_t f = {0};
+ * if (map_findfirst(&f, &map) == 1)
+ *     do {
+ *         value_type *v = f->value;
+ *         // use f->key and v here
+ *         if (gotta_break) {
+ *             map_findfree(&f); // call this when breaking!
+ *             break;
+ *         }
+ *     } while(map_findnext(&f) == 1);
+ *
+ * Emptying traversal:
+ * while (map_findfirst(&f, &map) == 1) {
+ *     value_type *v = f->value;
+ *     // use f->key and v here
+ *     map_unset(&map, f->key, 0);
+ * }
+ * map_findfree(&f);
+ *
+ * FIXME: yep, we're silently failing on allocation errors
+ */
 NODISCARD int map_findfirst(map_find_t *pf, map_t *root);
 NODISCARD int map_findnext(map_find_t *pf);
 #endif