1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2009,2012 Intel Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci *
23bf215546Sopenharmony_ci * Authors:
24bf215546Sopenharmony_ci *    Eric Anholt <eric@anholt.net>
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci */
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#ifndef _HASH_TABLE_H
29bf215546Sopenharmony_ci#define _HASH_TABLE_H
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include <stdlib.h>
32bf215546Sopenharmony_ci#include <inttypes.h>
33bf215546Sopenharmony_ci#include <stdbool.h>
34bf215546Sopenharmony_ci#include "macros.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#ifdef __cplusplus
37bf215546Sopenharmony_ciextern "C" {
38bf215546Sopenharmony_ci#endif
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_cistruct hash_entry {
41bf215546Sopenharmony_ci   uint32_t hash;
42bf215546Sopenharmony_ci   const void *key;
43bf215546Sopenharmony_ci   void *data;
44bf215546Sopenharmony_ci};
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_cistruct hash_table {
47bf215546Sopenharmony_ci   struct hash_entry *table;
48bf215546Sopenharmony_ci   uint32_t (*key_hash_function)(const void *key);
49bf215546Sopenharmony_ci   bool (*key_equals_function)(const void *a, const void *b);
50bf215546Sopenharmony_ci   const void *deleted_key;
51bf215546Sopenharmony_ci   uint32_t size;
52bf215546Sopenharmony_ci   uint32_t rehash;
53bf215546Sopenharmony_ci   uint64_t size_magic;
54bf215546Sopenharmony_ci   uint64_t rehash_magic;
55bf215546Sopenharmony_ci   uint32_t max_entries;
56bf215546Sopenharmony_ci   uint32_t size_index;
57bf215546Sopenharmony_ci   uint32_t entries;
58bf215546Sopenharmony_ci   uint32_t deleted_entries;
59bf215546Sopenharmony_ci};
60bf215546Sopenharmony_ci
61bf215546Sopenharmony_cistruct hash_table *
62bf215546Sopenharmony_ci_mesa_hash_table_create(void *mem_ctx,
63bf215546Sopenharmony_ci                        uint32_t (*key_hash_function)(const void *key),
64bf215546Sopenharmony_ci                        bool (*key_equals_function)(const void *a,
65bf215546Sopenharmony_ci                                                    const void *b));
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_cibool
68bf215546Sopenharmony_ci_mesa_hash_table_init(struct hash_table *ht,
69bf215546Sopenharmony_ci                      void *mem_ctx,
70bf215546Sopenharmony_ci                      uint32_t (*key_hash_function)(const void *key),
71bf215546Sopenharmony_ci                      bool (*key_equals_function)(const void *a,
72bf215546Sopenharmony_ci                                                  const void *b));
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_cistruct hash_table *
75bf215546Sopenharmony_ci_mesa_hash_table_create_u32_keys(void *mem_ctx);
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_cistruct hash_table *
78bf215546Sopenharmony_ci_mesa_hash_table_clone(struct hash_table *src, void *dst_mem_ctx);
79bf215546Sopenharmony_civoid _mesa_hash_table_destroy(struct hash_table *ht,
80bf215546Sopenharmony_ci                              void (*delete_function)(struct hash_entry *entry));
81bf215546Sopenharmony_civoid _mesa_hash_table_clear(struct hash_table *ht,
82bf215546Sopenharmony_ci                            void (*delete_function)(struct hash_entry *entry));
83bf215546Sopenharmony_civoid _mesa_hash_table_set_deleted_key(struct hash_table *ht,
84bf215546Sopenharmony_ci                                      const void *deleted_key);
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_cistatic inline uint32_t _mesa_hash_table_num_entries(struct hash_table *ht)
87bf215546Sopenharmony_ci{
88bf215546Sopenharmony_ci   return ht->entries;
89bf215546Sopenharmony_ci}
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_cistruct hash_entry *
92bf215546Sopenharmony_ci_mesa_hash_table_insert(struct hash_table *ht, const void *key, void *data);
93bf215546Sopenharmony_cistruct hash_entry *
94bf215546Sopenharmony_ci_mesa_hash_table_insert_pre_hashed(struct hash_table *ht, uint32_t hash,
95bf215546Sopenharmony_ci                                   const void *key, void *data);
96bf215546Sopenharmony_cistruct hash_entry *
97bf215546Sopenharmony_ci_mesa_hash_table_search(struct hash_table *ht, const void *key);
98bf215546Sopenharmony_cistruct hash_entry *
99bf215546Sopenharmony_ci_mesa_hash_table_search_pre_hashed(struct hash_table *ht, uint32_t hash,
100bf215546Sopenharmony_ci                                  const void *key);
101bf215546Sopenharmony_civoid _mesa_hash_table_remove(struct hash_table *ht,
102bf215546Sopenharmony_ci                             struct hash_entry *entry);
103bf215546Sopenharmony_civoid _mesa_hash_table_remove_key(struct hash_table *ht,
104bf215546Sopenharmony_ci                                 const void *key);
105bf215546Sopenharmony_ci
106bf215546Sopenharmony_cistruct hash_entry *_mesa_hash_table_next_entry(struct hash_table *ht,
107bf215546Sopenharmony_ci                                               struct hash_entry *entry);
108bf215546Sopenharmony_cistruct hash_entry *_mesa_hash_table_next_entry_unsafe(const struct hash_table *ht,
109bf215546Sopenharmony_ci                                               struct hash_entry *entry);
110bf215546Sopenharmony_cistruct hash_entry *
111bf215546Sopenharmony_ci_mesa_hash_table_random_entry(struct hash_table *ht,
112bf215546Sopenharmony_ci                              bool (*predicate)(struct hash_entry *entry));
113bf215546Sopenharmony_ci
114bf215546Sopenharmony_ciuint32_t _mesa_hash_data(const void *data, size_t size);
115bf215546Sopenharmony_ciuint32_t _mesa_hash_data_with_seed(const void *data, size_t size, uint32_t seed);
116bf215546Sopenharmony_ci
117bf215546Sopenharmony_ciuint32_t _mesa_hash_int(const void *key);
118bf215546Sopenharmony_ciuint32_t _mesa_hash_uint(const void *key);
119bf215546Sopenharmony_ciuint32_t _mesa_hash_u32(const void *key);
120bf215546Sopenharmony_ciuint32_t _mesa_hash_string(const void *key);
121bf215546Sopenharmony_ciuint32_t _mesa_hash_string_with_length(const void *_key, unsigned length);
122bf215546Sopenharmony_ciuint32_t _mesa_hash_pointer(const void *pointer);
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_cibool _mesa_key_int_equal(const void *a, const void *b);
125bf215546Sopenharmony_cibool _mesa_key_uint_equal(const void *a, const void *b);
126bf215546Sopenharmony_cibool _mesa_key_u32_equal(const void *a, const void *b);
127bf215546Sopenharmony_cibool _mesa_key_string_equal(const void *a, const void *b);
128bf215546Sopenharmony_cibool _mesa_key_pointer_equal(const void *a, const void *b);
129bf215546Sopenharmony_ci
130bf215546Sopenharmony_cistruct hash_table *
131bf215546Sopenharmony_ci_mesa_pointer_hash_table_create(void *mem_ctx);
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_cibool
134bf215546Sopenharmony_ci_mesa_hash_table_reserve(struct hash_table *ht, unsigned size);
135bf215546Sopenharmony_ci/**
136bf215546Sopenharmony_ci * This foreach function is safe against deletion (which just replaces
137bf215546Sopenharmony_ci * an entry's data with the deleted marker), but not against insertion
138bf215546Sopenharmony_ci * (which may rehash the table, making entry a dangling pointer).
139bf215546Sopenharmony_ci */
140bf215546Sopenharmony_ci#define hash_table_foreach(ht, entry)                                      \
141bf215546Sopenharmony_ci   for (struct hash_entry *entry = _mesa_hash_table_next_entry(ht, NULL);  \
142bf215546Sopenharmony_ci        entry != NULL;                                                     \
143bf215546Sopenharmony_ci        entry = _mesa_hash_table_next_entry(ht, entry))
144bf215546Sopenharmony_ci/**
145bf215546Sopenharmony_ci * This foreach function destroys the table as it iterates.
146bf215546Sopenharmony_ci * It is not safe to use when inserting or removing entries.
147bf215546Sopenharmony_ci */
148bf215546Sopenharmony_ci#define hash_table_foreach_remove(ht, entry)                                      \
149bf215546Sopenharmony_ci   for (struct hash_entry *entry = _mesa_hash_table_next_entry_unsafe(ht, NULL);  \
150bf215546Sopenharmony_ci        (ht)->entries;                                                     \
151bf215546Sopenharmony_ci        entry->hash = 0, entry->key = (void*)NULL, entry->data = NULL,      \
152bf215546Sopenharmony_ci        (ht)->entries--, entry = _mesa_hash_table_next_entry_unsafe(ht, entry))
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_cistatic inline void
155bf215546Sopenharmony_cihash_table_call_foreach(struct hash_table *ht,
156bf215546Sopenharmony_ci                        void (*callback)(const void *key,
157bf215546Sopenharmony_ci                                         void *data,
158bf215546Sopenharmony_ci                                         void *closure),
159bf215546Sopenharmony_ci                        void *closure)
160bf215546Sopenharmony_ci{
161bf215546Sopenharmony_ci   hash_table_foreach(ht, entry)
162bf215546Sopenharmony_ci      callback(entry->key, entry->data, closure);
163bf215546Sopenharmony_ci}
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci/**
166bf215546Sopenharmony_ci * Hash table wrapper which supports 64-bit keys.
167bf215546Sopenharmony_ci */
168bf215546Sopenharmony_cistruct hash_table_u64 {
169bf215546Sopenharmony_ci   struct hash_table *table;
170bf215546Sopenharmony_ci   void *freed_key_data;
171bf215546Sopenharmony_ci   void *deleted_key_data;
172bf215546Sopenharmony_ci};
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_cistruct hash_table_u64 *
175bf215546Sopenharmony_ci_mesa_hash_table_u64_create(void *mem_ctx);
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_civoid
178bf215546Sopenharmony_ci_mesa_hash_table_u64_destroy(struct hash_table_u64 *ht);
179bf215546Sopenharmony_ci
180bf215546Sopenharmony_civoid
181bf215546Sopenharmony_ci_mesa_hash_table_u64_insert(struct hash_table_u64 *ht, uint64_t key,
182bf215546Sopenharmony_ci                            void *data);
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_civoid *
185bf215546Sopenharmony_ci_mesa_hash_table_u64_search(struct hash_table_u64 *ht, uint64_t key);
186bf215546Sopenharmony_ci
187bf215546Sopenharmony_civoid
188bf215546Sopenharmony_ci_mesa_hash_table_u64_remove(struct hash_table_u64 *ht, uint64_t key);
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_civoid
191bf215546Sopenharmony_ci_mesa_hash_table_u64_clear(struct hash_table_u64 *ht);
192bf215546Sopenharmony_ci
193bf215546Sopenharmony_ci#ifdef __cplusplus
194bf215546Sopenharmony_ci} /* extern C */
195bf215546Sopenharmony_ci#endif
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci#endif /* _HASH_TABLE_H */
198