1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*
2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
31b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert*   Copyright (C) 1997-2014, International Business Machines
4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Corporation and others.  All Rights Reserved.
5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   Date        Name        Description
7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*   03/28/00    aliu        Creation.
8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru******************************************************************************
9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/
10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef HASH_H
12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define HASH_H
13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/unistr.h"
15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uobject.h"
1683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#include "cmemory.h"
17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uhash.h"
18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN
20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/**
22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Hashtable is a thin C++ wrapper around UHashtable, a general-purpose void*
23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * hashtable implemented in C.  Hashtable is designed to be idiomatic and
24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * easy-to-use in C++.
25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *
26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Hashtable is an INTERNAL CLASS.
27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */
28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass U_COMMON_API Hashtable : public UMemory {
29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UHashtable* hash;
30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UHashtable hashObj;
31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    inline void init(UHashFunction *keyHash, UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic:
35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Construct a hashtable
37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * @param ignoreKeyCase If true, keys are case insensitive.
38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * @param status Error code
39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Hashtable(UBool ignoreKeyCase, UErrorCode& status);
41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Construct a hashtable
4450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param keyComp Comparator for comparing the keys
4550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho     * @param valueComp Comparator for comparing the values
46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * @param status Error code
47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp, UErrorCode& status);
49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Construct a hashtable
52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * @param status Error code
53b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    */
54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Hashtable(UErrorCode& status);
55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Construct a hashtable, _disregarding any error_.  Use this constructor
58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * with caution.
59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Hashtable();
61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    /**
63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * Non-virtual destructor; make this virtual if Hashtable is subclassed
64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     * in the future.
65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru     */
66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    ~Hashtable();
67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UObjectDeleter *setValueDeleter(UObjectDeleter *fn);
69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t count() const;
71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    void* put(const UnicodeString& key, void* value, UErrorCode& status);
73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t puti(const UnicodeString& key, int32_t value, UErrorCode& status);
75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    void* get(const UnicodeString& key) const;
77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t geti(const UnicodeString& key) const;
79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    void* remove(const UnicodeString& key);
81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    int32_t removei(const UnicodeString& key);
83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    void removeAll(void);
85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UHashElement* find(const UnicodeString& key) const;
87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
881b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert    /**
891b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @param pos - must be UHASH_FIRST on first call, and untouched afterwards.
901b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     * @see uhash_nextElement
911b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert     */
92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    const UHashElement* nextElement(int32_t& pos) const;
93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
9450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UKeyComparator* setKeyComparator(UKeyComparator*keyComp);
95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
9650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho    UValueComparator* setValueComparator(UValueComparator* valueComp);
97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UBool equals(const Hashtable& that) const;
99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate:
100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Hashtable(const Hashtable &other); // forbid copying of this class
101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    Hashtable &operator=(const Hashtable &other); // forbid copying of this class
102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru};
103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*********************************************************************
105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Implementation
106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ********************************************************************/
107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline void Hashtable::init(UHashFunction *keyHash, UKeyComparator *keyComp,
109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                            UValueComparator *valueComp, UErrorCode& status) {
110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_FAILURE(status)) {
111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        return;
112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uhash_init(&hashObj, keyHash, keyComp, valueComp, &status);
114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (U_SUCCESS(status)) {
115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        hash = &hashObj;
11683a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius        uhash_setKeyDeleter(hash, uprv_deleteUObject);
117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline Hashtable::Hashtable(UKeyComparator *keyComp, UValueComparator *valueComp,
121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                 UErrorCode& status) : hash(0) {
122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    init( uhash_hashUnicodeString, keyComp, valueComp, status);
123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline Hashtable::Hashtable(UBool ignoreKeyCase, UErrorCode& status)
125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : hash(0)
126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    init(ignoreKeyCase ? uhash_hashCaselessUnicodeString
128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        : uhash_hashUnicodeString,
129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            ignoreKeyCase ? uhash_compareCaselessUnicodeString
130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru                        : uhash_compareUnicodeString,
131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            NULL,
132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru            status);
133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline Hashtable::Hashtable(UErrorCode& status)
136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : hash(0)
137b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline Hashtable::Hashtable()
142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : hash(0)
143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{
144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    init(uhash_hashUnicodeString, uhash_compareUnicodeString, NULL, status);
146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline Hashtable::~Hashtable() {
149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    if (hash != NULL) {
150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru        uhash_close(hash);
151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    }
152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline UObjectDeleter *Hashtable::setValueDeleter(UObjectDeleter *fn) {
155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_setValueDeleter(hash, fn);
156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline int32_t Hashtable::count() const {
159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_count(hash);
160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline void* Hashtable::put(const UnicodeString& key, void* value, UErrorCode& status) {
163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_put(hash, new UnicodeString(key), value, &status);
164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline int32_t Hashtable::puti(const UnicodeString& key, int32_t value, UErrorCode& status) {
167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_puti(hash, new UnicodeString(key), value, &status);
168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline void* Hashtable::get(const UnicodeString& key) const {
171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_get(hash, &key);
172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline int32_t Hashtable::geti(const UnicodeString& key) const {
175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_geti(hash, &key);
176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline void* Hashtable::remove(const UnicodeString& key) {
179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_remove(hash, &key);
180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline int32_t Hashtable::removei(const UnicodeString& key) {
183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_removei(hash, &key);
184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
186b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline const UHashElement* Hashtable::find(const UnicodeString& key) const {
187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_find(hash, &key);
188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline const UHashElement* Hashtable::nextElement(int32_t& pos) const {
191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_nextElement(hash, &pos);
192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline void Hashtable::removeAll(void) {
195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    uhash_removeAll(hash);
196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
19850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoinline UKeyComparator* Hashtable::setKeyComparator(UKeyComparator*keyComp){
199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_setKeyComparator(hash, keyComp);
200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
20250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoinline UValueComparator* Hashtable::setValueComparator(UValueComparator* valueComp){
203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru    return uhash_setValueComparator(hash, valueComp);
204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruinline UBool Hashtable::equals(const Hashtable& that)const{
207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru   return uhash_equals(hash, that.hash);
208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}
209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END
210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif
212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru
213