--- embedaddon/strongswan/src/libstrongswan/collections/hashtable.h 2020/06/03 09:46:43 1.1 +++ embedaddon/strongswan/src/libstrongswan/collections/hashtable.h 2021/03/17 00:20:08 1.1.1.2 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Tobias Brunner + * Copyright (C) 2008-2020 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ #include typedef struct hashtable_t hashtable_t; +typedef struct hashlist_t hashlist_t; /** * Prototype for a function that computes the hash code from the given key. @@ -52,7 +53,7 @@ u_int hashtable_hash_str(const void *key); /** * Prototype for a function that compares the two keys for equality. * - * @param key first key (the one we are looking for) + * @param key first key (the one we are looking for/inserting) * @param other_key second key * @return TRUE if the keys are equal */ @@ -77,9 +78,21 @@ bool hashtable_equals_ptr(const void *key, const void bool hashtable_equals_str(const void *key, const void *other_key); /** + * Prototype for a function that compares the two keys in order to sort them. + * + * @param key first key (the one we are looking for/inserting) + * @param other_key second key + * @return less than, equal to, or greater than 0 if key is + * less than, equal to, or greater than other_key + */ +typedef int (*hashtable_cmp_t)(const void *key, const void *other_key); + +/** * Class implementing a hash table. * * General purpose hash table. This hash table is not synchronized. + * + * The insertion order is maintained when enumerating entries. */ struct hashtable_t { @@ -88,7 +101,7 @@ struct hashtable_t { * * @return enumerator over (void *key, void *value) */ - enumerator_t *(*create_enumerator) (hashtable_t *this); + enumerator_t *(*create_enumerator)(hashtable_t *this); /** * Adds the given value with the given key to the hash table, if there @@ -100,7 +113,7 @@ struct hashtable_t { * @param value the value to store * @return NULL if no item was replaced, the old value otherwise */ - void *(*put) (hashtable_t *this, const void *key, void *value); + void *(*put)(hashtable_t *this, const void *key, void *value); /** * Returns the value with the given key, if the hash table contains such an @@ -109,33 +122,16 @@ struct hashtable_t { * @param key the key of the requested value * @return the value, NULL if not found */ - void *(*get) (hashtable_t *this, const void *key); + void *(*get)(hashtable_t *this, const void *key); /** - * Returns the value with a matching key, if the hash table contains such an - * entry, otherwise NULL is returned. - * - * Compared to get() the given match function is used to compare the keys - * for equality. The hash function does have to be devised properly in - * order to make this work if the match function compares keys differently - * than the equals function provided to the constructor. This basically - * allows to enumerate all entries with the same hash value. - * - * @param key the key to match against - * @param match match function to be used when comparing keys - * @return the value, NULL if not found - */ - void *(*get_match) (hashtable_t *this, const void *key, - hashtable_equals_t match); - - /** * Removes the value with the given key from the hash table and returns the * removed value (or NULL if no such value existed). * * @param key the key of the value to remove * @return the removed value, NULL if not found */ - void *(*remove) (hashtable_t *this, const void *key); + void *(*remove)(hashtable_t *this, const void *key); /** * Removes the key and value pair from the hash table at which the given @@ -143,19 +139,19 @@ struct hashtable_t { * * @param enumerator enumerator, from create_enumerator */ - void (*remove_at) (hashtable_t *this, enumerator_t *enumerator); + void (*remove_at)(hashtable_t *this, enumerator_t *enumerator); /** * Gets the number of items in the hash table. * * @return number of items */ - u_int (*get_count) (hashtable_t *this); + u_int (*get_count)(hashtable_t *this); /** * Destroys a hash table object. */ - void (*destroy) (hashtable_t *this); + void (*destroy)(hashtable_t *this); /** * Destroys a hash table object and calls the given function for each @@ -168,14 +164,84 @@ struct hashtable_t { }; /** + * Class implementing a hash table with ordered keys/items and special query + * method. + * + * @note The ordering only pertains to keys/items in the same bucket (with or + * without the same hash value), not to the order when enumerating. So unlike + * hashtable_t this class does not guarantee any specific order when enumerating + * all entries. + * + * This is intended to be used with hash functions that intentionally return the + * same hash value for different keys so multiple items can be retrieved for a + * key. + * + * It's like storing sorted linked lists in a hash table but with less overhead. + */ +struct hashlist_t { + + /** + * Implements the hash table interface. + */ + hashtable_t ht; + + /** + * Returns the first value with a matching key if the hash table contains + * such an entry, otherwise NULL is returned. + * + * Compared to get() the given match function is used to compare the keys + * for equality. The hash function does have to be devised specially in + * order to make this work if the match function compares keys differently + * than the equals/comparison function provided to the constructor. + * + * This basically allows to enumerate all entries with the same hash value + * in their key's order (insertion order, i.e. without comparison function) + * is only guaranteed for items with the same hash value. + * + * @param key the key to match against + * @param match match function to be used when comparing keys + * @return the value, NULL if not found + */ + void *(*get_match)(hashlist_t *this, const void *key, + hashtable_equals_t match); + + /** + * Destroys a hash list object. + */ + void (*destroy)(hashlist_t *this); +}; + +/** * Creates an empty hash table object. * * @param hash hash function * @param equals equals function - * @param capacity initial capacity - * @return hashtable_t object. + * @param size initial size + * @return hashtable_t object */ hashtable_t *hashtable_create(hashtable_hash_t hash, hashtable_equals_t equals, - u_int capacity); + u_int size); + +/** + * Creates an empty hash list object with each bucket's keys in insertion order. + * + * @param hash hash function + * @param equals equals function + * @param size initial size + * @return hashtable_t object + */ +hashlist_t *hashlist_create(hashtable_hash_t hash, hashtable_equals_t equals, + u_int size); + +/** + * Creates an empty hash list object with sorted keys in each bucket. + * + * @param hash hash function + * @param cmp comparison function + * @param size initial size + * @return hashtable_t object. + */ +hashlist_t *hashlist_create_sorted(hashtable_hash_t hash, + hashtable_cmp_t cmp, u_int size); #endif /** HASHTABLE_H_ @}*/