OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ******************************************************************************* |
| 3 * Copyright (C) 2000-2009, 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 ******************************************************************************* |
| 10 */ |
| 11 |
| 12 #include "cintltst.h" |
| 13 #include "uhash.h" |
| 14 #include "unicode/ctest.h" |
| 15 #include "unicode/ustring.h" |
| 16 #include "cstring.h" |
| 17 |
| 18 /********************************************************************** |
| 19 * Prototypes |
| 20 *********************************************************************/ |
| 21 |
| 22 static void TestBasic(void); |
| 23 static void TestOtherAPI(void); |
| 24 static void hashIChars(void); |
| 25 |
| 26 static int32_t U_EXPORT2 U_CALLCONV hashChars(const UHashTok key); |
| 27 |
| 28 static UBool U_EXPORT2 U_CALLCONV isEqualChars(const UHashTok key1, const UHashT
ok key2); |
| 29 |
| 30 static void _put(UHashtable* hash, |
| 31 const char* key, |
| 32 int32_t value, |
| 33 int32_t expectedOldValue); |
| 34 |
| 35 static void _get(UHashtable* hash, |
| 36 const char* key, |
| 37 int32_t expectedValue); |
| 38 |
| 39 static void _remove(UHashtable* hash, |
| 40 const char* key, |
| 41 int32_t expectedValue); |
| 42 |
| 43 void addHashtableTest(TestNode** root); |
| 44 |
| 45 /********************************************************************** |
| 46 * UHashTok wrapper functions |
| 47 *********************************************************************/ |
| 48 |
| 49 static UBool |
| 50 _compareChars(const void* a, const void* b) { |
| 51 UHashTok s, t; |
| 52 s.pointer = (void *)a; |
| 53 t.pointer = (void *)b; |
| 54 return uhash_compareChars(s, t); |
| 55 } |
| 56 |
| 57 static UBool |
| 58 _compareIChars(const void* a, const void* b) { |
| 59 UHashTok s, t; |
| 60 s.pointer = (void *)a; |
| 61 t.pointer = (void *)b; |
| 62 return uhash_compareIChars(s, t); |
| 63 } |
| 64 |
| 65 static UBool |
| 66 _compareUChars(const void* a, const void* b) { |
| 67 UHashTok s, t; |
| 68 s.pointer = (void *)a; |
| 69 t.pointer = (void *)b; |
| 70 return uhash_compareUChars(s, t); |
| 71 } |
| 72 |
| 73 static UBool |
| 74 _compareLong(int32_t a, int32_t b) { |
| 75 UHashTok s, t; |
| 76 s.integer = a; |
| 77 t.integer = b; |
| 78 return uhash_compareLong(s, t); |
| 79 } |
| 80 |
| 81 /********************************************************************** |
| 82 * FW Registration |
| 83 *********************************************************************/ |
| 84 |
| 85 void addHashtableTest(TestNode** root) { |
| 86 |
| 87 addTest(root, &TestBasic, "tsutil/chashtst/TestBasic"); |
| 88 addTest(root, &TestOtherAPI, "tsutil/chashtst/TestOtherAPI"); |
| 89 addTest(root, &hashIChars, "tsutil/chashtst/hashIChars"); |
| 90 |
| 91 } |
| 92 |
| 93 /********************************************************************** |
| 94 * Test Functions |
| 95 *********************************************************************/ |
| 96 |
| 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 o
ptimizations */ |
| 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; |
| 104 UHashtable *hash; |
| 105 |
| 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); |
| 110 return; |
| 111 } |
| 112 if (hash == NULL) { |
| 113 log_err("FAIL: uhash_open returned NULL\n"); |
| 114 return; |
| 115 } |
| 116 log_verbose("Ok: uhash_open returned 0x%08X\n", hash); |
| 117 |
| 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); |
| 128 _get(hash, two, 0); |
| 129 _get(hash, one, 100); |
| 130 _put(hash, two, 200, 0); |
| 131 _get(hash, omega, 48); |
| 132 _get(hash, two, 200); |
| 133 |
| 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"); |
| 139 } |
| 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"); |
| 145 } |
| 146 |
| 147 uhash_close(hash); |
| 148 |
| 149 } |
| 150 |
| 151 static void TestOtherAPI(void){ |
| 152 |
| 153 UErrorCode status = U_ZERO_ERROR; |
| 154 UHashtable *hash; |
| 155 |
| 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 com
piler 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
" */ |
| 165 |
| 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); |
| 170 return; |
| 171 } |
| 172 if (hash == NULL) { |
| 173 log_err("FAIL: uhash_open returned NULL\n"); |
| 174 return; |
| 175 } |
| 176 log_verbose("Ok: uhash_open returned 0x%08X\n", hash); |
| 177 |
| 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_coun
t(hash)); |
| 181 } |
| 182 if(uhash_find(hash, (void*)two) != NULL){ |
| 183 log_err("FAIL: uhash_find failed\n"); |
| 184 } |
| 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); |
| 189 |
| 190 if(uhash_count(hash) != 5){ |
| 191 log_err("FAIL: uhas_count() failed. Expected: 5, Got: %d\n", uhash_count
(hash)); |
| 192 } |
| 193 |
| 194 if(uhash_geti(hash, (void*)two2) != 2){ |
| 195 log_err("FAIL: uhash_geti failed\n"); |
| 196 } |
| 197 |
| 198 if(uhash_find(hash, (void*)two2) == NULL){ |
| 199 log_err("FAIL: uhash_find of \"two\" failed\n"); |
| 200 } |
| 201 |
| 202 if(uhash_removei(hash, (void*)five2) != 5){ |
| 203 log_err("FAIL: uhash_remove() failed\n"); |
| 204 } |
| 205 if(uhash_count(hash) != 4){ |
| 206 log_err("FAIL: uhas_count() failed. Expected: 4, Got: %d\n", uhash_count
(hash)); |
| 207 } |
| 208 |
| 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 p
air\n"); |
| 212 } |
| 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"); |
| 217 } |
| 218 |
| 219 status=U_ZERO_ERROR; |
| 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"); |
| 223 } |
| 224 |
| 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"); |
| 230 } |
| 231 |
| 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)); |
| 235 } |
| 236 |
| 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"); |
| 246 } |
| 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_coun
t(hash)); |
| 255 } |
| 256 if(uhash_iremovei(hash, 1004) != 4){ |
| 257 log_err("FAIL: uhash_remove failed\n"); |
| 258 } |
| 259 if(uhash_iremovei(hash, 1004) != 0){ |
| 260 log_err("FAIL: uhash_remove failed\n"); |
| 261 } |
| 262 |
| 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_coun
t(hash)); |
| 268 } |
| 269 if(uhash_iremove(hash, 2004) != (void*)one){ |
| 270 log_err("FAIL: uhash_remove failed\n"); |
| 271 } |
| 272 if(uhash_iremove(hash, 2004) != NULL){ |
| 273 log_err("FAIL: uhash_remove failed\n"); |
| 274 } |
| 275 if(uhash_count(hash) != 1){ |
| 276 log_err("FAIL: uhash_count() failed. Expected: 1, Got: %d\n", uhash_coun
t(hash)); |
| 277 } |
| 278 |
| 279 uhash_close(hash); |
| 280 |
| 281 } |
| 282 |
| 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; |
| 288 UHashtable *hash; |
| 289 |
| 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); |
| 294 return; |
| 295 } |
| 296 if (hash == NULL) { |
| 297 log_err("FAIL: uhash_open returned NULL\n"); |
| 298 return; |
| 299 } |
| 300 log_verbose("Ok: uhash_open returned 0x%08X\n", hash); |
| 301 |
| 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_coun
t(hash)); |
| 307 } |
| 308 _remove(hash, which, 2); |
| 309 |
| 310 uhash_close(hash); |
| 311 } |
| 312 |
| 313 |
| 314 /********************************************************************** |
| 315 * uhash Callbacks |
| 316 *********************************************************************/ |
| 317 |
| 318 /** |
| 319 * This hash function is designed to collide a lot to test key equality |
| 320 * resolution. It only uses the first char. |
| 321 */ |
| 322 static int32_t U_EXPORT2 U_CALLCONV hashChars(const UHashTok key) { |
| 323 return *(const char*) key.pointer; |
| 324 } |
| 325 |
| 326 static UBool U_EXPORT2 U_CALLCONV isEqualChars(const UHashTok key1, const UHashT
ok key2) { |
| 327 return (UBool)((key1.pointer != NULL) && |
| 328 (key2.pointer != NULL) && |
| 329 (uprv_strcmp((const char*)key1.pointer, (const char*)key2.pointer) == 0)
); |
| 330 } |
| 331 |
| 332 /********************************************************************** |
| 333 * Wrapper Functions |
| 334 *********************************************************************/ |
| 335 |
| 336 static void _put(UHashtable* hash, |
| 337 const char* key, |
| 338 int32_t value, |
| 339 int32_t expectedOldValue) { |
| 340 UErrorCode status = U_ZERO_ERROR; |
| 341 int32_t oldValue = |
| 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); |
| 349 } else { |
| 350 log_verbose("Ok: uhash_put(%s, %d) returned old value %ld\n", |
| 351 key, value, oldValue); |
| 352 } |
| 353 } |
| 354 |
| 355 static void _get(UHashtable* hash, |
| 356 const char* key, |
| 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); |
| 366 } else { |
| 367 log_verbose("Ok: uhash_get(%s) returned value %ld\n", |
| 368 key, value); |
| 369 } |
| 370 } |
| 371 |
| 372 static void _remove(UHashtable* hash, |
| 373 const char* key, |
| 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); |
| 379 } else { |
| 380 log_verbose("Ok: uhash_remove(%s) returned old value %ld\n", |
| 381 key, value); |
| 382 } |
| 383 } |
| 384 |
OLD | NEW |