Merge pull request #18 from scossu/iterator

Add hashmap_iter function.
pull/25/head
Josh Baker 3 years ago committed by GitHub
commit 9bb1f630e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -408,6 +408,42 @@ bool hashmap_scan(struct hashmap *map,
return true; return true;
} }
// hashmap_iter iterates one key at a time yielding a reference to an
// entry at each iteration. Useful to write simple loops and avoid writing
// dedicated callbacks and udata structures, as in hashmap_scan.
//
// map is a hash map handle. i is a pointer to a size_t cursor that
// should be initialized to 0 at the beginning of the loop. item is a void
// pointer pointer that is populated with the retrieved item. Note that this
// is NOT a copy of the item stored in the hash map and can be directly
// modified.
//
// Note that if hashmap_delete() is called on the hashmap being iterated,
// the buckets are rearranged and the iterator must be reset to 0, otherwise
// unexpected results may be returned after deletion.
//
// This function has not been tested for thread safety.
//
// The function returns true if an item was retrieved; false if the end of the
// iteration has been reached.
bool hashmap_iter(struct hashmap *map, size_t *i, void **item)
{
struct bucket *bucket;
do {
if (*i >= map->nbuckets) return false;
bucket = bucket_at(map, *i);
(*i)++;
} while (!bucket->dib);
*item = bucket_item(bucket);
return true;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// SipHash reference C implementation // SipHash reference C implementation
// //
@ -738,6 +774,13 @@ static void all() {
while (!(vals2 = xmalloc(N * sizeof(int)))) {} while (!(vals2 = xmalloc(N * sizeof(int)))) {}
memset(vals2, 0, N * sizeof(int)); memset(vals2, 0, N * sizeof(int));
assert(hashmap_scan(map, iter_ints, &vals2)); assert(hashmap_scan(map, iter_ints, &vals2));
// Test hashmap_iter. This does the same as hashmap_scan above.
size_t iter = 0;
void *iter_val;
while (hashmap_iter (map, &iter, &iter_val)) {
assert (iter_ints(iter_val, &vals2));
}
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
assert(vals2[i] == 1); assert(vals2[i] == 1);
} }

@ -41,6 +41,7 @@ void *hashmap_delete(struct hashmap *map, void *item);
void *hashmap_probe(struct hashmap *map, uint64_t position); void *hashmap_probe(struct hashmap *map, uint64_t position);
bool hashmap_scan(struct hashmap *map, bool hashmap_scan(struct hashmap *map,
bool (*iter)(const void *item, void *udata), void *udata); bool (*iter)(const void *item, void *udata), void *udata);
bool hashmap_iter(struct hashmap *map, size_t *i, void **item);
uint64_t hashmap_sip(const void *data, size_t len, uint64_t hashmap_sip(const void *data, size_t len,
uint64_t seed0, uint64_t seed1); uint64_t seed0, uint64_t seed1);

Loading…
Cancel
Save