Coverage Report

Created: 2025-06-22 06:56

/src/json-c/linkhash.h
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $
3
 *
4
 * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5
 * Michael Clark <michael@metaparadigm.com>
6
 * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
7
 *
8
 * This library is free software; you can redistribute it and/or modify
9
 * it under the terms of the MIT license. See COPYING for details.
10
 *
11
 */
12
13
/**
14
 * @file
15
 * @brief Internal methods for working with json_type_object objects.  Although
16
 *        this is exposed by the json_object_get_object() function and within the
17
 *        json_object_iter type, it is not recommended for direct use.
18
 */
19
#ifndef _json_c_linkhash_h_
20
#define _json_c_linkhash_h_
21
22
#include "json_object.h"
23
24
#ifdef __cplusplus
25
extern "C" {
26
#endif
27
28
/**
29
 * golden prime used in hash functions
30
 */
31
0
#define LH_PRIME 0x9e370001UL
32
33
/**
34
 * The fraction of filled hash buckets until an insert will cause the table
35
 * to be resized.
36
 * This can range from just above 0 up to 1.0.
37
 */
38
177k
#define LH_LOAD_FACTOR 0.66
39
40
/**
41
 * sentinel pointer value for empty slots
42
 */
43
2.29M
#define LH_EMPTY (void *)-1
44
45
/**
46
 * sentinel pointer value for freed slots
47
 */
48
746k
#define LH_FREED (void *)-2
49
50
/**
51
 * default string hash function
52
 */
53
0
#define JSON_C_STR_HASH_DFLT 0
54
55
/**
56
 * perl-like string hash function
57
 */
58
0
#define JSON_C_STR_HASH_PERLLIKE 1
59
60
/**
61
 * This function sets the hash function to be used for strings.
62
 * Must be one of the JSON_C_STR_HASH_* values.
63
 * @returns 0 - ok, -1 if parameter was invalid
64
 */
65
int json_global_set_string_hash(const int h);
66
67
struct lh_entry;
68
69
/**
70
 * callback function prototypes
71
 */
72
typedef void(lh_entry_free_fn)(struct lh_entry *e);
73
/**
74
 * callback function prototypes
75
 */
76
typedef unsigned long(lh_hash_fn)(const void *k);
77
/**
78
 * callback function prototypes
79
 */
80
typedef int(lh_equal_fn)(const void *k1, const void *k2);
81
82
/**
83
 * An entry in the hash table.  Outside of linkhash.c, treat this as opaque.
84
 */
85
struct lh_entry
86
{
87
  /**
88
   * The key.
89
   * @deprecated Use lh_entry_k() instead of accessing this directly.
90
   */
91
  const void *k;
92
  /**
93
   * A flag for users of linkhash to know whether or not they
94
   * need to free k.
95
   * @deprecated use lh_entry_k_is_constant() instead.
96
   */
97
  int k_is_constant;
98
  /**
99
   * The value.
100
   * @deprecated Use lh_entry_v() instead of accessing this directly.
101
   */
102
  const void *v;
103
  /**
104
   * The next entry.
105
   * @deprecated Use lh_entry_next() instead of accessing this directly.
106
   */
107
  struct lh_entry *next;
108
  /**
109
   * The previous entry.
110
   * @deprecated Use lh_entry_prev() instead of accessing this directly.
111
   */
112
  struct lh_entry *prev;
113
};
114
115
/**
116
 * The hash table structure.  Outside of linkhash.c, treat this as opaque.
117
 */
118
struct lh_table
119
{
120
  /**
121
   * Size of our hash.
122
   * @deprecated do not use outside of linkhash.c
123
   */
124
  int size;
125
  /**
126
   * Numbers of entries.
127
   * @deprecated Use lh_table_length() instead.
128
   */
129
  int count;
130
131
  /**
132
   * The first entry.
133
   * @deprecated Use lh_table_head() instead.
134
   */
135
  struct lh_entry *head;
136
137
  /**
138
   * The last entry.
139
   * @deprecated Do not use, may be removed in a future release.
140
   */
141
  struct lh_entry *tail;
142
143
  /**
144
   * Internal storage of the actual table of entries.
145
   * @deprecated do not use outside of linkhash.c
146
   */
147
  struct lh_entry *table;
148
149
  /**
150
   * A pointer to the function responsible for freeing an entry.
151
   * @deprecated do not use outside of linkhash.c
152
   */
153
  lh_entry_free_fn *free_fn;
154
  /**
155
   * @deprecated do not use outside of linkhash.c
156
   */
157
  lh_hash_fn *hash_fn;
158
  /**
159
   * @deprecated do not use outside of linkhash.c
160
   */
161
  lh_equal_fn *equal_fn;
162
};
163
typedef struct lh_table lh_table;
164
165
/**
166
 * Convenience list iterator.
167
 */
168
#define lh_foreach(table, entry) for (entry = lh_table_head(table); entry; entry = lh_entry_next(entry))
169
170
/**
171
 * lh_foreach_safe allows calling of deletion routine while iterating.
172
 *
173
 * @param table a struct lh_table * to iterate over
174
 * @param entry a struct lh_entry * variable to hold each element
175
 * @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
176
 */
177
#define lh_foreach_safe(table, entry, tmp) \
178
  for (entry = lh_table_head(table); entry && ((tmp = lh_entry_next(entry)) || 1); entry = tmp)
179
180
/**
181
 * Create a new linkhash table.
182
 *
183
 * @param size initial table size. The table is automatically resized
184
 * although this incurs a performance penalty.
185
 * @param free_fn callback function used to free memory for entries
186
 * when lh_table_free or lh_table_delete is called.
187
 * If NULL is provided, then memory for keys and values
188
 * must be freed by the caller.
189
 * @param hash_fn  function used to hash keys. 2 standard ones are defined:
190
 * lh_ptr_hash and lh_char_hash for hashing pointer values
191
 * and C strings respectively.
192
 * @param equal_fn comparison function to compare keys. 2 standard ones defined:
193
 * lh_ptr_hash and lh_char_hash for comparing pointer values
194
 * and C strings respectively.
195
 * @return On success, a pointer to the new linkhash table is returned.
196
 *  On error, a null pointer is returned.
197
 */
198
extern struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn,
199
                                     lh_equal_fn *equal_fn);
