ICU-149 rewrite UHashtable

X-SVN-Rev: 1001
This commit is contained in:
Alan Liu 2000-03-28 22:04:39 +00:00
parent d4146dab5f
commit 2ddc4768a3
14 changed files with 1233 additions and 717 deletions

View File

@ -256,6 +256,10 @@ SOURCE=.\uhash.c
# End Source File
# Begin Source File
SOURCE=.\uhash_us.cpp
# End Source File
# Begin Source File
SOURCE=.\uloc.c
# End Source File
# Begin Source File

View File

@ -0,0 +1,83 @@
/*
*******************************************************************************
* Copyright (C) 1997-2000, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
* Date Name Description
* 03/28/00 aliu Creation.
*******************************************************************************
*/
#ifndef HASH_H
#define HASH_H
#include "uhash.h"
#include "unicode/unistr.h"
/**
* Hashtable is a thin C++ wrapper around UHashtable, a general-purpose void*
* hashtable implemented in C. Hashtable is designed to be idiomatic and
* easy-to-use in C++.
*
* Hashtable is an INTERNAL CLASS.
*/
class Hashtable {
UHashtable* hash;
public:
Hashtable(UErrorCode& status);
/**
* Non-virtual destructor; make this virtual if Hashtable is subclassed
* in the future.
*/
~Hashtable();
UObjectDeleter setValueDeleter(UObjectDeleter fn);
void* put(const UnicodeString& key, void* value, UErrorCode& status);
void* get(const UnicodeString& key) const;
void* remove(const UnicodeString& key);
};
/*********************************************************************
* Implementation
********************************************************************/
inline Hashtable::Hashtable(UErrorCode& status) : hash(0) {
if (U_FAILURE(status)) {
return;
}
hash = uhash_open(uhash_hashUnicodeString,
uhash_compareUnicodeString, &status);
if (U_SUCCESS(status)) {
uhash_setKeyDeleter(hash, uhash_deleteUnicodeString);
}
}
inline Hashtable::~Hashtable() {
if (hash != 0) {
uhash_close(hash);
hash = 0;
}
}
inline UObjectDeleter Hashtable::setValueDeleter(UObjectDeleter fn) {
return uhash_setValueDeleter(hash, fn);
}
inline void* Hashtable::put(const UnicodeString& key, void* value, UErrorCode& status) {
return uhash_put(hash, new UnicodeString(key), value, &status);
}
inline void* Hashtable::get(const UnicodeString& key) const {
return uhash_get(hash, &key);
}
inline void* Hashtable::remove(const UnicodeString& key) {
return uhash_remove(hash, &key);
}
#endif

View File

@ -753,7 +753,7 @@ Locale::getLanguagesForCountry(const UnicodeString& country, int32_t& count)
// lookups.
if(ctry2LangMapping == 0) {
UErrorCode err = U_ZERO_ERROR;
UHashtable *temp = uhash_open((UHashFunction)uhash_hashUString, &err);
UHashtable *temp = uhash_open(uhash_hashUChars, uhash_compareUChars, &err);
if (U_FAILURE(err))
{
count = 0;
@ -776,7 +776,7 @@ Locale::getLanguagesForCountry(const UnicodeString& country, int32_t& count)
int32_t valLen = sizeof(values) / sizeof(values[0]);
for (int32_t k = 0; k < valLen; ++k)
compressedValues.extractBetween(k * 2, (k * 2) + 2, values[k]);
uhash_putKey(temp, uhash_hashUString((void*)key.getUChars()),values,&err);
uhash_put(temp, (void*)key.getUChars(), values, &err);
i = j;
}
@ -787,7 +787,8 @@ Locale::getLanguagesForCountry(const UnicodeString& country, int32_t& count)
ctry2LangMapping = temp;
}
const UnicodeString *result = (const UnicodeString*)uhash_get(ctry2LangMapping,uhash_hashUString(country.getUChars()));
const UnicodeString *result = (const UnicodeString*)
uhash_get(ctry2LangMapping, country.getUChars());
if(result == 0)
count = 0;
else

View File

