tests/test_hash_map.c

changeset 1114
ad5eeb256242
parent 1111
78eeeb950883
child 1115
6db21dee4929
equal deleted inserted replaced
1113:dce04550fbef 1114:ad5eeb256242
255 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 255 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
256 } 256 }
257 cx_testing_allocator_destroy(&talloc); 257 cx_testing_allocator_destroy(&talloc);
258 } 258 }
259 259
260 static void test_simple_destructor(void *data) { 260 struct test_destr_struct {
261 strcpy(data, "OK"); 261 char *str;
262 };
263
264 static void test_simple_destructor(void *d) {
265 struct test_destr_struct *data = d;
266 strcpy(data->str, "OK");
262 } 267 }
263 268
264 static void test_advanced_destructor( 269 static void test_advanced_destructor(
265 cx_attr_unused void *unused, 270 cx_attr_unused void *unused,
266 void *data 271 void *d
267 ) { 272 ) {
268 strcpy(data, "OK"); 273 test_simple_destructor(d);
269 } 274 }
270 275
271 static CX_TEST_SUBROUTINE(verify_any_destructor, CxMap *map) { 276 static CX_TEST_SUBROUTINE(verify_any_destructor, CxMap *map) {
272 CxHashKey k1 = cx_hash_key_str("key 1"); 277 CxHashKey k1 = cx_hash_key_str("key 1");
273 CxHashKey k2 = cx_hash_key_str("key 2"); 278 CxHashKey k2 = cx_hash_key_str("key 2");
278 char v1[] = "val 1"; 283 char v1[] = "val 1";
279 char v2[] = "val 2"; 284 char v2[] = "val 2";
280 char v3[] = "val 3"; 285 char v3[] = "val 3";
281 char v4[] = "val 4"; 286 char v4[] = "val 4";
282 char v5[] = "val 5"; 287 char v5[] = "val 5";
283 288 char v6[] = "val 6";
284 cxMapPut(map, k1, v1); 289 char v7[] = "val 7";
285 cxMapPut(map, k2, v2); 290
286 cxMapPut(map, k3, v3); 291 struct test_destr_struct d1 = {v1};
287 cxMapPut(map, k4, v4); 292 struct test_destr_struct d2 = {v2};
293 struct test_destr_struct d3 = {v3};
294 struct test_destr_struct d4 = {v4};
295 struct test_destr_struct d5 = {v5};
296 struct test_destr_struct d6 = {v6};
297 struct test_destr_struct d7 = {v7};
298
299 void *v1data = &d1;
300 void *v2data = &d2;
301 void *v3data = &d3;
302 void *v4data = &d4;
303 void *v5data = &d5;
304 void *v6data = &d6;
305 void *v7data = &d7;
306
307 cxMapPut(map, k1, v1data);
308 cxMapPut(map, k2, v2data);
309 cxMapPut(map, k3, v3data);
310 cxMapPut(map, k4, v4data);
288 311
289 CX_TEST_ASSERT(0 == cxMapRemove(map, k2)); 312 CX_TEST_ASSERT(0 == cxMapRemove(map, k2));
290 char *r; 313 if (map->collection.store_pointer) {
291 CX_TEST_ASSERT(0 == cxMapRemoveAndGet(map, k3, &r)); 314 struct test_destr_struct *r;
315 CX_TEST_ASSERT(0 == cxMapRemoveAndGet(map, k3, &r));
316 CX_TEST_ASSERT(r == &d3);
317 } else {
318 struct test_destr_struct r;
319 CX_TEST_ASSERT(0 == cxMapRemoveAndGet(map, k3, &r));
320 CX_TEST_ASSERT(r.str == v3);
321 }
292 322
293 CX_TEST_ASSERT(0 == strcmp(v1, "val 1")); 323 CX_TEST_ASSERT(0 == strcmp(v1, "val 1"));
294 CX_TEST_ASSERT(0 == strcmp(v2, "OK")); 324 CX_TEST_ASSERT(0 == strcmp(v2, "OK"));
295 CX_TEST_ASSERT(0 == strcmp(v3, "val 3")); 325 CX_TEST_ASSERT(0 == strcmp(v3, "val 3"));
296 CX_TEST_ASSERT(0 == strcmp(v4, "val 4")); 326 CX_TEST_ASSERT(0 == strcmp(v4, "val 4"));
297 CX_TEST_ASSERT(0 == strcmp(v5, "val 5")); 327 CX_TEST_ASSERT(0 == strcmp(v5, "val 5"));
298 CX_TEST_ASSERT(r == v3); 328
299 329 // put k5, overwrite k1, put new k3
300 cxMapClear(map); 330 cxMapPut(map, k5, v5data);
301 331 cxMapPut(map, k1, v6data);
302 CX_TEST_ASSERT(0 == strcmp(v1, "val 1")); 332 cxMapPut(map, k3, v7data);
303 CX_TEST_ASSERT(0 == strcmp(v2, "OK")); 333
334 // destructor the value behind k1 was called, but for k3 not
335 CX_TEST_ASSERT(0 == strcmp(v1, "OK"));
304 CX_TEST_ASSERT(0 == strcmp(v3, "val 3")); 336 CX_TEST_ASSERT(0 == strcmp(v3, "val 3"));
305 CX_TEST_ASSERT(0 == strcmp(v4, "OK")); 337
306 CX_TEST_ASSERT(0 == strcmp(v5, "val 5")); 338 // now remove k1 via key iterator and k5 (val 5) via value iterator
307 339 v1[0] = 'y'; // mark v1 and check that destr is not called for previous val
308 cxMapPut(map, k1, (void *) v1);
309 cxMapPut(map, k3, (void *) v3);
310 cxMapPut(map, k5, (void *) v5);
311
312 { 340 {
313 CxIterator iter = cxMapMutIteratorKeys(map); 341 CxIterator iter = cxMapMutIteratorKeys(map);
314 cx_foreach(CxHashKey*, key, iter) { 342 cx_foreach(CxHashKey*, key, iter) {
315 if (((char*)key->data)[4] == '1') cxIteratorFlagRemoval(iter); 343 if (((char*)key->data)[4] == '1') cxIteratorFlagRemoval(iter);
316 } 344 }
317 } 345 }
318 { 346 {
319 CxIterator iter = cxMapMutIteratorValues(map); 347 CxIterator iter = cxMapMutIteratorValues(map);
320 cx_foreach(char*, v, iter) { 348 cx_foreach(struct test_destr_struct*, v, iter) {
321 if (v[4] == '5') cxIteratorFlagRemoval(iter); 349 if (v->str[4] == '5') cxIteratorFlagRemoval(iter);
322 } 350 }
323 } 351 }
324 352
325 CX_TEST_ASSERT(0 == strcmp(v1, "OK")); 353 CX_TEST_ASSERT(0 == strcmp(v1, "yK"));
326 CX_TEST_ASSERT(0 == strcmp(v2, "OK")); 354 CX_TEST_ASSERT(0 == strcmp(v2, "OK"));
327 CX_TEST_ASSERT(0 == strcmp(v3, "val 3")); 355 CX_TEST_ASSERT(0 == strcmp(v3, "val 3"));
328 CX_TEST_ASSERT(0 == strcmp(v4, "OK")); 356 CX_TEST_ASSERT(0 == strcmp(v4, "val 4"));
329 CX_TEST_ASSERT(0 == strcmp(v5, "OK")); 357 CX_TEST_ASSERT(0 == strcmp(v5, "OK"));
330 358 CX_TEST_ASSERT(0 == strcmp(v6, "OK"));
359 CX_TEST_ASSERT(0 == strcmp(v7, "val 7"));
360
361 // mark the already destroyed items
362 // and check that they are not destroyed again
331 v1[0] = v2[0] = v4[0] = v5[0] = 'c'; 363 v1[0] = v2[0] = v4[0] = v5[0] = 'c';
332 364
333 cxMapFree(map); 365 cxMapFree(map);
334 366
335 CX_TEST_ASSERT(0 == strcmp(v1, "cK")); 367 CX_TEST_ASSERT(0 == strcmp(v1, "cK"));
336 CX_TEST_ASSERT(0 == strcmp(v2, "cK")); 368 CX_TEST_ASSERT(0 == strcmp(v2, "cK"));
337 CX_TEST_ASSERT(0 == strcmp(v3, "OK")); 369 CX_TEST_ASSERT(0 == strcmp(v3, "val 3"));
338 CX_TEST_ASSERT(0 == strcmp(v4, "cK")); 370 CX_TEST_ASSERT(0 == strcmp(v4, "OK"));
339 CX_TEST_ASSERT(0 == strcmp(v5, "cK")); 371 CX_TEST_ASSERT(0 == strcmp(v5, "cK"));
340 } 372 CX_TEST_ASSERT(0 == strcmp(v6, "OK"));
341 373 CX_TEST_ASSERT(0 == strcmp(v7, "OK"));
342 CX_TEST(test_hash_map_simple_destructor) { 374 }
375
376 CX_TEST(test_hash_map_simple_destructor_objects) {
377 CxTestingAllocator talloc;
378 cx_testing_allocator_init(&talloc);
379 CxAllocator *allocator = &talloc.base;
380 CX_TEST_DO {
381 CxMap *map = cxHashMapCreate(allocator,
382 sizeof(struct test_destr_struct), 0);
383 map->collection.simple_destructor = test_simple_destructor;
384 CX_TEST_CALL_SUBROUTINE(verify_any_destructor, map);
385 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
386 }
387 cx_testing_allocator_destroy(&talloc);
388 }
389
390 CX_TEST(test_hash_map_advanced_destructor_objects) {
391 CxTestingAllocator talloc;
392 cx_testing_allocator_init(&talloc);
393 CxAllocator *allocator = &talloc.base;
394 CX_TEST_DO {
395 CxMap *map = cxHashMapCreate(allocator,
396 sizeof(struct test_destr_struct), 0);
397 map->collection.advanced_destructor = test_advanced_destructor;
398 CX_TEST_CALL_SUBROUTINE(verify_any_destructor, map);
399 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
400 }
401 cx_testing_allocator_destroy(&talloc);
402 }
403
404 CX_TEST(test_hash_map_simple_destructor_pointers) {
343 CxTestingAllocator talloc; 405 CxTestingAllocator talloc;
344 cx_testing_allocator_init(&talloc); 406 cx_testing_allocator_init(&talloc);
345 CxAllocator *allocator = &talloc.base; 407 CxAllocator *allocator = &talloc.base;
346 CX_TEST_DO { 408 CX_TEST_DO {
347 CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0); 409 CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0);
350 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); 412 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
351 } 413 }
352 cx_testing_allocator_destroy(&talloc); 414 cx_testing_allocator_destroy(&talloc);
353 } 415 }
354 416
355 CX_TEST(test_hash_map_advanced_destructor) { 417 CX_TEST(test_hash_map_advanced_destructor_pointers) {
356 CxTestingAllocator talloc; 418 CxTestingAllocator talloc;
357 cx_testing_allocator_init(&talloc); 419 cx_testing_allocator_init(&talloc);
358 CxAllocator *allocator = &talloc.base; 420 CxAllocator *allocator = &talloc.base;
359 CX_TEST_DO { 421 CX_TEST_DO {
360 CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0); 422 CxMap *map = cxHashMapCreate(allocator, CX_STORE_POINTERS, 0);
672 cx_test_register(suite, test_hash_map_rehash); 734 cx_test_register(suite, test_hash_map_rehash);
673 cx_test_register(suite, test_hash_map_rehash_not_required); 735 cx_test_register(suite, test_hash_map_rehash_not_required);
674 cx_test_register(suite, test_hash_map_clear); 736 cx_test_register(suite, test_hash_map_clear);
675 cx_test_register(suite, test_hash_map_store_ucx_strings); 737 cx_test_register(suite, test_hash_map_store_ucx_strings);
676 cx_test_register(suite, test_hash_map_remove_via_iterator); 738 cx_test_register(suite, test_hash_map_remove_via_iterator);
739 cx_test_register(suite, test_hash_map_simple_destructor_objects);
740 cx_test_register(suite, test_hash_map_advanced_destructor_objects);
741 cx_test_register(suite, test_hash_map_simple_destructor_pointers);
742 cx_test_register(suite, test_hash_map_advanced_destructor_pointers);
677 cx_test_register(suite, test_empty_map_no_ops); 743 cx_test_register(suite, test_empty_map_no_ops);
678 cx_test_register(suite, test_empty_map_size); 744 cx_test_register(suite, test_empty_map_size);
679 cx_test_register(suite, test_empty_map_get); 745 cx_test_register(suite, test_empty_map_get);
680 cx_test_register(suite, test_empty_map_iterator); 746 cx_test_register(suite, test_empty_map_iterator);
681 cx_test_register(suite, test_hash_map_generics); 747 cx_test_register(suite, test_hash_map_generics);

mercurial