2 *******************************************************************************
3 * Copyright (C) 2000-2005, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 *******************************************************************************
6 * Date Name Description
7 * 03/22/00 aliu Creation.
8 * 07/13/00 Madhu Added more tests
9 *******************************************************************************
14 #include "unicode/ctest.h"
15 #include "unicode/ustring.h"
18 /**********************************************************************
20 *********************************************************************/
22 static void TestBasic(void);
23 static void TestOtherAPI(void);
24 static void hashIChars(void);
26 static int32_t U_EXPORT2 U_CALLCONV
hashChars(const UHashTok key
);
28 static UBool U_EXPORT2 U_CALLCONV
isEqualChars(const UHashTok key1
, const UHashTok key2
);
30 static void _put(UHashtable
* hash
,
33 int32_t expectedOldValue
);
35 static void _get(UHashtable
* hash
,
37 int32_t expectedValue
);
39 static void _remove(UHashtable
* hash
,
41 int32_t expectedValue
);
43 void addHashtableTest(TestNode
** root
);
45 /**********************************************************************
46 * UHashTok wrapper functions
47 *********************************************************************/
50 _compareChars(void* a
, void* b
) {
54 return uhash_compareChars(s
, t
);
58 _compareIChars(void* a
, void* b
) {
62 return uhash_compareIChars(s
, t
);
66 _compareUChars(void* a
, void* b
) {
70 return uhash_compareUChars(s
, t
);
74 _compareLong(int32_t a
, int32_t b
) {
78 return uhash_compareLong(s
, t
);
81 /**********************************************************************
83 *********************************************************************/
85 void addHashtableTest(TestNode
** root
) {
87 addTest(root
, &TestBasic
, "tsutil/chashtst/TestBasic");
88 addTest(root
, &TestOtherAPI
, "tsutil/chashtst/TestOtherAPI");
89 addTest(root
, &hashIChars
, "tsutil/chashtst/hashIChars");
93 /**********************************************************************
95 *********************************************************************/
97 static void TestBasic(void) {
98 static const char one
[4] = {0x6F, 0x6E, 0x65, 0}; /* "one" */
99 static const char one2
[4] = {0x6F, 0x6E, 0x65, 0}; /* Get around compiler optimizations */
100 static const char two
[4] = {0x74, 0x77, 0x6F, 0}; /* "two" */
101 static const char three
[6] = {0x74, 0x68, 0x72, 0x65, 0x65, 0}; /* "three" */
102 static const char omega
[6] = {0x6F, 0x6D, 0x65, 0x67, 0x61, 0}; /* "omega" */
103 UErrorCode status
= U_ZERO_ERROR
;
106 hash
= uhash_open(hashChars
, isEqualChars
, NULL
, &status
);
107 if (U_FAILURE(status
)) {
108 log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
109 u_errorName(status
), hash
);
113 log_err("FAIL: uhash_open returned NULL\n");
116 log_verbose("Ok: uhash_open returned 0x%08X\n", hash
);
118 _put(hash
, one
, 1, 0);
119 _put(hash
, omega
, 24, 0);
120 _put(hash
, two
, 2, 0);
121 _put(hash
, three
, 3, 0);
122 _put(hash
, one
, -1, 1);
123 _put(hash
, two
, -2, 2);
124 _put(hash
, omega
, 48, 24);
125 _put(hash
, one
, 100, -1);
126 _get(hash
, three
, 3);
127 _remove(hash
, two
, -2);
129 _get(hash
, one
, 100);
130 _put(hash
, two
, 200, 0);
131 _get(hash
, omega
, 48);
132 _get(hash
, two
, 200);
134 if(_compareChars((void*)one
, (void*)three
) == TRUE
||
135 _compareChars((void*)one
, (void*)one2
) != TRUE
||
136 _compareChars((void*)one
, (void*)one
) != TRUE
||
137 _compareChars((void*)one
, NULL
) == TRUE
) {
138 log_err("FAIL: compareChars failed\n");
140 if(_compareIChars((void*)one
, (void*)three
) == TRUE
||
141 _compareIChars((void*)one
, (void*)one
) != TRUE
||
142 _compareIChars((void*)one
, (void*)one2
) != TRUE
||
143 _compareIChars((void*)one
, NULL
) == TRUE
) {
144 log_err("FAIL: compareIChars failed\n");
151 static void TestOtherAPI(void){
153 UErrorCode status
= U_ZERO_ERROR
;
156 /* Use the correct type when cast to void * */
157 static const UChar one
[4] = {0x006F, 0x006E, 0x0065, 0}; /* L"one" */
158 static const UChar one2
[4] = {0x006F, 0x006E, 0x0065, 0}; /* Get around compiler optimizations */
159 static const UChar two
[4] = {0x0074, 0x0077, 0x006F, 0}; /* L"two" */
160 static const UChar two2
[4] = {0x0074, 0x0077, 0x006F, 0}; /* L"two" */
161 static const UChar three
[6] = {0x0074, 0x0068, 0x0072, 0x0065, 0x0065, 0}; /* L"three" */
162 static const UChar four
[6] = {0x0066, 0x006F, 0x0075, 0x0072, 0}; /* L"four" */
163 static const UChar five
[6] = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */
164 static const UChar five2
[6] = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */
166 hash
= uhash_open(uhash_hashUChars
, uhash_compareUChars
, NULL
, &status
);
167 if (U_FAILURE(status
)) {
168 log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
169 u_errorName(status
), hash
);
173 log_err("FAIL: uhash_open returned NULL\n");
176 log_verbose("Ok: uhash_open returned 0x%08X\n", hash
);
178 uhash_puti(hash
, (void*)one
, 1, &status
);
179 if(uhash_count(hash
) != 1){
180 log_err("FAIL: uhas_count() failed. Expected: 1, Got: %d\n", uhash_count(hash
));
182 if(uhash_find(hash
, (void*)two
) != NULL
){
183 log_err("FAIL: uhash_find failed\n");
185 uhash_puti(hash
, (void*)two
, 2, &status
);
186 uhash_puti(hash
, (void*)three
, 3, &status
);
187 uhash_puti(hash
, (void*)four
, 4, &status
);
188 uhash_puti(hash
, (void*)five
, 5, &status
);
190 if(uhash_count(hash
) != 5){
191 log_err("FAIL: uhas_count() failed. Expected: 5, Got: %d\n", uhash_count(hash
));
194 if(uhash_geti(hash
, (void*)two2
) != 2){
195 log_err("FAIL: uhash_geti failed\n");
198 if(uhash_find(hash
, (void*)two2
) == NULL
){
199 log_err("FAIL: uhash_find of \"two\" failed\n");
202 if(uhash_removei(hash
, (void*)five2
) != 5){
203 log_err("FAIL: uhash_remove() failed\n");
205 if(uhash_count(hash
) != 4){
206 log_err("FAIL: uhas_count() failed. Expected: 4, Got: %d\n", uhash_count(hash
));
209 uhash_put(hash
, (void*)one
, NULL
, &status
);
210 if(uhash_count(hash
) != 3){
211 log_err("FAIL: uhash_put() with value=NULL didn't remove the key value pair\n");
213 status
=U_ILLEGAL_ARGUMENT_ERROR
;
214 uhash_puti(hash
, (void*)one
, 1, &status
);
215 if(uhash_count(hash
) != 3){
216 log_err("FAIL: uhash_put() with value!=NULL should fail when status != U_ZERO_ERROR \n");
220 uhash_puti(hash
, (void*)one
, 1, &status
);
221 if(uhash_count(hash
) != 4){
222 log_err("FAIL: uhash_put() with value!=NULL didn't replace the key value pair\n");
225 if(_compareUChars((void*)one
, (void*)two
) == TRUE
||
226 _compareUChars((void*)one
, (void*)one
) != TRUE
||
227 _compareUChars((void*)one
, (void*)one2
) != TRUE
||
228 _compareUChars((void*)one
, NULL
) == TRUE
) {
229 log_err("FAIL: compareUChars failed\n");
232 uhash_removeAll(hash
);
233 if(uhash_count(hash
) != 0){
234 log_err("FAIL: uhas_count() failed. Expected: 0, Got: %d\n", uhash_count(hash
));
237 uhash_setKeyComparator(hash
, uhash_compareLong
);
238 uhash_setKeyHasher(hash
, uhash_hashLong
);
239 uhash_iputi(hash
, 1001, 1, &status
);
240 uhash_iputi(hash
, 1002, 2, &status
);
241 uhash_iputi(hash
, 1003, 3, &status
);
242 if(_compareLong(1001, 1002) == TRUE
||
243 _compareLong(1001, 1001) != TRUE
||
244 _compareLong(1001, 0) == TRUE
) {
245 log_err("FAIL: compareLong failed\n");
247 /*set the resize policy to just GROW and SHRINK*/
248 /*how to test this??*/
249 uhash_setResizePolicy(hash
, U_GROW_AND_SHRINK
);
250 uhash_iputi(hash
, 1004, 4, &status
);
251 uhash_iputi(hash
, 1005, 5, &status
);
252 uhash_iputi(hash
, 1006, 6, &status
);
253 if(uhash_count(hash
) != 6){
254 log_err("FAIL: uhash_count() failed. Expected: 6, Got: %d\n", uhash_count(hash
));
256 if(uhash_iremovei(hash
, 1004) != 4){
257 log_err("FAIL: uhash_remove failed\n");
259 if(uhash_iremovei(hash
, 1004) != 0){
260 log_err("FAIL: uhash_remove failed\n");
263 uhash_removeAll(hash
);
264 uhash_iput(hash
, 2004, (void*)one
, &status
);
265 uhash_iput(hash
, 2005, (void*)two
, &status
);
266 if(uhash_count(hash
) != 2){
267 log_err("FAIL: uhash_count() failed. Expected: 2, Got: %d\n", uhash_count(hash
));
269 if(uhash_iremove(hash
, 2004) != (void*)one
){
270 log_err("FAIL: uhash_remove failed\n");
272 if(uhash_iremove(hash
, 2004) != NULL
){
273 log_err("FAIL: uhash_remove failed\n");
275 if(uhash_count(hash
) != 1){
276 log_err("FAIL: uhash_count() failed. Expected: 1, Got: %d\n", uhash_count(hash
));
283 static void hashIChars(void) {
284 static const char which
[] = "which";
285 static const char WHICH2
[] = "WHICH";
286 static const char where
[] = "where";
287 UErrorCode status
= U_ZERO_ERROR
;
290 hash
= uhash_open(uhash_hashIChars
, uhash_compareIChars
, NULL
, &status
);
291 if (U_FAILURE(status
)) {
292 log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
293 u_errorName(status
), hash
);
297 log_err("FAIL: uhash_open returned NULL\n");
300 log_verbose("Ok: uhash_open returned 0x%08X\n", hash
);
302 _put(hash
, which
, 1, 0);
303 _put(hash
, WHICH2
, 2, 1);
304 _put(hash
, where
, 3, 0);
305 if(uhash_count(hash
) != 2){
306 log_err("FAIL: uhas_count() failed. Expected: 1, Got: %d\n", uhash_count(hash
));
308 _remove(hash
, which
, 2);
314 /**********************************************************************
316 *********************************************************************/
319 * This hash function is designed to collide a lot to test key equality
320 * resolution. It only uses the first char.
322 static int32_t U_EXPORT2 U_CALLCONV
hashChars(const UHashTok key
) {
323 return *(const char*) key
.pointer
;
326 static UBool U_EXPORT2 U_CALLCONV
isEqualChars(const UHashTok key1
, const UHashTok key2
) {
327 return (UBool
)((key1
.pointer
!= NULL
) &&
328 (key2
.pointer
!= NULL
) &&
329 (uprv_strcmp((const char*)key1
.pointer
, (const char*)key2
.pointer
) == 0));
332 /**********************************************************************
334 *********************************************************************/
336 static void _put(UHashtable
* hash
,
339 int32_t expectedOldValue
) {
340 UErrorCode status
= U_ZERO_ERROR
;
342 uhash_puti(hash
, (void*) key
, value
, &status
);
343 if (U_FAILURE(status
)) {
344 log_err("FAIL: uhash_put(%s) failed with %s and returned %ld\n",
345 key
, u_errorName(status
), oldValue
);
346 } else if (oldValue
!= expectedOldValue
) {
347 log_err("FAIL: uhash_put(%s) returned old value %ld; expected %ld\n",
348 key
, oldValue
, expectedOldValue
);
350 log_verbose("Ok: uhash_put(%s, %d) returned old value %ld\n",
351 key
, value
, oldValue
);
355 static void _get(UHashtable
* hash
,
357 int32_t expectedValue
) {
358 UErrorCode status
= U_ZERO_ERROR
;
359 int32_t value
= uhash_geti(hash
, key
);
360 if (U_FAILURE(status
)) {
361 log_err("FAIL: uhash_get(%s) failed with %s and returned %ld\n",
362 key
, u_errorName(status
), value
);
363 } else if (value
!= expectedValue
) {
364 log_err("FAIL: uhash_get(%s) returned %ld; expected %ld\n",
365 key
, value
, expectedValue
);
367 log_verbose("Ok: uhash_get(%s) returned value %ld\n",
372 static void _remove(UHashtable
* hash
,
374 int32_t expectedValue
) {
375 int32_t value
= uhash_removei(hash
, key
);
376 if (value
!= expectedValue
) {
377 log_err("FAIL: uhash_remove(%s) returned %ld; expected %ld\n",
378 key
, value
, expectedValue
);
380 log_verbose("Ok: uhash_remove(%s) returned old value %ld\n",