13a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton/****************************************************************************** 23a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * 33a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * Copyright (C) 2014 Google, Inc. 43a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * 53a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * Licensed under the Apache License, Version 2.0 (the "License"); 63a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * you may not use this file except in compliance with the License. 73a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * You may obtain a copy of the License at: 83a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * 93a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * http://www.apache.org/licenses/LICENSE-2.0 103a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * 113a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * Unless required by applicable law or agreed to in writing, software 123a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * distributed under the License is distributed on an "AS IS" BASIS, 133a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 143a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * See the License for the specific language governing permissions and 153a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * limitations under the License. 163a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton * 173a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton ******************************************************************************/ 183a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 193a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton#include <assert.h> 203a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton#include <list.h> 213a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton#include <hash_map.h> 223a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 230f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/allocator.h" 2453f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson 253a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonstruct hash_map_t; 263a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 273a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantontypedef struct hash_map_bucket_t { 283a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton list_t *list; 293a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} hash_map_bucket_t; 303a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 313a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantontypedef struct hash_map_t { 323a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_bucket_t *bucket; 333a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton size_t num_bucket; 343a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton size_t hash_size; 353a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_index_fn hash_fn; 363a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton key_free_fn key_fn; 373a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton data_free_fn data_fn; 3853f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson const allocator_t *allocator; 39aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson key_equality_fn keys_are_equal; 403a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} hash_map_t; 413a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 4253f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson// Hidden constructor for list, only to be used by us. 4353f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnsonlist_t *list_new_internal(list_free_cb callback, const allocator_t *zeroed_allocator); 4453f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson 453a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonstatic void bucket_free_(void *data); 46aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnsonstatic bool default_key_equality(const void *x, const void *y); 473a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonstatic hash_map_entry_t *find_bucket_entry_(list_t *hash_bucket_list, 483a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton const void *key); 493a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 5053f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson// Hidden constructor, only to be used by the allocation tracker. Behaves the same as 5153f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson// |hash_map_new|, except you get to specify the allocator. 52aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnsonhash_map_t *hash_map_new_internal( 5353f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson size_t num_bucket, 5453f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_index_fn hash_fn, 5553f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson key_free_fn key_fn, 5653f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson data_free_fn data_fn, 57aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson key_equality_fn equality_fn, 5853f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson const allocator_t *zeroed_allocator) { 593a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_fn != NULL); 603a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(num_bucket > 0); 6153f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson assert(zeroed_allocator != NULL); 623a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 6353f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map_t *hash_map = zeroed_allocator->alloc(sizeof(hash_map_t)); 643a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map == NULL) 653a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return NULL; 663a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 673a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map->hash_fn = hash_fn; 683a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map->key_fn = key_fn; 693a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map->data_fn = data_fn; 7053f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->allocator = zeroed_allocator; 71aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson hash_map->keys_are_equal = equality_fn ? equality_fn : default_key_equality; 723a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 733a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map->num_bucket = num_bucket; 7453f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->bucket = zeroed_allocator->alloc(sizeof(hash_map_bucket_t) * num_bucket); 753a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map->bucket == NULL) { 7653f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson zeroed_allocator->free(hash_map); 773a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return NULL; 783a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } 793a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return hash_map; 803a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 813a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 82aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnsonhash_map_t *hash_map_new( 8353f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson size_t num_bucket, 8453f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_index_fn hash_fn, 8553f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson key_free_fn key_fn, 86aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson data_free_fn data_fn, 87aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson key_equality_fn equality_fn) { 88aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson return hash_map_new_internal(num_bucket, hash_fn, key_fn, data_fn, equality_fn, &allocator_calloc); 8953f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson} 9053f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson 913a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonvoid hash_map_free(hash_map_t *hash_map) { 923a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map == NULL) 933a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return; 943a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_clear(hash_map); 9553f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->allocator->free(hash_map->bucket); 9653f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->allocator->free(hash_map); 973a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 983a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 993a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonbool hash_map_is_empty(const hash_map_t *hash_map) { 1003a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1013a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return (hash_map->hash_size == 0); 1023a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1033a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1043a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonsize_t hash_map_size(const hash_map_t *hash_map) { 1053a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1063a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return hash_map->hash_size; 1073a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1083a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1093a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonsize_t hash_map_num_buckets(const hash_map_t *hash_map) { 1103a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1113a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return hash_map->num_bucket; 1123a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1133a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1143a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonbool hash_map_has_key(const hash_map_t *hash_map, const void *key) { 1153a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1163a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1173a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; 1183a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton list_t *hash_bucket_list = hash_map->bucket[hash_key].list; 1193a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1203a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); 1213a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return (hash_map_entry != NULL); 1223a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1233a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1243a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonbool hash_map_set(hash_map_t *hash_map, const void *key, void *data) { 1253a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1263a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(data != NULL); 1273a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1283a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; 1293a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1303a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map->bucket[hash_key].list == NULL) { 13153f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->bucket[hash_key].list = list_new_internal(bucket_free_, hash_map->allocator); 1323a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map->bucket[hash_key].list == NULL) 1333a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return false; 1343a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } 1353a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton list_t *hash_bucket_list = hash_map->bucket[hash_key].list; 1363a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1373a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); 1383a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1393a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map_entry) { 1403a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton // Calls hash_map callback to delete the hash_map_entry. 1413a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton bool rc = list_remove(hash_bucket_list, hash_map_entry); 1423a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(rc == true); 1433a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } else { 1443a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map->hash_size++; 1453a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } 14653f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map_entry = hash_map->allocator->alloc(sizeof(hash_map_entry_t)); 1473a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map_entry == NULL) 1483a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return false; 1493a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1503a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry->key = key; 1513a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry->data = data; 1523a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry->hash_map = hash_map; 1533a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1543a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return list_append(hash_bucket_list, hash_map_entry); 1553a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1563a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1573a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonbool hash_map_erase(hash_map_t *hash_map, const void *key) { 1583a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1593a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1603a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; 1613a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton list_t *hash_bucket_list = hash_map->bucket[hash_key].list; 1623a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1633a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); 1643a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map_entry == NULL) { 1653a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return false; 1663a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } 1673a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1683a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map->hash_size--; 1693a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1703a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return list_remove(hash_bucket_list, hash_map_entry); 1713a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1723a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1734907b5cc919e103202a940af06a85c1f635932b1Zach Johnsonvoid *hash_map_get(const hash_map_t *hash_map, const void *key) { 1743a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1753a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1763a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_index_t hash_key = hash_map->hash_fn(key) % hash_map->num_bucket; 1773a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton list_t *hash_bucket_list = hash_map->bucket[hash_key].list; 1783a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1793a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry_t *hash_map_entry = find_bucket_entry_(hash_bucket_list, key); 1803a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map_entry != NULL) 1813a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return hash_map_entry->data; 1823a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1833a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return NULL; 1843a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1853a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1863a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonvoid hash_map_clear(hash_map_t *hash_map) { 1873a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(hash_map != NULL); 1883a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 1893a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton for (hash_index_t i = 0; i < hash_map->num_bucket; i++){ 1903a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_map->bucket[i].list == NULL) 1913a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton continue; 1923a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton list_free(hash_map->bucket[i].list); 1933a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map->bucket[i].list = NULL; 1943a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } 1953a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 1963a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 19753d559ca99e93d442d12c548104f939870862ea6Chris Mantonvoid hash_map_foreach(hash_map_t *hash_map, hash_map_iter_cb callback, void *context) { 19853d559ca99e93d442d12c548104f939870862ea6Chris Manton assert(hash_map != NULL); 19953d559ca99e93d442d12c548104f939870862ea6Chris Manton assert(callback != NULL); 20053d559ca99e93d442d12c548104f939870862ea6Chris Manton 20153d559ca99e93d442d12c548104f939870862ea6Chris Manton for (hash_index_t i = 0; i < hash_map->num_bucket; ++i){ 20253d559ca99e93d442d12c548104f939870862ea6Chris Manton if (hash_map->bucket[i].list == NULL) 20353d559ca99e93d442d12c548104f939870862ea6Chris Manton continue; 20453d559ca99e93d442d12c548104f939870862ea6Chris Manton for (const list_node_t *iter = list_begin(hash_map->bucket[i].list); 20553d559ca99e93d442d12c548104f939870862ea6Chris Manton iter != list_end(hash_map->bucket[i].list); 20653d559ca99e93d442d12c548104f939870862ea6Chris Manton iter = list_next(iter)) { 20753d559ca99e93d442d12c548104f939870862ea6Chris Manton hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)list_node(iter); 20853d559ca99e93d442d12c548104f939870862ea6Chris Manton if (!callback(hash_map_entry, context)) 20953d559ca99e93d442d12c548104f939870862ea6Chris Manton return; 21053d559ca99e93d442d12c548104f939870862ea6Chris Manton } 21153d559ca99e93d442d12c548104f939870862ea6Chris Manton } 21253d559ca99e93d442d12c548104f939870862ea6Chris Manton} 21353d559ca99e93d442d12c548104f939870862ea6Chris Manton 2143a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonstatic void bucket_free_(void *data) { 2153a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton assert(data != NULL); 2163a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)data; 21753f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson const hash_map_t *hash_map = hash_map_entry->hash_map; 2183a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 21953f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson if (hash_map->key_fn) 22053f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->key_fn((void *)hash_map_entry->key); 22153f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson if (hash_map->data_fn) 22253f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->data_fn(hash_map_entry->data); 22353f36a45bd5333db3b55f1d7fbcd7a3362027de0Zach Johnson hash_map->allocator->free(hash_map_entry); 2243a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 2253a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 2263a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Mantonstatic hash_map_entry_t * find_bucket_entry_(list_t *hash_bucket_list, 2273a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton const void *key) { 2283a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 2293a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton if (hash_bucket_list == NULL) 2303a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return NULL; 2313a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton 2323a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton for (const list_node_t *iter = list_begin(hash_bucket_list); 2333a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton iter != list_end(hash_bucket_list); 2343a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton iter = list_next(iter)) { 2353a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton hash_map_entry_t *hash_map_entry = (hash_map_entry_t *)list_node(iter); 236aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson if (hash_map_entry->hash_map->keys_are_equal(hash_map_entry->key, key)) { 2373a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return hash_map_entry; 2383a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } 2393a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton } 2403a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton return NULL; 2413a2ee939c61a1c3f57fa3eb99899ba908c41e7d5Chris Manton} 242aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson 243aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnsonstatic bool default_key_equality(const void *x, const void *y) { 244aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson return x == y; 245aa3a0114b6f018d0dd296d5bdb113d2f881cbc51Zach Johnson} 246