#include <stdbool.h>
#include <stdint.h>
#include <string.h>
+#include <assert.h>
#include "hashtable.h"
struct hashnode
lazy_init(ht);
- while (!it->node)
+ if (!it->running)
{
- if (it->bucket == ht->num_buckets)
- goto eof;
+ /* Find the first node and return it; the stored state in the iterator
+ * is invalid. */
+
+ while (it->bucket < ht->num_buckets)
+ {
+ it->node = ht->buckets[it->bucket];
+ if (it->node)
+ goto found;
+ it->bucket++;
+ }
+
+ /* hashtable is empty! */
+ }
+ else
+ {
+ /* The iterator is running; the stored state in the iterator points at
+ * the current node, so find the next one. */
- it->node = ht->buckets[it->bucket];
+ if (!it->advanced)
+ it->node = it->node->next;
if (it->node)
- break;
+ goto found;
- it->bucket++;
- }
+ for (;;)
+ {
+ it->bucket++;
+ if (it->bucket == ht->num_buckets)
+ break;
- it->key = it->node->key;
- it->value = it->node->value;
- it->node = it->node->next;
- if (!it->node)
- it->bucket++;
+ it->node = ht->buckets[it->bucket];
+ if (it->node)
+ goto found;
+ }
- return it->value;
+ /* nothing left found! */
+ }
-eof:
+ /* EOF: reset the iterator. */
+
+ it->running = false;
+ it->advanced = false;
it->key = it->value = NULL;
it->bucket = 0;
it->node = NULL;
return NULL;
+
+found:
+ it->running = true;
+ it->advanced = false;
+ it->key = it->node->key;
+ it->value = it->node->value;
+ return it->value;
+}
+
+void hashtable_delete_current(struct hashtable* ht, struct hashtable_iterator* it)
+{
+ struct hashnode** hnp;
+
+ assert(ht);
+ assert(it->running);
+
+ hnp = findnodep(ht, it->node->key);
+ it->node = it->node->next;
+ ht->freefunction(*hnp);
+ ht->size--;
+ *hnp = it->node;
+
+ it->advanced = true;
+}
+
+void hashtable_copy_all(struct hashtable* src, struct hashtable* dest)
+{
+ struct hashtable_iterator hit = {};
+ while (hashtable_next(src, &hit))
+ hashtable_put(dest, hit.key, hit.value);
}
void* value;
/* Private */
+ bool running;
+ bool advanced;
int bucket;
struct hashnode* node;
};
extern void* hashtable_remove(struct hashtable* ht, void* key);
extern void* hashtable_pop(struct hashtable* ht);
extern void* hashtable_next(struct hashtable* ht, struct hashtable_iterator* it);
+extern void* hashtable_delete_and_next(struct hashtable* ht, struct hashtable_iterator* it);
+
+extern void hashtable_copy_all(struct hashtable* src, struct hashtable* dest);
#endif