X-Git-Url: https://git.saurik.com/apple/icu.git/blobdiff_plain/b75a7d8f3b4adbae880cab104ce2c6a50eee4db2..2ca993e82fb37b597a3c73ecd1586a139a6579c5:/icuSources/common/uhash.h diff --git a/icuSources/common/uhash.h b/icuSources/common/uhash.h index 580ae957..0d96ea34 100644 --- a/icuSources/common/uhash.h +++ b/icuSources/common/uhash.h @@ -1,6 +1,6 @@ /* ****************************************************************************** -* Copyright (C) 1997-2001, International Business Machines +* Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. ****************************************************************************** * Date Name Description @@ -14,6 +14,9 @@ #define UHASH_H #include "unicode/utypes.h" +#include "cmemory.h" +#include "uelement.h" +#include "unicode/localpointer.h" /** * UHashtable stores key-value pairs and does moderately fast lookup @@ -55,10 +58,13 @@ * hashcode. During iteration an element may be deleted by calling * uhash_removeElement(); iteration may safely continue thereafter. * The uhash_remove() function may also be safely called in - * mid-iteration. However, if uhash_put() is called during iteration - * then the iteration will be out of sync. Under no circumstances - * should the UHashElement returned by uhash_nextElement be modified - * directly. + * mid-iteration. If uhash_put() is called during iteration, + * the iteration is still guaranteed to terminate reasonably, but + * there is no guarantee that every element will be returned or that + * some won't be returned more than once. + * + * Under no circumstances should the UHashElement returned by + * uhash_nextElement be modified directly. * * By default, the hashtable grows when necessary, but never shrinks, * even if all items are removed. For most applications this is @@ -76,20 +82,11 @@ U_CDECL_BEGIN /** - * A key or value within the hashtable. It may be either a 32-bit - * integral value or an opaque void* pointer. The void* pointer may - * be smaller than 32 bits (e.g. 24 bits) or may be larger (e.g. 64 - * bits). The hashing and comparison functions take a pointer to a + * A key or value within a UHashtable. + * The hashing and comparison functions take a pointer to a * UHashTok, but the deleter receives the void* pointer within it. - * - * Because a UHashTok is the size of a native pointer or a 32-bit - * integer, we pass it around by value. */ -union UHashTok { - void* pointer; - int32_t integer; -}; -typedef union UHashTok UHashTok; +typedef UElement UHashTok; /** * This is a single hash element. @@ -110,21 +107,16 @@ typedef struct UHashElement UHashElement; typedef int32_t U_CALLCONV UHashFunction(const UHashTok key); /** - * A key comparison function. - * @param key1 A key stored in a hashtable - * @param key2 A key stored in a hashtable - * @return TRUE if the two keys are equal. + * A key equality (boolean) comparison function. */ -typedef UBool U_CALLCONV UKeyComparator(const UHashTok key1, - const UHashTok key2); +typedef UElementsAreEqual UKeyComparator; /** - * A function called by uhash_remove, - * uhash_close, or uhash_put to delete - * an existing key or value. - * @param obj A key or value stored in a hashtable + * A value equality (boolean) comparison function. */ -typedef void U_CALLCONV UObjectDeleter(void* obj); +typedef UElementsAreEqual UValueComparator; + +/* see cmemory.h for UObjectDeleter and uprv_deleteUObject() */ /** * This specifies whether or not, and how, the hastable resizes itself. @@ -146,6 +138,19 @@ struct UHashtable { UHashElement *elements; + /* Function pointers */ + + UHashFunction *keyHasher; /* Computes hash from key. + * Never null. */ + UKeyComparator *keyComparator; /* Compares keys for equality. + * Never null. */ + UValueComparator *valueComparator; /* Compares the values for equality */ + + UObjectDeleter *keyDeleter; /* Deletes keys when required. + * If NULL won't do anything */ + UObjectDeleter *valueDeleter; /* Deletes values when required. + * If NULL won't do anything */ + /* Size parameters */ int32_t count; /* The number of key-value pairs in this table. @@ -153,8 +158,6 @@ struct UHashtable { * never let count == length (see code). */ int32_t length; /* The physical size of the arrays hashes, keys * and values. Must be prime. */ - int32_t primeIndex; /* Index into our prime table for length. - * length == PRIMES[primeIndex] */ /* Rehashing thresholds */ @@ -163,16 +166,9 @@ struct UHashtable { float highWaterRatio; /* 0..1; high water as a fraction of length */ float lowWaterRatio; /* 0..1; low water as a fraction of length */ - /* Function pointers */ - - UHashFunction *keyHasher; /* Computes hash from key. - * Never null. */ - UKeyComparator *keyComparator; /* Compares keys for equality. - * Never null. */ - UObjectDeleter *keyDeleter; /* Deletes keys when required. - * If NULL won't do anything */ - UObjectDeleter *valueDeleter; /* Deletes values when required. - * If NULL won't do anything */ + int8_t primeIndex; /* Index into our prime table for length. + * length == PRIMES[primeIndex] */ + UBool allocated; /* Was this UHashtable allocated? */ }; typedef struct UHashtable UHashtable; @@ -195,6 +191,7 @@ U_CDECL_END U_CAPI UHashtable* U_EXPORT2 uhash_open(UHashFunction *keyHash, UKeyComparator *keyComp, + UValueComparator *valueComp, UErrorCode *status); /** @@ -211,12 +208,49 @@ uhash_open(UHashFunction *keyHash, U_CAPI UHashtable* U_EXPORT2 uhash_openSize(UHashFunction *keyHash, UKeyComparator *keyComp, + UValueComparator *valueComp, + int32_t size, + UErrorCode *status); + +/** + * Initialize an existing UHashtable. + * @param keyHash A pointer to the key hashing function. Must not be + * NULL. + * @param keyComp A pointer to the function that compares keys. Must + * not be NULL. + * @param status A pointer to an UErrorCode to receive any errors. + * @return A pointer to a UHashtable, or 0 if an error occurred. + * @see uhash_openSize + */ +U_CAPI UHashtable* U_EXPORT2 +uhash_init(UHashtable *hash, + UHashFunction *keyHash, + UKeyComparator *keyComp, + UValueComparator *valueComp, + UErrorCode *status); + +/** + * Initialize an existing UHashtable. + * @param keyHash A pointer to the key hashing function. Must not be + * NULL. + * @param keyComp A pointer to the function that compares keys. Must + * not be NULL. + * @param size The initial capacity of this hash table. + * @param status A pointer to an UErrorCode to receive any errors. + * @return A pointer to a UHashtable, or 0 if an error occurred. + * @see uhash_openSize + */ +U_CAPI UHashtable* U_EXPORT2 +uhash_initSize(UHashtable *hash, + UHashFunction *keyHash, + UKeyComparator *keyComp, + UValueComparator *valueComp, int32_t size, UErrorCode *status); /** * Close a UHashtable, releasing the memory used. - * @param hash The UHashtable to close. + * @param hash The UHashtable to close. If hash is NULL no operation is performed. */ U_CAPI void U_EXPORT2 uhash_close(UHashtable *hash); @@ -242,6 +276,16 @@ uhash_setKeyHasher(UHashtable *hash, UHashFunction *fn); U_CAPI UKeyComparator *U_EXPORT2 uhash_setKeyComparator(UHashtable *hash, UKeyComparator *fn); +/** + * Set the function used to compare values. The default comparison is a + * void* pointer comparison. + * @param hash The UHashtable to set + * @param fn the function to be used compare keys; must not be NULL + * @return the previous key comparator; non-NULL + */ +U_CAPI UValueComparator *U_EXPORT2 +uhash_setValueComparator(UHashtable *hash, UValueComparator *fn); + /** * Set the function used to delete keys. If this function pointer is * NULL, this hashtable does not delete keys. If it is non-NULL, this @@ -341,6 +385,24 @@ uhash_puti(UHashtable *hash, int32_t value, UErrorCode *status); +/** + * Put a (key=integer, value=integer) item in a UHashtable. If the + * keyDeleter is non-NULL, then the hashtable owns 'key' after this + * call. valueDeleter must be NULL. Storing a 0 value is the same as + * calling uhash_remove(). + * @param hash The target UHashtable. + * @param key The key to store. + * @param value The integer value to store. + * @param status A pointer to an UErrorCode to receive any errors. + * @return The previous value, or 0 if none. + * @see uhash_get + */ +U_CAPI int32_t U_EXPORT2 +uhash_iputi(UHashtable *hash, + int32_t key, + int32_t value, + UErrorCode *status); + /** * Retrieve a pointer value from a UHashtable using a pointer key, * as previously stored by uhash_put(). @@ -373,6 +435,16 @@ uhash_iget(const UHashtable *hash, U_CAPI int32_t U_EXPORT2 uhash_geti(const UHashtable *hash, const void* key); +/** + * Retrieve an integer value from a UHashtable using an integer key, + * as previously stored by uhash_iputi(). + * @param hash The target UHashtable. + * @param key An integer key stored in a hashtable + * @return The requested item, or 0 if not found. + */ +U_CAPI int32_t U_EXPORT2 +uhash_igeti(const UHashtable *hash, + int32_t key); /** * Remove an item from a UHashtable stored by uhash_put(). @@ -404,6 +476,16 @@ U_CAPI int32_t U_EXPORT2 uhash_removei(UHashtable *hash, const void* key); +/** + * Remove an item from a UHashtable stored by uhash_iputi(). + * @param hash The target UHashtable. + * @param key An integer key stored in a hashtable + * @return The item removed, or 0 if not found. + */ +U_CAPI int32_t U_EXPORT2 +uhash_iremovei(UHashtable *hash, + int32_t key); + /** * Remove all items from a UHashtable. * @param hash The target UHashtable. @@ -425,6 +507,13 @@ uhash_removeAll(UHashtable *hash); U_CAPI const UHashElement* U_EXPORT2 uhash_find(const UHashtable *hash, const void* key); +/** + * \def UHASH_FIRST + * Constant for use with uhash_nextElement + * @see uhash_nextElement + */ +#define UHASH_FIRST (-1) + /** * Iterate through the elements of a UHashtable. The caller must not * modify the returned object. However, uhash_removeElement() may be @@ -433,7 +522,7 @@ uhash_find(const UHashtable *hash, const void* key); * called during iteration the iteration will then be out of sync and * should be restarted. * @param hash The target UHashtable. - * @param pos This should be set to -1 initially, and left untouched + * @param pos This should be set to UHASH_FIRST initially, and left untouched * thereafter. * @return a hash element, or NULL if no further key-value pairs * exist in the table. @@ -465,16 +554,16 @@ uhash_removeElement(UHashtable *hash, const UHashElement* e); * @param i The given integer * @return a UHashTok for an integer. */ -U_CAPI UHashTok U_EXPORT2 -uhash_toki(int32_t i); +/*U_CAPI UHashTok U_EXPORT2 +uhash_toki(int32_t i);*/ /** * Return a UHashTok for a pointer. * @param p The given pointer * @return a UHashTok for a pointer. */ -U_CAPI UHashTok U_EXPORT2 -uhash_tokp(void* p); +/*U_CAPI UHashTok U_EXPORT2 +uhash_tokp(void* p);*/ /******************************************************************** * UChar* and char* Support Functions @@ -500,10 +589,6 @@ uhash_hashUChars(const UHashTok key); U_CAPI int32_t U_EXPORT2 uhash_hashChars(const UHashTok key); -/* Used by UnicodeString to compute its hashcode - Not public API. */ -U_CAPI int32_t U_EXPORT2 -uhash_hashUCharsN(const UChar *key, int32_t length); - /** * Generate a case-insensitive hash code for a null-terminated char* * string. If the string is not null-terminated do not use this @@ -554,7 +639,7 @@ uhash_compareIChars(const UHashTok key1, const UHashTok key2); * @return A hash code for the key. */ U_CAPI int32_t U_EXPORT2 -uhash_hashUnicodeString(const UHashTok key); +uhash_hashUnicodeString(const UElement key); /** * Hash function for UnicodeString* keys (case insensitive). @@ -563,33 +648,7 @@ uhash_hashUnicodeString(const UHashTok key); * @return A hash code for the key. */ U_CAPI int32_t U_EXPORT2 -uhash_hashCaselessUnicodeString(const UHashTok key); - -/** - * Comparator function for UnicodeString* keys. - * @param key1 The string for comparison - * @param key2 The string for comparison - * @return true if key1 and key2 are equal, return false otherwise. - */ -U_CAPI UBool U_EXPORT2 -uhash_compareUnicodeString(const UHashTok key1, const UHashTok key2); - -/** - * Comparator function for UnicodeString* keys (case insensitive). - * Make sure to use together with uhash_hashCaselessUnicodeString. - * @param key1 The string for comparison - * @param key2 The string for comparison - * @return true if key1 and key2 are equal, return false otherwise. - */ -U_CAPI UBool U_EXPORT2 -uhash_compareCaselessUnicodeString(const UHashTok key1, const UHashTok key2); - -/** - * Deleter function for UnicodeString* keys or values. - * @param obj The object to be deleted - */ -U_CAPI void U_EXPORT2 -uhash_deleteUnicodeString(void *obj); +uhash_hashCaselessUnicodeString(const UElement key); /******************************************************************** * int32_t Support Functions @@ -623,19 +682,35 @@ uhash_compareLong(const UHashTok key1, const UHashTok key2); U_CAPI void U_EXPORT2 uhash_deleteHashtable(void *obj); +/* Use uprv_free() itself as a deleter for any key or value allocated using uprv_malloc. */ + /** - * Deleter for UVector objects. - * @param obj The object to be deleted + * Checks if the given hash tables are equal or not. + * @param hash1 + * @param hash2 + * @return true if the hashtables are equal and false if not. */ -U_CAPI void U_EXPORT2 -uhash_deleteUVector(void *obj); +U_CAPI UBool U_EXPORT2 +uhash_equals(const UHashtable* hash1, const UHashtable* hash2); + + +#if U_SHOW_CPLUSPLUS_API + +U_NAMESPACE_BEGIN /** - * Deleter for any key or value allocated using uprv_malloc. Calls - * uprv_free. - * @param obj The object to be deleted + * \class LocalUResourceBundlePointer + * "Smart pointer" class, closes a UResourceBundle via ures_close(). + * For most methods see the LocalPointerBase base class. + * + * @see LocalPointerBase + * @see LocalPointer + * @stable ICU 4.4 */ -U_CAPI void U_EXPORT2 -uhash_freeBlock(void *obj); +U_DEFINE_LOCAL_OPEN_POINTER(LocalUHashtablePointer, UHashtable, uhash_close); + +U_NAMESPACE_END + +#endif #endif