Coverage Report

Created: 2024-05-21 06:33

/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
176k
#define LH_LOAD_FACTOR 0.66
39
40
/**
41
 * sentinel pointer value for empty slots
42
 */
43
2.45M
#define LH_EMPTY (void *)-1
44
45
/**
46
 * sentinel pointer value for freed slots
47
 */
48
1.03M
#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(AIX_CC) || (defined(_MSC_VER) && (_MSC_VER <= 1800)) )
338
/* VS2010 can't handle inline funcs, so skip it there */
339
#define _LH_INLINE
340
#else
341
#define _LH_INLINE inline
342
#endif
343
344
/**
345
 * Return the first entry in the lh_table.
346
 * @see lh_entry_next()
347
 */
348
static _LH_INLINE struct lh_entry *lh_table_head(const lh_table *t)
349
57.5k
{
350
57.5k
  return t->head;
351
57.5k
}
json_object.c:lh_table_head
Line
Count
Source
349
57.5k
{
350
57.5k
  return t->head;
351
57.5k
}
Unexecuted instantiation: linkhash.c:lh_table_head
352
353
/**
354
 * Calculate the hash of a key for a given table.
355
 *
356
 * This is an extension to support functions that need to calculate
357
 * the hash several times and allows them to do it just once and then pass
358
 * in the hash to all utility functions. Depending on use case, this can be a
359
 * considerable performance improvement.
360
 * @param t the table (used to obtain hash function)
361
 * @param k a pointer to the key to lookup
362
 * @return the key's hash
363
 */
364
static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void *k)
365
464k
{
366
464k
  return t->hash_fn(k);
367
464k
}
json_object.c:lh_get_hash
Line
Count
Source
365
165k
{
366
165k
  return t->hash_fn(k);
367
165k
}
linkhash.c:lh_get_hash
Line
Count
Source
365
299k
{
366
299k
  return t->hash_fn(k);
367
299k
}
368
369
370
/**
371
 * @deprecated Don't use this outside of linkhash.h:
372
 */
373
#ifdef __UNCONST
374
#define _LH_UNCONST(a) __UNCONST(a)
375
#else
376
784k
#define _LH_UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
377
#endif
378
379
/**
380
 * Return a non-const version of lh_entry.k.
381
 *
382
 * lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
383
 * it, but callers are allowed to do what they want with it.
384
 * @see lh_entry_k_is_constant()
385
 */
386
static _LH_INLINE void *lh_entry_k(const struct lh_entry *e)
387
268k
{
388
268k
  return _LH_UNCONST(e->k);
389
268k
}
json_object.c:lh_entry_k
Line
Count
Source
387
268k
{
388
268k
  return _LH_UNCONST(e->k);
389
268k
}
Unexecuted instantiation: linkhash.c:lh_entry_k
390
391
/**
392
 * Returns 1 if the key for the given entry is constant, and thus
393
 *  does not need to be freed when the lh_entry is freed.
394
 * @see lh_table_insert_w_hash()
395
 */
396
static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e)
397
157k
{
398
157k
  return e->k_is_constant;
399
157k
}
json_object.c:lh_entry_k_is_constant
Line
Count
Source
397
157k
{
398
157k
  return e->k_is_constant;
399
157k
}
Unexecuted instantiation: linkhash.c:lh_entry_k_is_constant
400
401
/**
402
 * Return a non-const version of lh_entry.v.
403
 *
404
 * v is const to indicate and help ensure that linkhash itself doesn't modify
405
 * it, but callers are allowed to do what they want with it.
406
 */
407
static _LH_INLINE void *lh_entry_v(const struct lh_entry *e)
408
515k
{
409
515k
  return _LH_UNCONST(e->v);
410
515k
}
json_object.c:lh_entry_v
Line
Count
Source
408
277k
{
409
277k
  return _LH_UNCONST(e->v);
410
277k
}
linkhash.c:lh_entry_v
Line
Count
Source
408
238k
{
409
238k
  return _LH_UNCONST(e->v);
410
238k
}
411
412
/**
413
 * Change the value for an entry.  The caller is responsible for freeing
414
 *  the previous value.
415
 */
416
static _LH_INLINE void lh_entry_set_val(struct lh_entry *e, void *newval)
417
8.25k
{
418
8.25k
  e->v = newval;
419
8.25k
}
json_object.c:lh_entry_set_val
Line
Count
Source
417
8.25k
{
418
8.25k
  e->v = newval;
419
8.25k
}
Unexecuted instantiation: linkhash.c:lh_entry_set_val
420
421
/**
422
 * Return the next element, or NULL if there is no next element.
423
 * @see lh_table_head()
424
 * @see lh_entry_prev()
425
 */
426
static _LH_INLINE struct lh_entry *lh_entry_next(const struct lh_entry *e)
427
111k
{
428
111k
  return e->next;
429
111k
}
json_object.c:lh_entry_next
Line
Count
Source
427
111k
{
428
111k
  return e->next;
429
111k
}
Unexecuted instantiation: linkhash.c:lh_entry_next
430
431
/**
432
 * Return the previous element, or NULL if there is no previous element.
433
 * @see lh_table_head()
434
 * @see lh_entry_next()
435
 */
436
static _LH_INLINE struct lh_entry *lh_entry_prev(const struct lh_entry *e)
437
0
{
438
0
  return e->prev;
439
0
}
Unexecuted instantiation: json_object.c:lh_entry_prev
Unexecuted instantiation: linkhash.c:lh_entry_prev
440
441
#undef _LH_INLINE
442
443
#ifdef __cplusplus
444
}
445
#endif
446
447
#endif