BRL-CAD
hash.h
Go to the documentation of this file.
1 /* H A S H . H
2  * BRL-CAD
3  *
4  * Copyright (c) 2004-2024 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 
21 #ifndef BU_HASH_H
22 #define BU_HASH_H
23 
24 #include "common.h"
25 
26 #include "bu/defines.h"
27 
28 __BEGIN_DECLS
29 
30 /** @addtogroup bu_hash
31  * @brief
32  * An implementation of hash tables. TODO - need much better discussion here. Key points:
33  *
34  * 1. Keys are copied to the table and do not need to be maintained by the user
35  * 2. All keys, regardless of original type, are handled as byte arrays. Need
36  * examples of using strings and pointers as has keys
37  * 3. Void pointers sorted as values are *not* copies - the application must keep
38  * the data pointed to by the pointers intact and not rely on the table.
39  * 4. Performance is not currently a focus of bu_hash - it is not currently suitable
40  * for applications where high performance is critical.
41  */
42 /** @{ */
43 /** @file bu/hash.h */
44 
45 /* Use typedefs to hide the details of the hash entry and table structures */
46 typedef struct bu_hash_entry bu_hash_entry;
47 typedef struct bu_hash_tbl bu_hash_tbl;
48 
49 
50 /**
51  * Create and initialize a hash table. The input is the number of desired hash
52  * bins. This number will be rounded up to the nearest power of two, or a
53  * minimal size if tbl_size is smaller than the internal minimum bin count.
54  */
55 BU_EXPORT extern bu_hash_tbl *bu_hash_create(unsigned long tbl_size);
56 
57 
58 /**
59  * Free all the memory associated with the specified hash table.
60  *
61  * Note that the keys are freed (they are copies), but the "values"
62  * are not freed. (The values are merely pointers)
63  */
64 BU_EXPORT extern void bu_hash_destroy(bu_hash_tbl *t);
65 
66 
67 /**
68  * Get the value stored in the hash table entry corresponding to the provided key
69  *
70  * @param[in] t - The hash table to look in
71  * @param[in] key - the key to look for
72  * @param[in] key_len - the length of the key in bytes
73  *
74  * @return
75  * the void pointer stored in the hash table entry corresponding to key, or
76  * NULL if no entry corresponding to key exists.
77  */
78 BU_EXPORT extern void *bu_hash_get(const bu_hash_tbl *t, const uint8_t *key, size_t key_len);
79 
80 
81 /**
82  * Set the value stored in the hash table entry corresponding to the provided
83  * key to val, or if no entry corresponding to the provided key exists create a
84  * new entry associating the key and value. The key value is stored in the
85  * hash entry, but the table does not maintain its own copy of val - ensuring
86  * the value pointer remains valid is the responsibility of the caller.
87  *
88  * Null or zero length keys are not supported. The table will also not store
89  * a key/value combination where the value is NULL, but for random access with
90  * bu_hash_get get this won't matter because the return value for a key not
91  * in the table is NULL - i.e. the return will be the same as if the key/value
92  * pair had actually been added. The only use case where this property is observable
93  * is when a user iterates over the whole contents of a hash table - in that
94  * situation a key, NULL entry might be expected, but will not be present.
95  *
96  * @param[in] t - The hash table to look in
97  * @param[in] key - the key to look for
98  * @param[in] key_len - the length of the key in bytes
99  * @param[in] val - the value to be associated with key
100  *
101  * @return
102  * 1 if a new entry is created, 0 if an existing value was updated, -1 on error.
103  */
104 BU_EXPORT extern int bu_hash_set(bu_hash_tbl *t, const uint8_t *key, size_t key_len, void *val);
105 
106 
107 /**
108  * Remove the hash table entry associated with key from the table.
109  *
110  * @param[in] t - The hash table to look in
111  * @param[in] key - the key to look for
112  * @param[in] key_len - the length of the key in bytes
113  */
114 BU_EXPORT extern void bu_hash_rm(bu_hash_tbl *t, const uint8_t *key, size_t key_len);
115 
116 
117 /**
118  * Supports iteration of all the contents in a hash table.
119  *
120  * @param[in] t - The hash table to look in
121  * @param[in] p - the previous entry in the iteration
122  *
123  * This example prints all values in a hash table:
124  * @code
125  * void print_vals(struct bu_hash_tbl *t) {
126  * struct bu_hash_entry *e = bu_hash_next(t, NULL);
127  * while (e) {
128  * bu_log("Value: %p\n", bu_hash_value(e, NULL));
129  * e = bu_hash_next(t, e);
130  * }
131  * }
132  * @endcode
133  *
134  * @return
135  * Either first entry (if p is NULL) or next entry (if p is NON-null). Returns
136  * NULL when p is last entry in table.
137  */
138 BU_EXPORT extern bu_hash_entry *bu_hash_next(bu_hash_tbl *t, bu_hash_entry *p);
139 
140 
141 /**
142  * Supports iteration of all the contents in a hash table.
143  *
144  * @param[in] e - The hash table to look in
145  *
146  * @param[out] key - the entry's key
147  * @param[out] key_len - the length of the entry's key
148  *
149  * @return
150  * Returns 0 on success, 1 on failure.
151  */
152 BU_EXPORT extern int bu_hash_key(bu_hash_entry *e, uint8_t **key, size_t *key_len);
153 
154 
155 /* returns value of bu_hash_entry if nval is NULL.
156  * returns nval if nval was assigned to p's value.
157  * returns NULL on error */
158 
159 /**
160  * Extracts or updates the void pointer value for a bu_hash_entry. If nval is
161  * not NULL the entry will be updated.
162  *
163  * @param[in] e - The hash table to look in
164  * @param[in] nval - The new void pointer to assign to the entry's value slot, or NULL if no assignment is to be made.
165  *
166  * @return Returns the hash entry's value pointer, or NULL on error.
167  */
168 BU_EXPORT extern void *bu_hash_value(bu_hash_entry *e, void *nval);
169 
170 /** @} */
171 
172 
173 
174 /***************************************************************************
175  * Given data, return an unsigned long long value based on a hashing
176  * calculation. Unlike bu_hash_tbl and its related functions, this
177  * functionality does not implement key/value data storage - it's current
178  * primary use case is generation of content-based UUIDs.
179  *
180  * We are deliberately not documenting the hashing algorithm used
181  * to allow for "under the hood" improvements to its properties over time, and
182  * there should be no assumption of the equality of the hashed value between
183  * different versions of BRL-CAD.
184  *
185  * One of the uses for this function is to provide a "good enough" content-
186  * based universally unique identifier, similarly to how Git uses SHA1 hashes
187  * as UUIDs for commits.
188  **************************************************************************/
189 BU_EXPORT unsigned long long
190 bu_data_hash(const void *data, size_t len);
191 
192 /* bu_data_hash is the simple API, but there are situations where we need to
193  * build up the data to be used for hashing from multiple inputs. For that
194  * case, the below API allows for updating a persistent hash state.
195  */
196 struct bu_data_hash_impl;
197 struct bu_data_hash_state {
198  struct bu_data_hash_impl *i;
199 };
200 
201 BU_EXPORT struct bu_data_hash_state *
202 bu_data_hash_create(void);
203 
204 BU_EXPORT void
206 
207 BU_EXPORT void
208 bu_data_hash_update(struct bu_data_hash_state *s, const void *data, size_t len);
209 
210 BU_EXPORT unsigned long long
212 
213 
214 __END_DECLS
215 
216 #endif /* BU_HASH_H */
217 
218 
219 /*
220  * Local Variables:
221  * mode: C
222  * tab-width: 8
223  * indent-tabs-mode: t
224  * c-file-style: "stroustrup"
225  * End:
226  * ex: shiftwidth=4 tabstop=8
227  */
Header file for the BRL-CAD common definitions.
void * bu_hash_get(const bu_hash_tbl *t, const uint8_t *key, size_t key_len)
struct bu_hash_tbl bu_hash_tbl
Definition: hash.h:48
void bu_hash_destroy(bu_hash_tbl *t)
struct bu_hash_entry bu_hash_entry
Definition: hash.h:47
bu_hash_entry * bu_hash_next(bu_hash_tbl *t, bu_hash_entry *p)
int bu_hash_key(bu_hash_entry *e, uint8_t **key, size_t *key_len)
int bu_hash_set(bu_hash_tbl *t, const uint8_t *key, size_t key_len, void *val)
void bu_hash_rm(bu_hash_tbl *t, const uint8_t *key, size_t key_len)
bu_hash_tbl * bu_hash_create(unsigned long tbl_size)
void * bu_hash_value(bu_hash_entry *e, void *nval)
unsigned long long bu_data_hash_val(struct bu_data_hash_state *s)
void bu_data_hash_update(struct bu_data_hash_state *s, const void *data, size_t len)
struct bu_data_hash_state * bu_data_hash_create(void)
void bu_data_hash_destroy(struct bu_data_hash_state *s)
unsigned long long bu_data_hash(const void *data, size_t len)
struct bu_data_hash_impl * i
Definition: hash.h:199