ICU-149 rewrite UHashtable
X-SVN-Rev: 1001
This commit is contained in:
parent
d4146dab5f
commit
2ddc4768a3
@ -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
|
||||
|
83
icu4c/source/common/hash.h
Normal file
83
icu4c/source/common/hash.h
Normal 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
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
@ -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
|
||||
|
||||
|
||||
|
||||
|
37
icu4c/source/common/uhash_us.cpp
Normal file
37
icu4c/source/common/uhash_us.cpp
Normal 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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user