200
201
/**
202
 * Convenience function to create a new linkhash table with char keys.
203
 *
204
 * @param size initial table size.
205
 * @param free_fn callback function used to free memory for entries.
206
 * @return On success, a pointer to the new linkhash table is returned.
207
 *  On error, a null pointer is returned.
208
 */
209
extern struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn);
210
211
/**
212
 * Convenience function to create a new linkhash table with ptr keys.
213
 *
214
 * @param size initial table size.
215
 * @param free_fn callback function used to free memory for entries.
216
 * @return On success, a pointer to the new linkhash table is returned.
217
 *  On error, a null pointer is returned.
218
 */
219
extern struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn);
220
221
/**
222
 * Free a linkhash table.
223
 *
224
 * If a lh_entry_free_fn callback free function was provided then it is
225
 * called for all entries in the table.
226
 *
227
 * @param t table to free.
228
 */
229
extern void lh_table_free(struct lh_table *t);
230
231
/**
232
 * Insert a record into the table.
233
 *
234
 * @param t the table to insert into.
235
 * @param k a pointer to the key to insert.
236
 * @param v a pointer to the value to insert.
237
 *
238
 * @return On success, <code>0</code> is returned.
239
 *  On error, a negative value is returned.
240
 */
241
extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
242
243
/**
244
 * Insert a record into the table using a precalculated key hash.
245
 *
246
 * The hash h, which should be calculated with lh_get_hash() on k, is provided by
247
 *  the caller, to allow for optimization when multiple operations with the same
248
 *  key are known to be needed.
249
 *
250
 * @param t the table to insert into.
251
 * @param k a pointer to the key to insert.
252
 * @param v a pointer to the value to insert.
253
 * @param h hash value of the key to insert
254
 * @param opts if set to JSON_C_OBJECT_ADD_CONSTANT_KEY, sets lh_entry.k_is_constant
255
 *             so t's free function knows to avoid freeing the key.
256
 */