@ -20,7 +20,8 @@
ResourceBundleCache::ResourceBundleCache()
{
UErrorCode err = U_ZERO_ERROR;
hashTable = uhash_open((UHashFunction)uhash_hashUString, &err);
hashTable = uhash_open((UHashFunction)uhash_OLD_hashUString,
uhash_OLD_pointerComparator, &err);
uhash_setValueDeleter(hashTable, deleteValue);
}
@ -34,7 +35,8 @@ void ResourceBundleCache::deleteValue(void* value)
VisitedFileCache::VisitedFileCache()
{
UErrorCode err = U_ZERO_ERROR;
hashTable = uhash_open((UHashFunction)uhash_hashUString, &err);
hashTable = uhash_open((UHashFunction)uhash_OLD_hashUString,
uhash_OLD_pointerComparator, &err);
}
VisitedFileCache::~VisitedFileCache()

View File

@ -55,13 +55,13 @@ class U_COMMON_API VisitedFileCache // Not really external; just making the comp
inline bool_t VisitedFileCache::wasVisited(const UnicodeString& filename) const
{
return (uhash_get(hashTable, uhash_hashUString(filename.getUChars())) != 0);
return (uhash_OLD_get(hashTable, uhash_OLD_hashUString(filename.getUChars())) != 0);
}
inline void VisitedFileCache::markAsVisited(const UnicodeString& filename)
{
UErrorCode err = U_ZERO_ERROR;
uhash_putKey(hashTable, uhash_hashUString(filename.getUChars()), (void*)TRUE, &err);
uhash_OLD_putKey(hashTable, uhash_OLD_hashUString(filename.getUChars()), (void*)TRUE, &err);
}

View File

