src/ucx/hash_map.c

changeset 438
22eca559aded
parent 415
d938228c382e
child 484
c036a8b242a8
--- a/src/ucx/hash_map.c	Sun Nov 20 12:43:44 2022 +0100
+++ b/src/ucx/hash_map.c	Sat Nov 26 17:07:08 2022 +0100
@@ -201,34 +201,42 @@
     return cx_hash_map_get_remove(map, key, true);
 }
 
-static void *cx_hash_map_iter_current_entry(CxIterator const *iter) {
+static void *cx_hash_map_iter_current_entry(void const *it) {
+    struct cx_iterator_s const *iter = it;
     // struct has to have a compatible signature
     return (struct cx_map_entry_s *) &(iter->kv_data);
 }
 
-static void *cx_hash_map_iter_current_key(CxIterator const *iter) {
+static void *cx_hash_map_iter_current_key(void const *it) {
+    struct cx_iterator_s const *iter = it;
     struct cx_hash_map_element_s *elm = iter->elem_handle;
     return &elm->key;
 }
 
-static void *cx_hash_map_iter_current_value(CxIterator const *iter) {
+static void *cx_hash_map_iter_current_value(void const *it) {
+    struct cx_iterator_s const *iter = it;
     struct cx_hash_map_element_s *elm = iter->elem_handle;
     // TODO: return a pointer to data if this map is storing copies
     return elm->data;
 }
 
-static bool cx_hash_map_iter_valid(CxIterator const *iter) {
+static bool cx_hash_map_iter_valid(void const *it) {
+    struct cx_iterator_s const *iter = it;
     return iter->elem_handle != NULL;
 }
 
-static void cx_hash_map_iter_next(CxIterator *iter) {
-    struct cx_hash_map_s *map = iter->src_handle;
+static void cx_hash_map_iter_next(void *it) {
+    struct cx_iterator_s *iter = it;
     struct cx_hash_map_element_s *elm = iter->elem_handle;
 
     // remove current element, if asked
-    if (iter->remove) {
+    if (iter->base.remove) {
+        // obtain mutable pointer to the map
+        struct cx_mut_iterator_s *miter = it;
+        struct cx_hash_map_s *map = miter->src_handle;
+
         // clear the flag
-        iter->remove = false;
+        iter->base.remove = false;
 
         // determine the next element
         struct cx_hash_map_element_s *next = elm->next;
@@ -254,6 +262,7 @@
     }
 
     // search the next bucket, if required
+    struct cx_hash_map_s const *map = iter->src_handle;
     while (elm == NULL && ++iter->slot < map->bucket_count) {
         elm = map->buckets[iter->slot];
     }
@@ -270,17 +279,29 @@
     }
 }
 
-static CxIterator cx_hash_map_iterator(CxMap *map) {
+static bool cx_hash_map_iter_flag_rm(void *it) {
+    struct cx_iterator_base_s *iter = it;
+    if (iter->mutating) {
+        iter->remove = true;
+        return true;
+    } else {
+        return false;
+    }
+}
+
+static CxIterator cx_hash_map_iterator(CxMap const *map) {
     CxIterator iter;
 
     iter.src_handle = map;
-    iter.valid = cx_hash_map_iter_valid;
-    iter.next = cx_hash_map_iter_next;
-    iter.current = cx_hash_map_iter_current_entry;
+    iter.base.valid = cx_hash_map_iter_valid;
+    iter.base.next = cx_hash_map_iter_next;
+    iter.base.current = cx_hash_map_iter_current_entry;
+    iter.base.flag_removal = cx_hash_map_iter_flag_rm;
+    iter.base.remove = false;
+    iter.base.mutating = false;
 
     iter.slot = 0;
     iter.index = 0;
-    iter.remove = false;
 
     if (map->size > 0) {
         struct cx_hash_map_s *hash_map = (struct cx_hash_map_s *) map;
@@ -301,15 +322,37 @@
     return iter;
 }
 
-static CxIterator cx_hash_map_iterator_keys(CxMap *map) {
+static CxIterator cx_hash_map_iterator_keys(CxMap const *map) {
     CxIterator iter = cx_hash_map_iterator(map);
-    iter.current = cx_hash_map_iter_current_key;
+    iter.base.current = cx_hash_map_iter_current_key;
+    return iter;
+}
+
+static CxIterator cx_hash_map_iterator_values(CxMap const *map) {
+    CxIterator iter = cx_hash_map_iterator(map);
+    iter.base.current = cx_hash_map_iter_current_value;
     return iter;
 }
 
-static CxIterator cx_hash_map_iterator_values(CxMap *map) {
-    CxIterator iter = cx_hash_map_iterator(map);
-    iter.current = cx_hash_map_iter_current_value;
+static CxMutIterator cx_hash_map_mut_iterator(CxMap *map) {
+    CxIterator it = cx_hash_map_iterator(map);
+    it.base.mutating = true;
+
+    // we know the iterators share the same memory layout
+    CxMutIterator iter;
+    memcpy(&iter, &it, sizeof(CxMutIterator));
+    return iter;
+}
+
+static CxMutIterator cx_hash_map_mut_iterator_keys(CxMap *map) {
+    CxMutIterator iter = cx_hash_map_mut_iterator(map);
+    iter.base.current = cx_hash_map_iter_current_key;
+    return iter;
+}
+
+static CxMutIterator cx_hash_map_mut_iterator_values(CxMap *map) {
+    CxMutIterator iter = cx_hash_map_mut_iterator(map);
+    iter.base.current = cx_hash_map_iter_current_value;
     return iter;
 }
 
@@ -322,6 +365,9 @@
         cx_hash_map_iterator,
         cx_hash_map_iterator_keys,
         cx_hash_map_iterator_values,
+        cx_hash_map_mut_iterator,
+        cx_hash_map_mut_iterator_keys,
+        cx_hash_map_mut_iterator_values,
 };
 
 CxMap *cxHashMapCreate(

mercurial