]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/common/uhash.h
ICU-57131.0.1.tar.gz
[apple/icu.git] / icuSources / common / uhash.h
index 580ae957f55ed7ef659fa24b1920533c54faafb0..0d96ea34cd1cc9586b44d0727dbd76751038eb62 100644 (file)
@@ -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
  * 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
 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 <TT>uhash_remove</TT>,
- * <TT>uhash_close</TT>, or <TT>uhash_put</TT> 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