@ -82,10 +82,12 @@ String2dList::getStaticClassID()
TaggedList::TaggedList()
{
UErrorCode err = U_ZERO_ERROR;
fHashtableValues = uhash_open((UHashFunction)uhash_hashUString, &err);
fHashtableValues = uhash_open((UHashFunction)uhash_OLD_hashUString,
uhash_OLD_pointerComparator, &err);
uhash_setValueDeleter(fHashtableValues, deleteValue);
fHashtableKeys = uhash_open((UHashFunction)uhash_hashUString, &err);
fHashtableKeys = uhash_open((UHashFunction)uhash_OLD_hashUString,
uhash_OLD_pointerComparator, &err);
}
TaggedList::~TaggedList()
@ -100,13 +102,13 @@ TaggedList::put(const UnicodeString& tag,
{
UErrorCode err = U_ZERO_ERROR;
uhash_putKey(fHashtableValues,
uhash_OLD_putKey(fHashtableValues,
tag.hashCode() & 0x7FFFFFFF,
(new UnicodeString(data)),
&err);
uhash_putKey(fHashtableKeys,
uhash_size(fHashtableValues),
uhash_OLD_putKey(fHashtableKeys,
uhash_count(fHashtableValues),
(new UnicodeString(tag)),
&err);
}
@ -115,7 +117,7 @@ const UnicodeString*
TaggedList::get(const UnicodeString& tag) const
{
return (const UnicodeString*)
uhash_get(fHashtableValues, tag.hashCode() & 0x7FFFFFFF);
uhash_OLD_get(fHashtableValues, tag.hashCode() & 0x7FFFFFFF);
}
void

View File

@ -262,7 +262,8 @@ rb_parse(FileStream *f,
if(U_FAILURE(status)) return 0;
/* Open the hashtable for saving data */
retval = uhash_open((UHashFunction)uhash_hashUString, &status);
retval = uhash_open((UHashFunction)uhash_OLD_hashUString,
uhash_OLD_pointerComparator, &status);
if(retval == 0 || U_FAILURE(status)) {
status = U_MEMORY_ALLOCATION_ERROR;
return 0;
@ -306,7 +307,7 @@ rb_parse(FileStream *f,
uhash_close(retval);
return 0;
}
uhash_putKey(retval, listname.hashCode() & 0x7FFFFFFF,
uhash_OLD_putKey(retval, listname.hashCode() & 0x7FFFFFFF,
strlist, &status);
if(U_FAILURE(status)) {
uhash_close(retval);
@ -316,7 +317,7 @@ rb_parse(FileStream *f,
case sSTRINGLIST2D:
strlist2d = read_strlist2d(f, listname, status);
uhash_putKey(retval, listname.hashCode() & 0x7FFFFFFF,
uhash_OLD_putKey(retval, listname.hashCode() & 0x7FFFFFFF,
strlist2d, &status);
if(U_FAILURE(status)) {
uhash_close(retval);
@ -326,7 +327,7 @@ rb_parse(FileStream *f,
case sTAGGEDLIST:
taglist = read_taglist(f, listname, status);
uhash_putKey(retval, listname.hashCode() & 0x7FFFFFFF,
uhash_OLD_putKey(retval, listname.hashCode() & 0x7FFFFFFF,
taglist, &status);
if(U_FAILURE(status)) {
uhash_close(retval);

View File

@ -599,7 +599,7 @@ ResourceBundle::getDataForTag(const char *tag,
if(fData[i] != 0) {
const ResourceBundleData* s =
(const ResourceBundleData*)uhash_get(fData[i],
(const ResourceBundleData*)uhash_OLD_get(fData[i],
UnicodeString(tag, "").hashCode() & 0x7FFFFFFF);
if(s != 0) {
err = fDataStatus[i]; /* restore the error from the original lookup. */
@ -849,10 +849,10 @@ getTaggedArrayUCharsImplementation( const ResourceBundle* bundle,
numItems = 0;
int32_t pos = -1;
while(value = uhash_nextElement(forEnumerationValues, &pos)) {
while(value = uhash_OLD_nextElement(forEnumerationValues, &pos)) {
if(numItems < maxItems) {
itemTags[numItems] =
((const UnicodeString*)uhash_get(((TaggedList*)data)->fHashtableKeys,
((const UnicodeString*)uhash_OLD_get(((TaggedList*)data)->fHashtableKeys,
numItems+1))->getUChars();
items[numItems] = ((const UnicodeString*)value)->getUChars();
}
@ -879,7 +879,7 @@ ResourceBundle::getTaggedArray( const char *resourceTag,
// go through the resource once and count how many items there are
numItems = uhash_size(((TaggedList*)data)->fHashtableValues);
numItems = uhash_count(((TaggedList*)data)->fHashtableValues);
// now create the string arrays and go through the hash table again, this
// time copying the keys and values into the string arrays
@ -891,9 +891,9 @@ ResourceBundle::getTaggedArray( const char *resourceTag,
numItems = 0;
int32_t pos = -1;
while(value = uhash_nextElement(forEnumerationValues, &pos)) {
while(value = uhash_OLD_nextElement(forEnumerationValues, &pos)) {
itemTags[numItems] =
*((const UnicodeString*)uhash_get(((TaggedList*)data)->fHashtableKeys,
*((const UnicodeString*)uhash_OLD_get(((TaggedList*)data)->fHashtableKeys,
numItems+1));
items[numItems] = *((const UnicodeString*)value);
numItems++;
@ -961,7 +961,7 @@ ResourceBundle::listInstalledLocales(const UnicodeString& path,
if(h != 0) {
UnicodeString ukIndexTag = UnicodeString(kIndexTag,"");
ResourceBundleData *data =
(ResourceBundleData*) uhash_get(h, ukIndexTag.hashCode() & 0x7FFFFFFF);
(ResourceBundleData*) uhash_OLD_get(h, ukIndexTag.hashCode() & 0x7FFFFFFF);
if(data != 0
&& data->getDynamicClassID() == StringList::getStaticClassID()) {
numInstalledLocales = ((StringList*)data)->fCount;
@ -1025,7 +1025,7 @@ T_ResourceBundle_countArrayItemsImplementation(const ResourceBundle* resourceBun
numItems = ((StringList*)data)->fCount;
}
else if(rbkeyClassID == TaggedList::getStaticClassID()) {
numItems = uhash_size(((TaggedList*)data)->fHashtableValues);
numItems = uhash_count(((TaggedList*)data)->fHashtableValues);
}
else if(rbkeyClassID == String2dList::getStaticClassID()) {
numItems = ((String2dList*)data)->fRowCount;
@ -1061,7 +1061,7 @@ ResourceBundle::getFromCache(const PathInfo& path,
Mutex lock;
return (const UHashtable*)
uhash_get(fgCache->hashTable, keyname.hashCode() & 0x7FFFFFFF);
uhash_OLD_get(fgCache->hashTable, keyname.hashCode() & 0x7FFFFFFF);
}
/**
@ -1127,8 +1127,8 @@ ResourceBundle::addToCache(const UnicodeString& localeName,
UnicodeString keyName(c->makeHashkey(localeName));
UErrorCode err = U_ZERO_ERROR;
Mutex lock;
if(uhash_get(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF) == 0) {
uhash_putKey(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF,
if(uhash_OLD_get(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF) == 0) {
uhash_OLD_putKey(fgCache->hashTable, keyName.hashCode() & 0x7FFFFFFF,
hashtable, &err);
}
}

View File

@ -137,6 +137,7 @@ int32_t ucnv_flushCache ()
UConverterSharedData *mySharedData = NULL;
int32_t pos = -1;
int32_t tableDeletedNum = 0;
UHashElement *e;
/*if shared data hasn't even been lazy evaluated yet
* return 0
@ -148,18 +149,18 @@ int32_t ucnv_flushCache ()
*table
*/
umtx_lock (NULL);
while (mySharedData = (UConverterSharedData *) uhash_nextElement (SHARED_DATA_HASHTABLE, &pos))
while ((e = uhash_nextElement (SHARED_DATA_HASHTABLE, &pos)) != NULL)
{
mySharedData = (UConverterSharedData *) e->value;
/*deletes only if reference counter == 0 */
if (mySharedData->referenceCounter == 0)
{
UErrorCode err = U_ZERO_ERROR;
tableDeletedNum++;
{
UErrorCode err = U_ZERO_ERROR;
tableDeletedNum++;
uhash_remove (SHARED_DATA_HASHTABLE, uhash_hashIString (mySharedData->name), &err);
deleteSharedConverterData (mySharedData);
}
uhash_removeElement(SHARED_DATA_HASHTABLE, e);
deleteSharedConverterData (mySharedData);
}
}
umtx_unlock (NULL);

View File

@ -64,11 +64,6 @@ static UConverterSharedData *createConverterFromFile (const char *converterName,
static const UConverterSharedData *getAlgorithmicTypeFromName (const char *realName);
/**
*hash function for UConverterSharedData
*/
static int32_t uhash_hashSharedData (void *sharedData);
/*Defines the struct of a UConverterSharedData the immutable, shared part of
*UConverter -
* This is the definition from ICU 1.4, necessary to read converter data
@ -182,11 +177,6 @@ const UConverterSharedData *
return NULL;
}
int32_t uhash_hashSharedData (void *sharedData)
{
return uhash_hashIString(((UConverterSharedData *) sharedData)->name);
}
/*Puts the shared data in the static hashtable SHARED_DATA_HASHTABLE */
void shareConverterData (UConverterSharedData * data)
{
@ -195,7 +185,7 @@ void shareConverterData (UConverterSharedData * data)
if (SHARED_DATA_HASHTABLE == NULL)
{
UHashtable* myHT = uhash_openSize ((UHashFunction) uhash_hashSharedData,
UHashtable* myHT = uhash_openSize (uhash_hashIChars, uhash_compareIChars,
ucnv_io_countAvailableAliases(&err),
&err);
if (U_FAILURE (err)) return;
@ -208,6 +198,8 @@ void shareConverterData (UConverterSharedData * data)
umtx_lock (NULL);
/* ### check to see if the element is not already there! */
uhash_put(SHARED_DATA_HASHTABLE,
(void*) data->name, /* Okay to cast away const as long as
keyDeleter == NULL */
data,
&err);
umtx_unlock (NULL);
@ -221,7 +213,7 @@ UConverterSharedData *getSharedConverterData (const char *name)
if (SHARED_DATA_HASHTABLE == NULL) return NULL;
else
{
return (UConverterSharedData*)uhash_get (SHARED_DATA_HASHTABLE, uhash_hashIString (name));
return (UConverterSharedData*)uhash_get (SHARED_DATA_HASHTABLE, name);
}
}

View File

@ -11,7 +11,6 @@
*
*/
#include "uhash.h"
#include "ucmp8.h"
#include "ucmp16.h"
#include "unicode/ucnv_bld.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,10 @@
/*
*******************************************************************************
*
* Copyright (C) 1997-1999, International Business Machines
* Copyright (C) 1997-2000, International Business Machines
* Corporation and others. All Rights Reserved.
*
*******************************************************************************
*
* File uhash.h
*
* Modification History:
*
* Date Name Description
* 03/12/99 stephen Creation.
* 03/22/00 aliu Adapted from original C++ ICU Hashtable.
*******************************************************************************
*/
@ -20,77 +13,153 @@
#include "unicode/utypes.h"
/*
* Hashtable stores key-value pairs and does efficient lookup based on keys.
* It also provides a protocol for enumerating through the key-value pairs
* (although it does so in no particular order).
* Values are stored as void* pointers.
/**
* UHashtable stores key-value pairs and does efficient lookup based
* on keys. It also provides a protocol for enumerating through the
* key-value pairs (in no particular order). Both keys and values are
* stored as void* pointers. Hashing of keys and comparison of keys
* are accomplished by user-supplied functions. Several prebuilt
* functions exist for common key types.
*
* UHashtable may optionally own either its keys or its values. To
* accomplish this the key and/or value deleter function pointers must
* be set to non-NULL values. If keys and/or values are owned, then
* keys and/or values passed to uhash_put() are owned by the hashtable
* and will be deleted by it at some point, either as keys and/or
* values are replaced, or when uhash_close() is finally called. Keys
* passed to methods other than uhash_put() are never owned by the
* hashtable.
*
* To see what's in a hashtable, use uhash_nextElement() to iterate
* through its contents. Each call to this function returns a
* UHashElement pointer. A hash element contains a key, value, and
* hashcode. During iteration an element may be deleted by calling
* uhash_removeElement(); iteration may safely continue thereafter.
* However, if uhash_put() is called during iteration then the
* iteration will be out of sync. Under no circumstances should the
* hash element be modified directly.
*/
/********************************************************************
* Data Structures
********************************************************************/
U_CDECL_BEGIN
/**
* A hashing function.
* @param parm A pointer to the data to be hashed.
* @param key A key stored in a hashtable
* @return A NON-NEGATIVE hash code for parm.
*/
typedef int32_t (*UHashFunction)(const void*);
typedef int32_t (* U_CALLCONV UHashFunction)(const void* key);
/**
* A function called when performing a <TT>uhash_remove</TT> or a <TT>uhash_close</TT>
* and <TT>uhash_put</TT>
* @param parm A pointer to the data to be hashed.
* 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.
*/
typedef bool_t (* U_CALLCONV UKeyComparator)(const void* key1,
const void* key2);
/**
* 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
*/
typedef void (* U_CALLCONV UObjectDeleter)(void* obj);
/**
* This is a single hash element. These should pack nicely
* into exactly 24 bytes. If this is not true, then split
* the elements array into 3 separate arrays for the hash,
* key, and value.
*/
struct UHashElement {
int32_t hashcode;
void* key;
void* value;
};
typedef struct UHashElement UHashElement;
/**
* The UHashtable struct. Clients should treat this as an opaque data type
* and manipulate it only through the uhash_... API.
*/
typedef void (* U_CALLCONV ValueDeleter)(void* valuePtr);
/** The UHashtable struct */
struct UHashtable {
/* Internals - DO NOT TOUCH! */
/* Main key-value pair storage array */
UHashElement *elements;
/* Size parameters */
int32_t primeIndex; /* Index into our prime table for length */
int32_t highWaterMark; /* Used for determiningg rehashing time */
int32_t lowWaterMark;
float highWaterFactor;
float lowWaterFactor;
int32_t count; /* The number of key-value pairs in this table.
* 0 <= count <= length. In practice we
* 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] */
int32_t count; /* The number of items in this table */
int32_t *hashes; /* Hash codes associated with values */
void **values; /* The stored values */
int32_t length; /* The physical size of hashes and values */
/* Rehashing thresholds */
int32_t highWaterMark; /* If count > highWaterMark, rehash */
int32_t lowWaterMark; /* If count < lowWaterMark, rehash */
float highWaterRatio; /* 0..1; high water as a fraction of length */
float lowWaterRatio; /* 0..1; low water as a fraction of length */
/* Function pointers */
ValueDeleter valueDelete; /*Function deletes values when required, if NULL won't do anything*/
UHashFunction hashFunction; /* Hashing function */
int32_t toBeDeletedCount;
void** toBeDeleted;
bool_t isGrowable;
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 */
};
typedef struct UHashtable UHashtable;
U_CDECL_END
/********************************************************************
* API
********************************************************************/
/**
* Initialize a new UHashtable.
* @param func A pointer to the hashing function to be used by this hash table.
* @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*
uhash_open(UHashFunction func,
UErrorCode *status);
uhash_open(UHashFunction keyHash,
UKeyComparator keyComp,
UErrorCode *status);
/**
* Initialize a new UHashtable with a given size. If after a sequence of uhash_put the table runs out of space
* An error will be signalled by uhash_put.
* @param hash A pointer to the UHashtable to be initialized.
* @param func A pointer to the hashing function to be used by this hash table.
* @param size The maximal capacity of this hash table.
* Initialize a new UHashtable with a given initial size.
* @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_open
*/
U_CAPI UHashtable*
uhash_openSize(UHashFunction func,
int32_t size,
UErrorCode *status);
uhash_openSize(UHashFunction keyHash,
UKeyComparator keyComp,
int32_t size,
UErrorCode *status);
/**
* Close a UHashtable, releasing the memory used.
@ -99,44 +168,71 @@ uhash_openSize(UHashFunction func,
U_CAPI void
uhash_close(UHashtable *hash);
U_CAPI void
uhash_setValueDeleter(UHashtable *hash, ValueDeleter del);
/**
* Set the function used to hash keys.
* @param fn the function to be used hash keys; must not be NULL
* @return the previous key hasher; non-NULL
*/
U_CAPI UHashFunction
uhash_setKeyHasher(UHashtable *hash, UHashFunction fn);
/**
* Get the number of items stored in a UHashtable.
* Set the function used to compare keys. The default comparison is a
* void* pointer comparison.
* @param fn the function to be used compare keys; must not be NULL
* @return the previous key comparator; non-NULL
*/
U_CAPI UKeyComparator
uhash_setKeyComparator(UHashtable *hash, UKeyComparator 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
* hashtable does delete keys. This function should be set once
* before any elements are added to the hashtable and should not be
* changed thereafter.
* @param fn the function to be used delete keys, or NULL
* @return the previous key deleter; may be NULL
*/
U_CAPI UObjectDeleter
uhash_setKeyDeleter(UHashtable *hash, UObjectDeleter fn);
/**
* Set the function used to delete values. If this function pointer
* is NULL, this hashtable does not delete values. If it is non-NULL,
* this hashtable does delete values. This function should be set
* once before any elements are added to the hashtable and should not
* be changed thereafter.
* @param fn the function to be used delete values, or NULL
* @return the previous value deleter; may be NULL
*/
U_CAPI UObjectDeleter
uhash_setValueDeleter(UHashtable *hash, UObjectDeleter fn);
/**
* Get the number of key-value pairs stored in a UHashtable.
* @param hash The UHashtable to query.
* @return The number of items stored in hash.
* @return The number of key-value pairs stored in hash.
*/
U_CAPI int32_t
uhash_size(const UHashtable *hash);
uhash_count(const UHashtable *hash);
/**
* Put an item in a UHashtable.
* Put an item in a UHashtable. If the keyDeleter is non-NULL, then
* the hashtable owns 'key' after this call. If the valueDeleter is
* non-NULL, then the hashtable owns 'value' after this call.
* @param hash The target UHashtable.
* @param key The key to store.
* @param value The value to store.
* @param status A pointer to an UErrorCode to receive any errors.
* @return The hash code associated with value.
* @return The previous value, or NULL if none.
* @see uhash_get
*/
U_CAPI int32_t
U_CAPI void*
uhash_put(UHashtable *hash,
void *value,
UErrorCode *status);
/**
* Put an item in a UHashtable.
* @param hash The target UHashtable.
* @param value The value to store.
* @param status A pointer to an UErrorCode to receive any errors.
* @return The hash code associated with value.
* @see uhash_get
*/
U_CAPI int32_t
uhash_putKey(UHashtable *hash,
int32_t valueKey,
void *value,
UErrorCode *status);
void *key,
void *value,
UErrorCode *status);
/**
* Get an item from a UHashtable.
@ -146,7 +242,7 @@ uhash_putKey(UHashtable *hash,
*/
U_CAPI void*
uhash_get(const UHashtable *hash,
int32_t key);
const void *key);
/**
* Remove an item from a UHashtable.
@ -157,8 +253,197 @@ uhash_get(const UHashtable *hash,
*/
U_CAPI void*
uhash_remove(UHashtable *hash,
int32_t key,
UErrorCode *status);
const void *key);
/**
* Iterate through the elements of a UHashtable. The caller must not
* modify the returned object. However, uhash_removeElement() may be
* called during iteration to remove an element from the table.
* Iteration may safely be resumed afterwards. If uhash_put() is
* 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
* thereafter.
* @return a hash element, or NULL if no further key-value pairs
* exist in the table.
*/
U_CAPI UHashElement*
uhash_nextElement(const UHashtable *hash,
int32_t *pos);
/**
* Remove an element, returned by uhash_nextElement(), from the table.
* Iteration may be safely continued afterwards.
* @param hash The hashtable
* @param e The element, returned by uhash_nextElement(), to remove.
* Must not be NULL. Must not be an empty or deleted element (as long
* as this was returned by uhash_nextElement() it will not be empty or
* deleted).
* @return the value that was removed.
*/
U_CAPI void*
uhash_removeElement(UHashtable *hash, UHashElement* e);
/********************************************************************
* Key Hash Functions
********************************************************************/
/**
* Generate a hash code for a null-terminated UChar* string. If the
* string is not null-terminated do not use this function. Use
* together with uhash_compareUChars.
* @param key The string (const UChar*) to hash.
* @return A hash code for the key.
*/
U_CAPI int32_t
uhash_hashUChars(const void *key);
/**
* Generate a hash code for a null-terminated char* string. If the
* string is not null-terminated do not use this function. Use
* together with uhash_compareChars.
* @param key The string (const char*) to hash.
* @return A hash code for the key.
*/
U_CAPI int32_t
uhash_hashChars(const void *key);
/**
* Generate a case-insensitive hash code for a null-terminated char*
* string. If the string is not null-terminated do not use this
* function. Use together with uhash_compareIChars.
* @param key The string (const char*) to hash.
* @return A hash code for the key.
*/
U_CAPI int32_t
uhash_hashIChars(const void *key);
/**
* Generate a hash code for a 32-bit integer. The hashcode is
* identical to the void* value itself.
* @param key The 32-bit integer (cast to void*) to hash.
* @return A hash code for the key.
*/
U_CAPI int32_t
uhash_hashLong(const void *key);
/********************************************************************
* Key Comparators
********************************************************************/
/**
* Comparator for null-terminated UChar* strings. Use together with
* uhash_hashUChars.
*/
U_CAPI bool_t
uhash_compareUChars(const void *key1, const void *key2);
/**
* Comparator for null-terminated char* strings. Use together with
* uhash_hashChars.
*/
U_CAPI bool_t
uhash_compareChars(const void *key1, const void *key2);
/**
* Case-insensitive comparator for null-terminated char* strings. Use
* together with uhash_hashIChars.
*/
U_CAPI bool_t
uhash_compareIChars(const void *key1, const void *key2);
/********************************************************************
* Object Deleters
********************************************************************/
/**
* Deleter for any key or value allocated using uprv_malloc. Calls
* uprv_free.
*/
U_CAPI void
uhash_freeBlock(void *obj);
/********************************************************************
* UnicodeString Support Functions
********************************************************************/
/**
* Hash function for UnicodeString* keys.
*/
U_CAPI int32_t
uhash_hashUnicodeString(const void *key);
/**
* Comparator function for UnicodeString* keys.
*/
U_CAPI bool_t
uhash_compareUnicodeString(const void *key1, const void *key2);
/**
* Deleter function for UnicodeString* keys or values.
*/
U_CAPI void
uhash_deleteUnicodeString(void *obj);
/*********************************************************************
* BEGIN BACKWARD COMPATIBILITY
* BEGIN BACKWARD COMPATIBILITY
*
* These functions will go away soon. Do not under any circumstances
* use them. This means you.
********************************************************************/
/**
* Put an item in a UHashtable.
* @param hash The target UHashtable.
* @param value The value to store.
* @param status A pointer to an UErrorCode to receive any errors.
* @return The hash code associated with value.
* @see uhash_get
*/
U_CAPI int32_t
uhash_OLD_put(UHashtable *hash,
void *value,
UErrorCode *status);
U_CAPI void*
uhash_OLD_get(const UHashtable *hash,
int32_t key);
/**
* Put an item in a UHashtable.
* @param hash The target UHashtable.
* @param value The value to store.
* @param status A pointer to an UErrorCode to receive any errors.
* @return The hash code associated with value.
* @see uhash_get
*/
U_CAPI int32_t
uhash_OLD_putKey(UHashtable *hash,
int32_t valueKey,
void *value,
UErrorCode *status);
/**
* Remove an item from a UHashtable.
* @param hash The target UHashtable.
* @param key The hash code of the value to be removed.
* @param status A pointer to an UErrorCode to receive any errors.
* @return The item removed, or 0 if not found.
*/
U_CAPI void*
uhash_OLD_remove(UHashtable *hash,
int32_t key,
UErrorCode *status);
/**
* Iterate through the elements of a UHashtable.
@ -168,57 +453,18 @@ uhash_remove(UHashtable *hash,
* @return The next item in the hash table, or 0 if no items remain.
*/
U_CAPI void*
uhash_nextElement(const UHashtable *hash,
int32_t *pos);
uhash_OLD_nextElement(const UHashtable *hash,
int32_t *pos);
/* Predefined hashing functions */
/** Indicates an invalid hash code */
#define UHASH_INVALID 0
/** Indicates a value is empty or 0 */
#define UHASH_EMPTY 1
/**
* Generate a hash code for a null-terminated ustring.
* If the string is not null-terminated the behavior of this
* function is undefined.
* @param parm The ustring (const UChar*) to hash.
* @return A hash code for parm.
*/
U_CAPI int32_t
uhash_hashUString(const void *parm);
uhash_OLD_hashUString(const void *key);
/**
* Generate a hash code for a null-terminated string.
* If the string is not null-terminated the behavior of this
* function is undefined.
* @param parm The string (const char*) to hash.
* @return A hash code for parm.
*/
U_CAPI int32_t
uhash_hashString(const void *parm);
U_CAPI bool_t
uhash_OLD_pointerComparator(const void* key1, const void* key2);
/**
* Generate a hash code for a null-terminated string in a case-insensitive way.
* If the string is not null-terminated the behavior of this
* function is undefined.
* @param parm The string (const char*) to hash.
* @return A hash code for parm.
*/
U_CAPI int32_t
uhash_hashIString(const void *parm);
/**
* Generate a hash code for long integer.
* @param parm The long (cast to void*) to hash.
* @return A hash code for parm.
*/
U_CAPI int32_t
uhash_hashLong(const void *parm);
/*********************************************************************
* END BACKWARD COMPATIBILITY
* END BACKWARD COMPATIBILITY
********************************************************************/
#endif

View File

@ -0,0 +1,37 @@
/*
*******************************************************************************
* Copyright (C) 1997-2000, International Business Machines
* Corporation and others. All Rights Reserved.
*******************************************************************************
* Date Name Description
* 03/22/00 aliu Creation.
*******************************************************************************
*/
#include "uhash.h"
#include "unicode/unistr.h"
/********************************************************************
* PUBLIC UnicodeString support functions for UHashtable
********************************************************************/
U_CAPI int32_t
uhash_hashUnicodeString(const void *key) {
return (key == NULL) ? 0 : ((UnicodeString*)key)->hashCode();
}
U_CAPI void
uhash_deleteUnicodeString(void *obj) {
delete (UnicodeString*) obj;
}
U_CAPI bool_t
uhash_compareUnicodeString(const void *key1, const void *key2) {
if (key1 == key2) {
return TRUE;
}
if (key1 == NULL || key2 == NULL) {
return FALSE;
}
return *((UnicodeString*) key1) == *((UnicodeString*) key2);
}