Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:19:16

0001 /*
0002  * $Id: linkhash.h,v 1.6 2006/01/30 23:07:57 mclark Exp $
0003  *
0004  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
0005  * Michael Clark <michael@metaparadigm.com>
0006  * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
0007  *
0008  * This library is free software; you can redistribute it and/or modify
0009  * it under the terms of the MIT license. See COPYING for details.
0010  *
0011  */
0012 
0013 /**
0014  * @file
0015  * @brief Internal methods for working with json_type_object objects.  Although
0016  *        this is exposed by the json_object_get_object() function and within the
0017  *        json_object_iter type, it is not recommended for direct use.
0018  */
0019 #ifndef _json_c_linkhash_h_
0020 #define _json_c_linkhash_h_
0021 
0022 #include "json_object.h"
0023 
0024 #ifdef __cplusplus
0025 extern "C" {
0026 #endif
0027 
0028 /**
0029  * golden prime used in hash functions
0030  */
0031 #define LH_PRIME 0x9e370001UL
0032 
0033 /**
0034  * The fraction of filled hash buckets until an insert will cause the table
0035  * to be resized.
0036  * This can range from just above 0 up to 1.0.
0037  */
0038 #define LH_LOAD_FACTOR 0.66
0039 
0040 /**
0041  * sentinel pointer value for empty slots
0042  */
0043 #define LH_EMPTY (void *)-1
0044 
0045 /**
0046  * sentinel pointer value for freed slots
0047  */
0048 #define LH_FREED (void *)-2
0049 
0050 /**
0051  * default string hash function
0052  */
0053 #define JSON_C_STR_HASH_DFLT 0
0054 
0055 /**
0056  * perl-like string hash function
0057  */
0058 #define JSON_C_STR_HASH_PERLLIKE 1
0059 
0060 /**
0061  * This function sets the hash function to be used for strings.
0062  * Must be one of the JSON_C_STR_HASH_* values.
0063  * @returns 0 - ok, -1 if parameter was invalid
0064  */
0065 int json_global_set_string_hash(const int h);
0066 
0067 struct lh_entry;
0068 
0069 /**
0070  * callback function prototypes
0071  */
0072 typedef void(lh_entry_free_fn)(struct lh_entry *e);
0073 /**
0074  * callback function prototypes
0075  */
0076 typedef unsigned long(lh_hash_fn)(const void *k);
0077 /**
0078  * callback function prototypes
0079  */
0080 typedef int(lh_equal_fn)(const void *k1, const void *k2);
0081 
0082 /**
0083  * An entry in the hash table.  Outside of linkhash.c, treat this as opaque.
0084  */
0085 struct lh_entry
0086 {
0087     /**
0088      * The key.
0089      * @deprecated Use lh_entry_k() instead of accessing this directly.
0090      */
0091     const void *k;
0092     /**
0093      * A flag for users of linkhash to know whether or not they
0094      * need to free k.
0095      * @deprecated use lh_entry_k_is_constant() instead.
0096      */
0097     int k_is_constant;
0098     /**
0099      * The value.
0100      * @deprecated Use lh_entry_v() instead of accessing this directly.
0101      */
0102     const void *v;
0103     /**
0104      * The next entry.
0105      * @deprecated Use lh_entry_next() instead of accessing this directly.
0106      */
0107     struct lh_entry *next;
0108     /**
0109      * The previous entry.
0110      * @deprecated Use lh_entry_prev() instead of accessing this directly.
0111      */
0112     struct lh_entry *prev;
0113 };
0114 
0115 /**
0116  * The hash table structure.  Outside of linkhash.c, treat this as opaque.
0117  */
0118 struct lh_table
0119 {
0120     /**
0121      * Size of our hash.
0122      * @deprecated do not use outside of linkhash.c
0123      */
0124     int size;
0125     /**
0126      * Numbers of entries.
0127      * @deprecated Use lh_table_length() instead.
0128      */
0129     int count;
0130 
0131     /**
0132      * The first entry.
0133      * @deprecated Use lh_table_head() instead.
0134      */
0135     struct lh_entry *head;
0136 
0137     /**
0138      * The last entry.
0139      * @deprecated Do not use, may be removed in a future release.
0140      */
0141     struct lh_entry *tail;
0142 
0143     /**
0144      * Internal storage of the actual table of entries.
0145      * @deprecated do not use outside of linkhash.c
0146      */
0147     struct lh_entry *table;
0148 
0149     /**
0150      * A pointer to the function responsible for freeing an entry.
0151      * @deprecated do not use outside of linkhash.c
0152      */
0153     lh_entry_free_fn *free_fn;
0154     /**
0155      * @deprecated do not use outside of linkhash.c
0156      */
0157     lh_hash_fn *hash_fn;
0158     /**
0159      * @deprecated do not use outside of linkhash.c
0160      */
0161     lh_equal_fn *equal_fn;
0162 };
0163 typedef struct lh_table lh_table;
0164 
0165 /**
0166  * Convenience list iterator.
0167  */
0168 #define lh_foreach(table, entry) for (entry = lh_table_head(table); entry; entry = lh_entry_next(entry))
0169 
0170 /**
0171  * lh_foreach_safe allows calling of deletion routine while iterating.
0172  *
0173  * @param table a struct lh_table * to iterate over
0174  * @param entry a struct lh_entry * variable to hold each element
0175  * @param tmp a struct lh_entry * variable to hold a temporary pointer to the next element
0176  */
0177 #define lh_foreach_safe(table, entry, tmp) \
0178     for (entry = lh_table_head(table); entry && ((tmp = lh_entry_next(entry)) || 1); entry = tmp)
0179 
0180 /**
0181  * Create a new linkhash table.
0182  *
0183  * @param size initial table size. The table is automatically resized
0184  * although this incurs a performance penalty.
0185  * @param free_fn callback function used to free memory for entries
0186  * when lh_table_free or lh_table_delete is called.
0187  * If NULL is provided, then memory for keys and values
0188  * must be freed by the caller.
0189  * @param hash_fn  function used to hash keys. 2 standard ones are defined:
0190  * lh_ptr_hash and lh_char_hash for hashing pointer values
0191  * and C strings respectively.
0192  * @param equal_fn comparison function to compare keys. 2 standard ones defined:
0193  * lh_ptr_hash and lh_char_hash for comparing pointer values
0194  * and C strings respectively.
0195  * @return On success, a pointer to the new linkhash table is returned.
0196  *  On error, a null pointer is returned.
0197  */
0198 extern struct lh_table *lh_table_new(int size, lh_entry_free_fn *free_fn, lh_hash_fn *hash_fn,
0199                                      lh_equal_fn *equal_fn);
0200 
0201 /**
0202  * Convenience function to create a new linkhash table with char keys.
0203  *
0204  * @param size initial table size.
0205  * @param free_fn callback function used to free memory for entries.
0206  * @return On success, a pointer to the new linkhash table is returned.
0207  *  On error, a null pointer is returned.
0208  */
0209 extern struct lh_table *lh_kchar_table_new(int size, lh_entry_free_fn *free_fn);
0210 
0211 /**
0212  * Convenience function to create a new linkhash table with ptr keys.
0213  *
0214  * @param size initial table size.
0215  * @param free_fn callback function used to free memory for entries.
0216  * @return On success, a pointer to the new linkhash table is returned.
0217  *  On error, a null pointer is returned.
0218  */
0219 extern struct lh_table *lh_kptr_table_new(int size, lh_entry_free_fn *free_fn);
0220 
0221 /**
0222  * Free a linkhash table.
0223  *
0224  * If a lh_entry_free_fn callback free function was provided then it is
0225  * called for all entries in the table.
0226  *
0227  * @param t table to free.
0228  */
0229 extern void lh_table_free(struct lh_table *t);
0230 
0231 /**
0232  * Insert a record into the table.
0233  *
0234  * @param t the table to insert into.
0235  * @param k a pointer to the key to insert.
0236  * @param v a pointer to the value to insert.
0237  *
0238  * @return On success, <code>0</code> is returned.
0239  *  On error, a negative value is returned.
0240  */
0241 extern int lh_table_insert(struct lh_table *t, const void *k, const void *v);
0242 
0243 /**
0244  * Insert a record into the table using a precalculated key hash.
0245  *
0246  * The hash h, which should be calculated with lh_get_hash() on k, is provided by
0247  *  the caller, to allow for optimization when multiple operations with the same
0248  *  key are known to be needed.
0249  *
0250  * @param t the table to insert into.
0251  * @param k a pointer to the key to insert.
0252  * @param v a pointer to the value to insert.
0253  * @param h hash value of the key to insert
0254  * @param opts if set to JSON_C_OBJECT_ADD_CONSTANT_KEY, sets lh_entry.k_is_constant
0255  *             so t's free function knows to avoid freeing the key.
0256  */
0257 extern int lh_table_insert_w_hash(struct lh_table *t, const void *k, const void *v,
0258                                   const unsigned long h, const unsigned opts);
0259 
0260 /**
0261  * Lookup a record in the table.
0262  *
0263  * @param t the table to lookup
0264  * @param k a pointer to the key to lookup
0265  * @return a pointer to the record structure of the value or NULL if it does not exist.
0266  */
0267 extern struct lh_entry *lh_table_lookup_entry(struct lh_table *t, const void *k);
0268 
0269 /**
0270  * Lookup a record in the table using a precalculated key hash.
0271  *
0272  * The hash h, which should be calculated with lh_get_hash() on k, is provided by
0273  *  the caller, to allow for optimization when multiple operations with the same
0274  *  key are known to be needed.
0275  *
0276  * @param t the table to lookup
0277  * @param k a pointer to the key to lookup
0278  * @param h hash value of the key to lookup
0279  * @return a pointer to the record structure of the value or NULL if it does not exist.
0280  */
0281 extern struct lh_entry *lh_table_lookup_entry_w_hash(struct lh_table *t, const void *k,
0282                                                      const unsigned long h);
0283 
0284 /**
0285  * Lookup a record in the table.
0286  *
0287  * @param t the table to lookup
0288  * @param k a pointer to the key to lookup
0289  * @param v a pointer to a where to store the found value (set to NULL if it doesn't exist).
0290  * @return whether or not the key was found
0291  */
0292 extern json_bool lh_table_lookup_ex(struct lh_table *t, const void *k, void **v);
0293 
0294 /**
0295  * Delete a record from the table.
0296  *
0297  * If a callback free function is provided then it is called for the
0298  * for the item being deleted.
0299  * @param t the table to delete from.
0300  * @param e a pointer to the entry to delete.
0301  * @return 0 if the item was deleted.
0302  * @return -1 if it was not found.
0303  */
0304 extern int lh_table_delete_entry(struct lh_table *t, struct lh_entry *e);
0305 
0306 /**
0307  * Delete a record from the table.
0308  *
0309  * If a callback free function is provided then it is called for the
0310  * for the item being deleted.
0311  * @param t the table to delete from.
0312  * @param k a pointer to the key to delete.
0313  * @return 0 if the item was deleted.
0314  * @return -1 if it was not found.
0315  */
0316 extern int lh_table_delete(struct lh_table *t, const void *k);
0317 
0318 /**
0319  * Return the number of entries in the table.
0320  */
0321 extern int lh_table_length(struct lh_table *t);
0322 
0323 /**
0324  * Resizes the specified table.
0325  *
0326  * @param t Pointer to table to resize.
0327  * @param new_size New table size. Must be positive.
0328  *
0329  * @return On success, <code>0</code> is returned.
0330  *  On error, a negative value is returned.
0331  */
0332 int lh_table_resize(struct lh_table *t, int new_size);
0333 
0334 /**
0335  * @deprecated Don't use this outside of linkhash.h:
0336  */
0337 #if (defined(AIX_CC) || (defined(_MSC_VER) && (_MSC_VER <= 1800)) )
0338 /* VS2010 can't handle inline funcs, so skip it there */
0339 #define _LH_INLINE
0340 #else
0341 #define _LH_INLINE inline
0342 #endif
0343 
0344 /**
0345  * Return the first entry in the lh_table.
0346  * @see lh_entry_next()
0347  */
0348 static _LH_INLINE struct lh_entry *lh_table_head(const lh_table *t)
0349 {
0350     return t->head;
0351 }
0352 
0353 /**
0354  * Calculate the hash of a key for a given table.
0355  *
0356  * This is an extension to support functions that need to calculate
0357  * the hash several times and allows them to do it just once and then pass
0358  * in the hash to all utility functions. Depending on use case, this can be a
0359  * considerable performance improvement.
0360  * @param t the table (used to obtain hash function)
0361  * @param k a pointer to the key to lookup
0362  * @return the key's hash
0363  */
0364 static _LH_INLINE unsigned long lh_get_hash(const struct lh_table *t, const void *k)
0365 {
0366     return t->hash_fn(k);
0367 }
0368 
0369 
0370 /**
0371  * @deprecated Don't use this outside of linkhash.h:
0372  */
0373 #ifdef __UNCONST
0374 #define _LH_UNCONST(a) __UNCONST(a)
0375 #else
0376 #define _LH_UNCONST(a) ((void *)(uintptr_t)(const void *)(a))
0377 #endif
0378 
0379 /**
0380  * Return a non-const version of lh_entry.k.
0381  *
0382  * lh_entry.k is const to indicate and help ensure that linkhash itself doesn't modify
0383  * it, but callers are allowed to do what they want with it.
0384  * @see lh_entry_k_is_constant()
0385  */
0386 static _LH_INLINE void *lh_entry_k(const struct lh_entry *e)
0387 {
0388     return _LH_UNCONST(e->k);
0389 }
0390 
0391 /**
0392  * Returns 1 if the key for the given entry is constant, and thus
0393  *  does not need to be freed when the lh_entry is freed.
0394  * @see lh_table_insert_w_hash()
0395  */
0396 static _LH_INLINE int lh_entry_k_is_constant(const struct lh_entry *e)
0397 {
0398     return e->k_is_constant;
0399 }
0400 
0401 /**
0402  * Return a non-const version of lh_entry.v.
0403  *
0404  * v is const to indicate and help ensure that linkhash itself doesn't modify
0405  * it, but callers are allowed to do what they want with it.
0406  */
0407 static _LH_INLINE void *lh_entry_v(const struct lh_entry *e)
0408 {
0409     return _LH_UNCONST(e->v);
0410 }
0411 
0412 /**
0413  * Change the value for an entry.  The caller is responsible for freeing
0414  *  the previous value.
0415  */
0416 static _LH_INLINE void lh_entry_set_val(struct lh_entry *e, void *newval)
0417 {
0418     e->v = newval;
0419 }
0420 
0421 /**
0422  * Return the next element, or NULL if there is no next element.
0423  * @see lh_table_head()
0424  * @see lh_entry_prev()
0425  */
0426 static _LH_INLINE struct lh_entry *lh_entry_next(const struct lh_entry *e)
0427 {
0428     return e->next;
0429 }
0430 
0431 /**
0432  * Return the previous element, or NULL if there is no previous element.
0433  * @see lh_table_head()
0434  * @see lh_entry_next()
0435  */
0436 static _LH_INLINE struct lh_entry *lh_entry_prev(const struct lh_entry *e)
0437 {
0438     return e->prev;
0439 }
0440 
0441 #undef _LH_INLINE
0442 
0443 #ifdef __cplusplus
0444 }
0445 #endif
0446 
0447 #endif