2 *******************************************************************************
3 * Copyright (C) 2000-2004, 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);
25 static int32_t U_EXPORT2 U_CALLCONV
hashChars(const UHashTok key
);
27 static UBool U_EXPORT2 U_CALLCONV
isEqualChars(const UHashTok key1
, const UHashTok key2
);
29 static void _put(UHashtable
* hash
,
32 int32_t expectedOldValue
);
34 static void _get(UHashtable
* hash
,
36 int32_t expectedValue
);
38 static void _remove(UHashtable
* hash
,
40 int32_t expectedValue
);
42 void addHashtableTest(TestNode
** root
);
44 /**********************************************************************
45 * UHashTok wrapper functions
46 *********************************************************************/
49 _compareChars(void* a
, void* b
) {
53 return uhash_compareChars(s
, t
);
57 _compareIChars(void* a
, void* b
) {
61 return uhash_compareIChars(s
, t
);
65 _compareUChars(void* a
, void* b
) {
69 return uhash_compareUChars(s
, t
);
73 _compareLong(int32_t a
, int32_t b
) {
77 return uhash_compareLong(s
, t
);
80 /**********************************************************************
82 *********************************************************************/
84 void addHashtableTest(TestNode
** root
) {
86 addTest(root
, &TestBasic
, "tsutil/chashtst/TestBasic");
87 addTest(root
, &TestOtherAPI
, "tsutil/chashtst/TestOtherAPI");
91 /**********************************************************************
93 *********************************************************************/
95 static void TestBasic(void) {
96 const char one
[4] = {0x6F, 0x6E, 0x65, 0}; /* "one" */
97 const char one2
[4] = {0x6F, 0x6E, 0x65, 0}; /* Get around compiler optimizations */
98 const char two
[4] = {0x74, 0x77, 0x6F, 0}; /* "two" */
99 const char three
[6] = {0x74, 0x68, 0x72, 0x65, 0x65, 0}; /* "three" */
100 const char omega
[6] = {0x6F, 0x6D, 0x65, 0x67, 0x61, 0}; /* "omega" */
101 UErrorCode status
= U_ZERO_ERROR
;
104 hash
= uhash_open(hashChars
, isEqualChars
, &status
);
105 if (U_FAILURE(status
)) {
106 log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
107 u_errorName(status
), hash
);
111 log_err("FAIL: uhash_open returned NULL\n");
114 log_verbose("Ok: uhash_open returned 0x%08X\n", hash
);
116 _put(hash
, one
, 1, 0);
117 _put(hash
, omega
, 24, 0);
118 _put(hash
, two
, 2, 0);
119 _put(hash
, three
, 3, 0);
120 _put(hash
, one
, -1, 1);
121 _put(hash
, two
, -2, 2);
122 _put(hash
, omega
, 48, 24);
123 _put(hash
, one
, 100, -1);
124 _get(hash
, three
, 3);
125 _remove(hash
, two
, -2);
127 _get(hash
, one
, 100);
128 _put(hash
, two
, 200, 0);
129 _get(hash
, omega
, 48);
130 _get(hash
, two
, 200);
132 if(_compareChars((void*)one
, (void*)three
) == TRUE
||
133 _compareChars((void*)one
, (void*)one2
) != TRUE
||
134 _compareChars((void*)one
, (void*)one
) != TRUE
||
135 _compareChars((void*)one
, NULL
) == TRUE
) {
136 log_err("FAIL: compareChars failed\n");
138 if(_compareIChars((void*)one
, (void*)three
) == TRUE
||
139 _compareIChars((void*)one
, (void*)one
) != TRUE
||
140 _compareIChars((void*)one
, (void*)one2
) != TRUE
||
141 _compareIChars((void*)one
, NULL
) == TRUE
) {
142 log_err("FAIL: compareIChars failed\n");
149 static void TestOtherAPI(void){
151 UErrorCode status
= U_ZERO_ERROR
;
154 /* Use the correct type when cast to void * */
155 const UChar one
[4] = {0x006F, 0x006E, 0x0065, 0}; /* L"one" */
156 const UChar one2
[4] = {0x006F, 0x006E, 0x0065, 0}; /* Get around compiler optimizations */
157 const UChar two
[4] = {0x0074, 0x0077, 0x006F, 0}; /* L"two" */
158 const UChar two2
[4] = {0x0074, 0x0077, 0x006F, 0}; /* L"two" */
159 const UChar three
[6] = {0x0074, 0x0068, 0x0072, 0x0065, 0x0065, 0}; /* L"three" */
160 const UChar four
[6] = {0x0066, 0x006F, 0x0075, 0x0072, 0}; /* L"four" */
161 const UChar five
[6] = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */
162 const UChar five2
[6] = {0x0066, 0x0069, 0x0076, 0x0065, 0}; /* L"five" */
164 hash
= uhash_open(uhash_hashUChars
, uhash_compareUChars
, &status
);
165 if (U_FAILURE(status
)) {
166 log_err("FAIL: uhash_open failed with %s and returned 0x%08x\n",
167 u_errorName(status
), hash
);
171 log_err("FAIL: uhash_open returned NULL\n");
174 log_verbose("Ok: uhash_open returned 0x%08X\n", hash
);
176 uhash_puti(hash
, (void*)one
, 1, &status
);
177 if(uhash_count(hash
) != 1){
178 log_err("FAIL: uhas_count() failed. Expected: 1, Got: %d\n", uhash_count(hash
));
180 uhash_puti(hash
, (void*)two
, 2, &status
);
181 uhash_puti(hash
, (void*)three
, 3, &status
);
182 uhash_puti(hash
, (void*)four
, 4, &status
);
183 uhash_puti(hash
, (void*)five
, 5, &status
);
185 if(uhash_count(hash
) != 5){
186 log_err("FAIL: uhas_count() failed. Expected: 5, Got: %d\n", uhash_count(hash
));
189 if(uhash_geti(hash
, (void*)two2
) != 2){
190 log_err("FAIL: uhash_geti failed\n");
193 if(uhash_removei(hash
, (void*)five2
) != 5){
194 log_err("FAIL: uhash_remove() failed\n");
196 if(uhash_count(hash
) != 4){
197 log_err("FAIL: uhas_count() failed. Expected: 4, Got: %d\n", uhash_count(hash
));
200 uhash_put(hash
, (void*)one
, NULL
, &status
);
201 if(uhash_count(hash
) != 3){
202 log_err("FAIL: uhash_put() with value=NULL didn't remove the key value pair\n");
204 status
=U_ILLEGAL_ARGUMENT_ERROR
;
205 uhash_puti(hash
, (void*)one
, 1, &status
);
206 if(uhash_count(hash
) != 3){
207 log_err("FAIL: uhash_put() with value!=NULL should fail when status != U_ZERO_ERROR \n");
211 uhash_puti(hash
, (void*)one
, 1, &status
);
212 if(uhash_count(hash
) != 4){
213 log_err("FAIL: uhash_put() with value!=NULL didn't replace the key value pair\n");
216 if(_compareUChars((void*)one
, (void*)two
) == TRUE
||
217 _compareUChars((void*)one
, (void*)one
) != TRUE
||
218 _compareUChars((void*)one
, (void*)one2
) != TRUE
||
219 _compareUChars((void*)one
, NULL
) == TRUE
) {
220 log_err("FAIL: compareUChars failed\n");
223 uhash_removeAll(hash
);
224 if(uhash_count(hash
) != 0){
225 log_err("FAIL: uhas_count() failed. Expected: 0, Got: %d\n", uhash_count(hash
));
228 uhash_setKeyComparator(hash
, uhash_compareLong
);
229 uhash_setKeyHasher(hash
, uhash_hashLong
);
230 uhash_iputi(hash
, 1001, 1, &status
);
231 uhash_iputi(hash
, 1002, 2, &status
);
232 uhash_iputi(hash
, 1003, 3, &status
);
233 if(_compareLong(1001, 1002) == TRUE
||
234 _compareLong(1001, 1001) != TRUE
||
235 _compareLong(1001, 0) == TRUE
) {
236 log_err("FAIL: compareLong failed\n");
238 /*set the resize policy to just GROW and SHRINK*/
239 /*how to test this??*/
240 uhash_setResizePolicy(hash
, U_GROW_AND_SHRINK
);
241 uhash_iputi(hash
, 1004, 4, &status
);
242 uhash_iputi(hash
, 1005, 5, &status
);
243 uhash_iputi(hash
, 1006, 6, &status
);
244 if(uhash_count(hash
) != 6){
245 log_err("FAIL: uhash_count() failed. Expected: 6, Got: %d\n", uhash_count(hash
));
247 if(uhash_iremovei(hash
, 1004) != 4){
248 log_err("FAIL: uhash_remove failed\n");
250 if(uhash_iremovei(hash
, 1004) != 0){
251 log_err("FAIL: uhash_remove failed\n");
256 /**********************************************************************
258 *********************************************************************/
261 * This hash function is designed to collide a lot to test key equality
262 * resolution. It only uses the first char.
264 static int32_t U_EXPORT2 U_CALLCONV
hashChars(const UHashTok key
) {
265 return *(const char*) key
.pointer
;
268 static UBool U_EXPORT2 U_CALLCONV
isEqualChars(const UHashTok key1
, const UHashTok key2
) {
269 return (UBool
)((key1
.pointer
!= NULL
) &&
270 (key2
.pointer
!= NULL
) &&
271 (uprv_strcmp((const char*)key1
.pointer
, (const char*)key2
.pointer
) == 0));
274 /**********************************************************************
276 *********************************************************************/
278 static void _put(UHashtable
* hash
,
281 int32_t expectedOldValue
) {
282 UErrorCode status
= U_ZERO_ERROR
;
284 uhash_puti(hash
, (void*) key
, value
, &status
);
285 if (U_FAILURE(status
)) {
286 log_err("FAIL: uhash_put(%s) failed with %s and returned %ld\n",
287 key
, u_errorName(status
), oldValue
);
288 } else if (oldValue
!= expectedOldValue
) {
289 log_err("FAIL: uhash_put(%s) returned old value %ld; expected %ld\n",
290 key
, oldValue
, expectedOldValue
);
292 log_verbose("Ok: uhash_put(%s, %d) returned old value %ld\n",
293 key
, value
, oldValue
);
297 static void _get(UHashtable
* hash
,
299 int32_t expectedValue
) {
300 UErrorCode status
= U_ZERO_ERROR
;
301 int32_t value
= uhash_geti(hash
, key
);
302 if (U_FAILURE(status
)) {
303 log_err("FAIL: uhash_get(%s) failed with %s and returned %ld\n",
304 key
, u_errorName(status
), value
);
305 } else if (value
!= expectedValue
) {
306 log_err("FAIL: uhash_get(%s) returned %ld; expected %ld\n",
307 key
, value
, expectedValue
);
309 log_verbose("Ok: uhash_get(%s) returned value %ld\n",
314 static void _remove(UHashtable
* hash
,
316 int32_t expectedValue
) {
317 int32_t value
= uhash_removei(hash
, key
);
318 if (value
!= expectedValue
) {
319 log_err("FAIL: uhash_remove(%s) returned %ld; expected %ld\n",
320 key
, value
, expectedValue
);
322 log_verbose("Ok: uhash_remove(%s) returned old value %ld\n",