257
extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v,
258
                                  const unsigned long h, const unsigned opts);
259
260
/**
261
 * Lookup a record in the table.
262
 *
263
 * @param t the table to lookup
264
 * @param k a pointer to the key to lookup
265
 * @return a pointer to the record structure of the value or NULL if it does not exist.
266
 */
267
extern struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k);
268
269
/**
270
 * Lookup a record in the table using a precalculated key hash.
271
 *
272
 * The hash h, which should be calculated with lh_get_hash() on k, is provided by
273
 *  the caller, to allow for optimization when multiple operations with the same
274
 *  key are known to be needed.
275
 *
276
 * @param t the table to lookup
277
 * @param k a pointer to the key to lookup
278
 * @param h hash value of the key to lookup
279
 * @return a pointer to the record structure of the value or NULL if it does not exist.
280
 */
281
extern struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k,
282
                                                     const unsigned long h);
283
284
/**
285
 * Lookup a record in the table.
286
 *
287
 * @param t the table to lookup
288
 * @param k a pointer to the key to lookup
289
 * @param v a pointer to a where to store the found value (set to NULL if it doesn't exist).
290
 * @return whether or not the key was found
291
 */
292
extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v);
293
294
/**
295
 * Delete a record from the table.
296
 *
297
 * If a callback free function is provided then it is called for the
298
 * for the item being deleted.
299
 * @param t the table to delete from.
300
 * @param e a pointer to the entry to delete.
301
 * @return 0 if the item was deleted.
302
 * @return -1 if it was not found.
303
 */
304
extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
305
306
/**
307
 * Delete a record from the table.
308
 *
309
 * If a callback free function is provided then it is called for the
310
 * for the item being deleted.
311
 * @param t the table to delete from.
312
 * @param k a pointer to the key to delete.
313
 * @return 0 if the item was deleted.
314
 * @return -1 if it was not found.
315
 */
316
extern int lh_table_delete(struct lh_table *t, const void *k);
317
318
/**
319
 * Return the number of entries in the table.
320
 */
321
extern int lh_table_length(struct lh_table *t);
322
323
/**
324
 * Resizes the specified table.
325
 *
326
 * @param t Pointer to table to resize.
327
 * @param new_size New table size. Must be positive.
328
 *
329
 * @return On success, <code>0</code> is returned.
330
 *  On error, a negative value is returned.
331
 */
332
int lh_table_resize(struct lh_table *t, int new_size);
333
334
/**
335
 * @deprecated Don't use this outside of linkhash.h:
336
 */
337
#if !defined (__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
338
/* C89 compilers like VS2010 can't handle inline funcs, so skip it there,
339
   note: this also applies to -std=c89 in GCC! */
340
#define _LH_INLINE
341
#else
342
#define _LH_INLINE inline
343
#endif
344
345
/**
346
 * Return the first entry in the lh_table.
347
 * @see lh_entry_next()
348
 */
349
static _LH_INLINE struct lh_entry *lh_table_head(const lh_table *t)
350
58.9k
{
351
58.9k
  return t->head;
352
58.9k
}
json_object.c:lh_table_head
Line
Count
Source
350
58.9k
{
351
58.9k
  return t->head;
352
58.9k
}
Unexecuted instantiation: linkhash.c:lh_table_head
353
354
/**
355
 * Calculate the hash of a key for a given table.
356
 *
357
 * This is an extension to support functions that need to calculate
358
 * the hash several times and allows them to do it just once and then pass
359
 * in the hash to all utility functions. Depending on use case, this can be a
360
 * considerable performance improvement.
361
 * @param t the table (used to obtain hash function)
362
 * @param k a pointer to the key to lookup
363
 * @return the key's hash
364
 */
