Coverage Report

Created: 2026-05-30 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/json-c/linkhash.h
Line
Count
Source
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
0
#define LH_LOAD_FACTOR 0.66
39
40
/**
41
 * sentinel pointer value for empty slots
42
 */
43
0
#define LH_EMPTY (void *)-1
44
45
/**
46
 * sentinel pointer value for freed slots
47
 */
48
0
#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 all entries from the specified one to the tail of the list.
308
 * Same as calling lh_table_delete_entry() on each of them.
309
 *
310
 * @param t the table to delete from.
311
 * @param e a pointer to the first entry to delete.
312
 * @return 0 if the item was deleted.
313
 * @return -1 if it was not found.
314
 */
315
extern int lh_table_delete_entry_to_tail(struct lh_table *t, struct lh_entry *e);
316
317
/**
318
 * Delete a record from the table.
319
 *
320
 * If a callback free function is provided then it is called for the
321
 * for the item being deleted.
322
 * @param t the table to delete from.
323
 * @param k a pointer to the key to delete.
324
 * @return 0 if the item was deleted.
325
 * @return -1 if it was not found.
326
 */
327
extern int lh_table_delete(struct lh_table *t, const void *k);
328
329
/**
330
 * Return the number of entries in the table.
331
 */
332
extern int lh_table_length(struct lh_table *t);
333
334
/**
335
 * Resizes the specified table.
336
 *
337
 * @param t Pointer to table to resize.
338
 * @param new_size New table size. Must be positive.
339
 *
340
 * @return On success, <code>0</code> is returned.
341
 *  On error, a negative value is returned.
342
 */
343
int lh_table_resize(struct lh_table *t, int new_size);
344
345
/**
346
 * @deprecated Don't use this outside of linkhash.h:
347
 */
348
#if !defined (__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
349
/* C89 compilers like VS2010 can't handle inline funcs, so skip it there,
350
   note: this also applies to -std=c89 in GCC! */
351
#define _LH_INLINE
352
#else
353
#define _LH_INLINE inline
354
#endif
355
356
/**
357
 * Return the first entry in the lh_table.
358
 * @see lh_entry_next()
359
 */
360
static _LH_INLINE struct lh_entry *lh_table_head(const lh_table *t)
361
0
{
362
0
  return t->head;
363
0
}
Unexecuted instantiation: json_object.c:lh_table_head
Unexecuted instantiation: linkhash.c:lh_table_head
364
365
/**
366
 * Calculate the hash of a key for a given table.
367
 *
368
 * This is an extension to support functions that need to calculate
369
 * the hash several times and allows them to do it just once and then pass
370
 * in the hash to all utility functions. Depending on use case, this can be a
371
 * considerable performance improvement.
372
 * @param t the table (used to obtain hash function)
373
 * @param k a pointer to the key to lookup
374
 * @return the key's hash
375
 */
376
static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void *k)
377
0
{
378
0
  return t->hash_fn(k);
379
0
}
Unexecuted instantiation: json_object.c:lh_get_hash
Unexecuted instantiation: linkhash.c:lh_get_hash
380
381
382
/**
383
 * @deprecated Don't use this outside of linkhash.h:
384
 */
385
#ifdef __UNCONST
386
#define _LH_UNCONST(a) __UNCONST(a)
387
#else
388
0
#define _LH_UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
389
#endif
390
391
/**
392
 * Return a non-const version of lh_entry.k.
393
 *
394
 * lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
395
 * it, but callers are allowed to do what they want with it.
396
 * @see lh_entry_k_is_constant()
397
 */
398
static _LH_INLINE void *lh_entry_k(const struct lh_entry *e)
399
0
{
400
0
  return _LH_UNCONST(e->k);
401
0
}
Unexecuted instantiation: json_object.c:lh_entry_k
Unexecuted instantiation: linkhash.c:lh_entry_k
402
403
/**
404
 * Returns 1 if the key for the given entry is constant, and thus
405
 *  does not need to be freed when the lh_entry is freed.
406
 * @see lh_table_insert_w_hash()
407
 */
408
static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e)
409
0
{
410
0
  return e->k_is_constant;
411
0
}
Unexecuted instantiation: json_object.c:lh_entry_k_is_constant
Unexecuted instantiation: linkhash.c:lh_entry_k_is_constant
412
413
/**
414
 * Return a non-const version of lh_entry.v.
415
 *
416
 * v is const to indicate and help ensure that linkhash itself doesn't modify
417
 * it, but callers are allowed to do what they want with it.
418
 */
419
static _LH_INLINE void *lh_entry_v(const struct lh_entry *e)
420
0
{
421
0
  return _LH_UNCONST(e->v);
422
0
}
Unexecuted instantiation: json_object.c:lh_entry_v
Unexecuted instantiation: linkhash.c:lh_entry_v
423
424
/**
425
 * Change the value for an entry.  The caller is responsible for freeing
426
 *  the previous value.
427
 */
428
static _LH_INLINE void lh_entry_set_val(struct lh_entry *e, void *newval)
429
0
{
430
0
  e->v = newval;
431
0
}
Unexecuted instantiation: json_object.c:lh_entry_set_val
Unexecuted instantiation: linkhash.c:lh_entry_set_val
432
433
/**
434
 * Return the next element, or NULL if there is no next element.
435
 * @see lh_table_head()
436
 * @see lh_entry_prev()
437
 */
438
static _LH_INLINE struct lh_entry *lh_entry_next(const struct lh_entry *e)
439
0
{
440
0
  return e->next;
441
0
}
Unexecuted instantiation: json_object.c:lh_entry_next
Unexecuted instantiation: linkhash.c:lh_entry_next
442
443
/**
444
 * Return the previous element, or NULL if there is no previous element.
445
 * @see lh_table_head()
446
 * @see lh_entry_next()
447
 */
448
static _LH_INLINE struct lh_entry *lh_entry_prev(const struct lh_entry *e)
449
0
{
450
0
  return e->prev;
451
0
}
Unexecuted instantiation: json_object.c:lh_entry_prev
Unexecuted instantiation: linkhash.c:lh_entry_prev
452
453
#undef _LH_INLINE
454
455
#ifdef __cplusplus
456
}
457
#endif
458
459
#endif