/*
******************************************************************************
-* Copyright (C) 1997-2008, International Business Machines
+* Copyright (C) 1997-2016, International Business Machines
* Corporation and others. All Rights Reserved.
******************************************************************************
* Date Name Description
#include "cstring.h"
#include "cmemory.h"
#include "uassert.h"
+#include "ustr_imp.h"
/* This hashtable is implemented as a double hash. All elements are
* stored in a single array with no secondary storage for collision
* prime number while being less than a power of two.
*/
static const int32_t PRIMES[] = {
- 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749,
+ 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749,
65521, 131071, 262139, 524287, 1048573, 2097143, 4194301, 8388593,
16777213, 33554393, 67108859, 134217689, 268435399, 536870909,
1073741789, 2147483647 /*, 4294967291 */
};
-#define PRIMES_LENGTH (sizeof(PRIMES) / sizeof(PRIMES[0]))
-#define DEFAULT_PRIME_INDEX 3
+#define PRIMES_LENGTH UPRV_LENGTHOF(PRIMES)
+#define DEFAULT_PRIME_INDEX 4
/* These ratios are tuned to the PRIMES array such that a resize
* places the table back into the zone of non-resizing. That is,
return _uhash_init(fillinResult, keyHash, keyComp, valueComp, DEFAULT_PRIME_INDEX, status);
}
+U_CAPI UHashtable* U_EXPORT2
+uhash_initSize(UHashtable *fillinResult,
+ UHashFunction *keyHash,
+ UKeyComparator *keyComp,
+ UValueComparator *valueComp,
+ int32_t size,
+ UErrorCode *status) {
+
+ /* Find the smallest index i for which PRIMES[i] >= size. */
+ int32_t i = 0;
+ while (i<(PRIMES_LENGTH-1) && PRIMES[i]<size) {
+ ++i;
+ }
+
+ return _uhash_init(fillinResult, keyHash, keyComp, valueComp, i, status);
+}
+
U_CAPI void U_EXPORT2
uhash_close(UHashtable *hash) {
- U_ASSERT(hash != NULL);
+ if (hash == NULL) {
+ return;
+ }
if (hash->elements != NULL) {
if (hash->keyDeleter != NULL || hash->valueDeleter != NULL) {
- int32_t pos=-1;
+ int32_t pos=UHASH_FIRST;
UHashElement *e;
while ((e = (UHashElement*) uhash_nextElement(hash, &pos)) != NULL) {
HASH_DELETE_KEY_VALUE(hash, e->key.pointer, e->value.pointer);
U_CAPI void U_EXPORT2
uhash_removeAll(UHashtable *hash) {
- int32_t pos = -1;
+ int32_t pos = UHASH_FIRST;
const UHashElement *e;
U_ASSERT(hash != NULL);
if (hash->count != 0) {
U_ASSERT(hash != NULL);
U_ASSERT(e != NULL);
if (!IS_EMPTY_OR_DELETED(e->hashcode)) {
- return _uhash_internalRemoveElement(hash, (UHashElement*) e).pointer;
+ UHashElement *nce = (UHashElement *)e;
+ return _uhash_internalRemoveElement(hash, nce).pointer;
}
return NULL;
}
* PUBLIC Key Hash Functions
********************************************************************/
-/*
- Compute the hash by iterating sparsely over about 32 (up to 63)
- characters spaced evenly through the string. For each character,
- multiply the previous hash value by a prime number and add the new
- character in, like a linear congruential random number generator,
- producing a pseudorandom deterministic value well distributed over
- the output range. [LIU]
-*/
-
-#define STRING_HASH(TYPE, STR, STRLEN, DEREF) \
- int32_t hash = 0; \
- const TYPE *p = (const TYPE*) STR; \
- if (p != NULL) { \
- int32_t len = (int32_t)(STRLEN); \
- int32_t inc = ((len - 32) / 32) + 1; \
- const TYPE *limit = p + len; \
- while (p<limit) { \
- hash = (hash * 37) + DEREF; \
- p += inc; \
- } \
- } \
- return hash
-
U_CAPI int32_t U_EXPORT2
uhash_hashUChars(const UHashTok key) {
- STRING_HASH(UChar, key.pointer, u_strlen(p), *p);
-}
-
-/* Used by UnicodeString to compute its hashcode - Not public API. */
-U_CAPI int32_t U_EXPORT2
-uhash_hashUCharsN(const UChar *str, int32_t length) {
- STRING_HASH(UChar, str, length, *p);
+ const UChar *s = (const UChar *)key.pointer;
+ return s == NULL ? 0 : ustr_hashUCharsN(s, u_strlen(s));
}
U_CAPI int32_t U_EXPORT2
uhash_hashChars(const UHashTok key) {
- STRING_HASH(uint8_t, key.pointer, uprv_strlen((char*)p), *p);
+ const char *s = (const char *)key.pointer;
+ return s == NULL ? 0 : ustr_hashCharsN(s, uprv_strlen(s));
}
U_CAPI int32_t U_EXPORT2
uhash_hashIChars(const UHashTok key) {
- STRING_HASH(uint8_t, key.pointer, uprv_strlen((char*)p), uprv_tolower(*p));
+ const char *s = (const char *)key.pointer;
+ return s == NULL ? 0 : ustr_hashICharsN(s, uprv_strlen(s));
}
U_CAPI UBool U_EXPORT2
uhash_equals(const UHashtable* hash1, const UHashtable* hash2){
-
int32_t count1, count2, pos, i;
if(hash1==hash2){
return FALSE;
}
- pos=-1;
+ pos=UHASH_FIRST;
for(i=0; i<count1; i++){
const UHashElement* elem1 = uhash_nextElement(hash1, &pos);
const UHashTok key1 = elem1->key;
uhash_compareLong(const UHashTok key1, const UHashTok key2) {
return (UBool)(key1.integer == key2.integer);
}
-
-/********************************************************************
- * PUBLIC Deleter Functions
- ********************************************************************/
-
-U_CAPI void U_EXPORT2
-uhash_freeBlock(void *obj) {
- uprv_free(obj);
-}
-