109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher/**************************************************************************
209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher *
309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * Copyright 2008 VMware, Inc.
409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * All Rights Reserved.
509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher *
609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * Permission is hereby granted, free of charge, to any person obtaining a
709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * copy of this software and associated documentation files (the
809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * "Software"), to deal in the Software without restriction, including
909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * without limitation the rights to use, copy, modify, merge, publish,
1009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * distribute, sub license, and/or sell copies of the Software, and to
1109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * permit persons to whom the Software is furnished to do so, subject to
1209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * the following conditions:
1309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher *
1409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * The above copyright notice and this permission notice (including the
1509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * next paragraph) shall be included in all copies or substantial portions
1609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * of the Software.
1709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher *
1809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
2209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher *
2609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher **************************************************************************/
2709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
2809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher/**
2909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * @file
3009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * General purpose hash table implementation.
3109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher *
3209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * Just uses the util_hash for now, but it might be better switch to a linear
3309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * probing hash table implementation at some point -- as it is said they have
3409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * better lookup and cache performance and it appears to be possible to write
3509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * a lock-free implementation of such hash tables .
3609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher *
3709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher * @author José Fonseca <jfonseca@vmware.com>
3809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher */
3909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
4009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
41f4c2bfd63e55b9c878f4c1420af15a88c57b43a2Emil Velikov#ifdef HAVE_CONFIG_H
42f4c2bfd63e55b9c878f4c1420af15a88c57b43a2Emil Velikov#include "config.h"
43f4c2bfd63e55b9c878f4c1420af15a88c57b43a2Emil Velikov#endif
4409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
4509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher#include "util_hash_table.h"
4609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher#include "util_hash.h"
4709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
4809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher#include <stdlib.h>
4909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher#include <assert.h>
5009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
5109361395363805b5892d48d7bc10cf717e4d2927Alex Deucherstruct util_hash_table
5209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
5309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash *head;
5409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
5509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	/** Hash function */
5609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	unsigned (*make_hash)(void *key);
5709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
5809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	/** Compare two keys */
5909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	int (*compare)(void *key1, void *key2);
6009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher};
6109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
6209361395363805b5892d48d7bc10cf717e4d2927Alex Deucherstruct util_hash_table_item
6309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
6409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	void *key;
6509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	void *value;
6609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher};
6709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
6809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
6909361395363805b5892d48d7bc10cf717e4d2927Alex Deucherstatic struct util_hash_table_item *
7009361395363805b5892d48d7bc10cf717e4d2927Alex Deucherutil_hash_table_item(struct util_hash_iter iter)
7109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
7209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	return (struct util_hash_table_item *)util_hash_iter_data(iter);
7309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
7409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
75f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovdrm_private struct util_hash_table *
76f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovutil_hash_table_create(unsigned (*hash)(void *key),
77f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikov		       int (*compare)(void *key1, void *key2))
7809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
7909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table *ht;
8009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
8109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	ht = malloc(sizeof(struct util_hash_table));
8209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if(!ht)
8309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return NULL;
8409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
8509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	ht->head = util_hash_create();
8609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if(!ht->head) {
8709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		free(ht);
8809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return NULL;
8909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
9009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
9109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	ht->make_hash = hash;
9209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	ht->compare = compare;
9309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
9409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	return ht;
9509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
9609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
9709361395363805b5892d48d7bc10cf717e4d2927Alex Deucherstatic struct util_hash_iter
9809361395363805b5892d48d7bc10cf717e4d2927Alex Deucherutil_hash_table_find_iter(struct util_hash_table *ht,
9909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher			  void *key, unsigned key_hash)
10009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
10109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_iter iter;
10209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
10309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
10409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	iter = util_hash_find(ht->head, key_hash);
10509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	while (!util_hash_iter_is_null(iter)) {
10609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		item = (struct util_hash_table_item *)util_hash_iter_data(iter);
10709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		if (!ht->compare(item->key, key))
10809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher			break;
10909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		iter = util_hash_iter_next(iter);
11009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
11109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
11209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	return iter;
11309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
11409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
11509361395363805b5892d48d7bc10cf717e4d2927Alex Deucherstatic struct util_hash_table_item *
11609361395363805b5892d48d7bc10cf717e4d2927Alex Deucherutil_hash_table_find_item(struct util_hash_table *ht,
11709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher                          void *key, unsigned key_hash)
11809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
11909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_iter iter;
12009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
12109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
12209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	iter = util_hash_find(ht->head, key_hash);
12309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	while (!util_hash_iter_is_null(iter)) {
12409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		item = (struct util_hash_table_item *)util_hash_iter_data(iter);
12509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		if (!ht->compare(item->key, key))
12609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher			return item;
12709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		iter = util_hash_iter_next(iter);
12809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
12909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
13009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	return NULL;
13109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
13209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
133f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovdrm_private void
134f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovutil_hash_table_set(struct util_hash_table *ht, void *key, void *value)
13509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
13609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	unsigned key_hash;
13709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
13809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_iter iter;
13909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
14009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	assert(ht);
14109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if (!ht)
14209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
14309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
14409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	key_hash = ht->make_hash(key);
14509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
14609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	item = util_hash_table_find_item(ht, key, key_hash);
14709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if(item) {
14809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		/* TODO: key/value destruction? */
14909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		item->value = value;
15009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
15109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
15209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
15309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	item = malloc(sizeof(struct util_hash_table_item));
15409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if(!item)
15509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
15609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
15709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	item->key = key;
15809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	item->value = value;
15909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
16009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	iter = util_hash_insert(ht->head, key_hash, item);
16109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if(util_hash_iter_is_null(iter)) {
16209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		free(item);
16309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
16409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
16509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
16609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
167f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovdrm_private void *util_hash_table_get(struct util_hash_table *ht, void *key)
16809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
16909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	unsigned key_hash;
17009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
17109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
17209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	assert(ht);
17309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if (!ht)
17409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return NULL;
17509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
17609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	key_hash = ht->make_hash(key);
17709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
17809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	item = util_hash_table_find_item(ht, key, key_hash);
17909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if(!item)
18009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return NULL;
18109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
18209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	return item->value;
18309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
18409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
185f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovdrm_private void util_hash_table_remove(struct util_hash_table *ht, void *key)
18609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
18709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	unsigned key_hash;
18809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_iter iter;
18909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
19009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
19109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	assert(ht);
19209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if (!ht)
19309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
19409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
19509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	key_hash = ht->make_hash(key);
19609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
19709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	iter = util_hash_table_find_iter(ht, key, key_hash);
19809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if(util_hash_iter_is_null(iter))
19909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
20009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
20109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	item = util_hash_table_item(iter);
20209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	assert(item);
20309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	free(item);
20409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
20509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	util_hash_erase(ht->head, iter);
20609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
20709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
208f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovdrm_private void util_hash_table_clear(struct util_hash_table *ht)
20909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
21009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_iter iter;
21109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
21209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
21309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	assert(ht);
21409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if (!ht)
21509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
21609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
21709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	iter = util_hash_first_node(ht->head);
21809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	while (!util_hash_iter_is_null(iter)) {
21909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		item = (struct util_hash_table_item *)util_hash_take(ht->head, util_hash_iter_key(iter));
22009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		free(item);
22109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		iter = util_hash_first_node(ht->head);
22209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
22309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
22409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
225f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovdrm_private void util_hash_table_foreach(struct util_hash_table *ht,
22609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher			void (*callback)(void *key, void *value, void *data),
22709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher			void *data)
22809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
22909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_iter iter;
23009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
23109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
23209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	assert(ht);
23309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if (!ht)
23409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
23509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
23609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	iter = util_hash_first_node(ht->head);
23709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	while (!util_hash_iter_is_null(iter)) {
23809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		item = (struct util_hash_table_item *)util_hash_iter_data(iter);
23909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		callback(item->key, item->value, data);
24009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		iter = util_hash_iter_next(iter);
24109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
24209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
24309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
244f4d14f147cfc2bdea4f1ffafcfd302ebdfbcef1dEmil Velikovdrm_private void util_hash_table_destroy(struct util_hash_table *ht)
24509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher{
24609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_iter iter;
24709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	struct util_hash_table_item *item;
24809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
24909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	assert(ht);
25009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	if (!ht)
25109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		return;
25209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
25309361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	iter = util_hash_first_node(ht->head);
25409361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	while (!util_hash_iter_is_null(iter)) {
25509361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		item = (struct util_hash_table_item *)util_hash_iter_data(iter);
25609361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		free(item);
25709361395363805b5892d48d7bc10cf717e4d2927Alex Deucher		iter = util_hash_iter_next(iter);
25809361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	}
25909361395363805b5892d48d7bc10cf717e4d2927Alex Deucher
26009361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	util_hash_delete(ht->head);
26109361395363805b5892d48d7bc10cf717e4d2927Alex Deucher	free(ht);
26209361395363805b5892d48d7bc10cf717e4d2927Alex Deucher}
263