365
static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void *k)
366
465k
{
367
465k
  return t->hash_fn(k);
368
465k
}
json_object.c:lh_get_hash
Line
Count
Source
366
163k
{
367
163k
  return t->hash_fn(k);
368
163k
}
linkhash.c:lh_get_hash
Line
Count
Source
366
301k
{
367
301k
  return t->hash_fn(k);
368
301k
}
369
370
371
/**
372
 * @deprecated Don't use this outside of linkhash.h:
373
 */
374
#ifdef __UNCONST
375
#define _LH_UNCONST(a) __UNCONST(a)
376
#else
377
788k
#define _LH_UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
378
#endif
379
380
/**
381
 * Return a non-const version of lh_entry.k.
382
 *
383
 * lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
384
 * it, but callers are allowed to do what they want with it.
385
 * @see lh_entry_k_is_constant()
386
 */
387
static _LH_INLINE void *lh_entry_k(const struct lh_entry *e)
388
270k
{
389
270k
  return _LH_UNCONST(e->k);
390
270k
}
json_object.c:lh_entry_k
Line
Count
Source
388
270k
{
389
270k
  return _LH_UNCONST(e->k);
390
270k
}
Unexecuted instantiation: linkhash.c:lh_entry_k
391
392
/**
393
 * Returns 1 if the key for the given entry is constant, and thus
394
 *  does not need to be freed when the lh_entry is freed.
395
 * @see lh_table_insert_w_hash()
396
 */
397
static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e)
398
156k
{
399
156k
  return e->k_is_constant;
400
156k
}
json_object.c:lh_entry_k_is_constant
Line
Count
Source
398
156k
{
399
156k
  return e->k_is_constant;
400
156k
}
Unexecuted instantiation: linkhash.c:lh_entry_k_is_constant
401
402
/**
403
 * Return a non-const version of lh_entry.v.
404
 *
405
 * v is const to indicate and help ensure that linkhash itself doesn't modify
406
 * it, but callers are allowed to do what they want with it.
407
 */
408
static _LH_INLINE void *lh_entry_v(const struct lh_entry *e)
409
518k
{
410
518k
  return _LH_UNCONST(e->v);
411
518k
}
json_object.c:lh_entry_v
Line
Count
Source
409
277k
{
410
277k
  return _LH_UNCONST(e->v);
411
277k
}
linkhash.c:lh_entry_v
Line
Count
Source
409
240k
{
410
240k
  return _LH_UNCONST(e->v);
411
240k
}
412
413
/**
414
 * Change the value for an entry.  The caller is responsible for freeing
415
 *  the previous value.
416
 */
417
static _LH_INLINE void lh_entry_set_val(struct lh_entry *e, void *newval)
418
7.60k
{
419
7.60k
  e->v = newval;
420
7.60k
}
json_object.c:lh_entry_set_val
Line
Count
Source
418
7.60k
{
419
7.60k
  e->v = newval;
420
7.60k
}
Unexecuted instantiation: linkhash.c:lh_entry_set_val
421
422
/**
423
 * Return the next element, or NULL if there is no next element.
424
 * @see lh_table_head()
425
 * @see lh_entry_prev()
426
 */
427
static _LH_INLINE struct lh_entry *lh_entry_next(const struct lh_entry *e)
428
114k
{
429
114k
  return e->next;
430
114k
}
json_object.c:lh_entry_next
Line
Count
Source
428
114k
{
429
114k
  return e->next;
430
114k
}
Unexecuted instantiation: linkhash.c:lh_entry_next
431
432
/**
433
 * Return the previous element, or NULL if there is no previous element.
434
 * @see lh_table_head()
435
 * @see lh_entry_next()
436
 */
437
static _LH_INLINE struct lh_entry *lh_entry_prev(const struct lh_entry *e)
438
0
{
439
0
  return e->prev;
440
0
}
Unexecuted instantiation: json_object.c:lh_entry_prev
Unexecuted instantiation: linkhash.c:lh_entry_prev
441
442
#undef _LH_INLINE
443
444
#ifdef __cplusplus
445
}
446
#endif
447
448
#endif