Annotation of embedaddon/strongswan/src/libstrongswan/tests/suites/test_hashtable.c, revision 1.1.1.2

1.1       misho       1: /*
1.1.1.2 ! misho       2:  * Copyright (C) 2010-2020 Tobias Brunner
1.1       misho       3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "test_suite.h"
                     17: 
                     18: #include <collections/hashtable.h>
                     19: #include <utils/chunk.h>
                     20: 
                     21: /*******************************************************************************
1.1.1.2 ! misho      22:  * hash table functions
1.1       misho      23:  */
                     24: 
1.1.1.2 ! misho      25: static u_int hash_match(char *key)
1.1       misho      26: {
1.1.1.2 ! misho      27:        return chunk_hash(chunk_create(key, 4));
1.1       misho      28: }
                     29: 
1.1.1.2 ! misho      30: static bool equal_match(char *key1, char *key2)
1.1       misho      31: {
1.1.1.2 ! misho      32:        if (!strneq(key1, key2, 4))
        !            33:        {
        !            34:                return FALSE;
        !            35:        }
        !            36:        /* look for an item with a key < than what we look for */
        !            37:        return strcmp(key1, key2) >= 0;
1.1       misho      38: }
                     39: 
                     40: /*******************************************************************************
                     41:  * test fixture
                     42:  */
                     43: 
                     44: static hashtable_t *ht;
                     45: 
1.1.1.2 ! misho      46: typedef enum {
        !            47:        /* regular string hash table */
        !            48:        HASHTABLE_REGULAR,
        !            49:        /* regular string hash list */
        !            50:        HASHLIST_REGULAR,
        !            51:        /* sorted string hash list */
        !            52:        HASHLIST_REGULAR_SORTED,
        !            53:        REGULAR_MAX,
        !            54:        /* hash table with only 4 characters hashed -> one bucket tests */
        !            55:        HASHTABLE_FUZZY = REGULAR_MAX,
        !            56:        /* hash list with only 4 characters hashed */
        !            57:        HASHLIST_FUZZY,
        !            58:        /* sorted string hash list with only 4 characters hashed */
        !            59:        HASHLIST_FUZZY_SORTED,
        !            60:        HASHTABLE_MAX,
        !            61: } hashtable_type_t;
        !            62: 
        !            63: /**
        !            64:  * Create a specific hash table/list
        !            65:  */
        !            66: static hashtable_t *create_hashtable(int i)
1.1       misho      67: {
1.1.1.2 ! misho      68:        hashlist_t *hl = NULL;
        !            69: 
        !            70:        DESTROY_IF(ht);
        !            71: 
        !            72:        switch (i)
        !            73:        {
        !            74:                case HASHTABLE_REGULAR:
        !            75:                        ht = hashtable_create(hashtable_hash_str,
        !            76:                                                                  hashtable_equals_str, 0);
        !            77:                        break;
        !            78:                case HASHLIST_REGULAR:
        !            79:                        hl = hashlist_create(hashtable_hash_str,
        !            80:                                                                 hashtable_equals_str, 0);
        !            81:                        break;
        !            82:                case HASHLIST_REGULAR_SORTED:
        !            83:                        hl = hashlist_create_sorted(hashtable_hash_str,
        !            84:                                                                           (hashtable_cmp_t)strcmp, 0);
        !            85:                        break;
        !            86:                case HASHTABLE_FUZZY:
        !            87:                        ht = hashtable_create((hashtable_hash_t)hash_match,
        !            88:                                                                  hashtable_equals_str, 0);
        !            89:                        break;
        !            90:                case HASHLIST_FUZZY:
        !            91:                        hl = hashlist_create((hashtable_hash_t)hash_match,
        !            92:                                                                 hashtable_equals_str, 0);
        !            93:                        break;
        !            94:                case HASHLIST_FUZZY_SORTED:
        !            95:                        hl = hashlist_create_sorted((hashtable_hash_t)hash_match,
        !            96:                                                                                (hashtable_cmp_t)strcmp, 0);
        !            97:                        break;
        !            98:        }
        !            99:        if (hl)
        !           100:        {
        !           101:                ht = &hl->ht;
        !           102:        }
1.1       misho     103:        ck_assert_int_eq(ht->get_count(ht), 0);
1.1.1.2 ! misho     104:        return ht;
        !           105: }
        !           106: 
        !           107: START_SETUP(setup_ht)
        !           108: {
        !           109:        create_hashtable(_i);
1.1       misho     110: }
                    111: END_SETUP
                    112: 
                    113: START_TEARDOWN(teardown_ht)
                    114: {
                    115:        ht->destroy(ht);
1.1.1.2 ! misho     116:        ht = NULL;
1.1       misho     117: }
                    118: END_TEARDOWN
                    119: 
                    120: /*******************************************************************************
                    121:  * put/get
                    122:  */
                    123: 
                    124: START_TEST(test_put_get)
                    125: {
                    126:        char *k1 = "key1", *k2 = "key2", *k3 = "key3";
                    127:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
                    128: 
                    129:        value = ht->put(ht, k1, v1);
                    130:        ck_assert_int_eq(ht->get_count(ht), 1);
                    131:        ck_assert(streq(ht->get(ht, k1), v1));
                    132:        ck_assert(ht->get(ht, k2) == NULL);
                    133:        ck_assert(ht->get(ht, k3) == NULL);
                    134:        ck_assert(value == NULL);
                    135: 
                    136:        ht->put(ht, k2, v2);
                    137:        ht->put(ht, k3, v3);
                    138:        ck_assert_int_eq(ht->get_count(ht), 3);
                    139:        ck_assert(streq(ht->get(ht, k1), v1));
                    140:        ck_assert(streq(ht->get(ht, k2), v2));
                    141:        ck_assert(streq(ht->get(ht, k3), v3));
                    142: 
                    143:        value = ht->put(ht, k2, v1);
                    144:        ck_assert_int_eq(ht->get_count(ht), 3);
                    145:        ck_assert(streq(value, v2));
                    146:        ck_assert(streq(ht->get(ht, k2), v1));
                    147: }
                    148: END_TEST
                    149: 
                    150: /*******************************************************************************
                    151:  * get_match
                    152:  */
                    153: 
                    154: START_TEST(test_get_match)
                    155: {
1.1.1.2 ! misho     156:        hashlist_t *hl;
1.1       misho     157:        char *k1 = "key1_a", *k2 = "key2", *k3 = "key1_b", *k4 = "key1_c";
                    158:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
                    159: 
1.1.1.2 ! misho     160:        hl = (hashlist_t*)create_hashtable(HASHLIST_FUZZY);
1.1       misho     161: 
                    162:        ht->put(ht, k1, v1);
                    163:        ht->put(ht, k2, v2);
                    164:        value = ht->put(ht, k3, v3);
                    165:        ck_assert_int_eq(ht->get_count(ht), 3);
                    166:        ck_assert(streq(ht->get(ht, k1), v1));
                    167:        ck_assert(streq(ht->get(ht, k2), v2));
                    168:        ck_assert(streq(ht->get(ht, k3), v3));
                    169:        ck_assert(value == NULL);
                    170: 
1.1.1.2 ! misho     171:        value = hl->get_match(hl, k1, (hashtable_equals_t)equal_match);
1.1       misho     172:        ck_assert(value != NULL);
                    173:        ck_assert(streq(value, v1));
1.1.1.2 ! misho     174:        value = hl->get_match(hl, k2, (hashtable_equals_t)equal_match);
1.1       misho     175:        ck_assert(value != NULL);
                    176:        ck_assert(streq(value, v2));
1.1.1.2 ! misho     177:        value = hl->get_match(hl, k3, (hashtable_equals_t)equal_match);
1.1       misho     178:        ck_assert(value != NULL);
                    179:        ck_assert(streq(value, v1));
1.1.1.2 ! misho     180:        value = hl->get_match(hl, k4, (hashtable_equals_t)equal_match);
1.1       misho     181:        ck_assert(value != NULL);
                    182:        ck_assert(streq(value, v1));
1.1.1.2 ! misho     183: }
        !           184: END_TEST
1.1       misho     185: 
1.1.1.2 ! misho     186: START_TEST(test_get_match_remove)
        !           187: {
        !           188:        hashlist_t *hl;
        !           189:        char *k1 = "key1_a", *k2 = "key2", *k3 = "key1_b", *k4 = "key1_c";
        !           190:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
        !           191: 
        !           192:        hl = (hashlist_t*)create_hashtable(HASHLIST_FUZZY);
        !           193: 
        !           194:        /* by removing and reinserting the first item we verify that insertion
        !           195:         * order is adhered */
        !           196:        ht->put(ht, k1, v1);
        !           197:        ht->put(ht, k2, v2);
        !           198:        ht->put(ht, k3, v3);
        !           199:        ht->remove(ht, k1);
        !           200:        ht->put(ht, k1, v1);
        !           201:        ck_assert_int_eq(ht->get_count(ht), 3);
        !           202:        ck_assert(streq(ht->get(ht, k1), v1));
        !           203:        ck_assert(streq(ht->get(ht, k2), v2));
        !           204:        ck_assert(streq(ht->get(ht, k3), v3));
        !           205: 
        !           206:        value = hl->get_match(hl, k1, (hashtable_equals_t)equal_match);
        !           207:        ck_assert(value != NULL);
        !           208:        ck_assert(streq(value, v1));
        !           209:        value = hl->get_match(hl, k2, (hashtable_equals_t)equal_match);
        !           210:        ck_assert(value != NULL);
        !           211:        ck_assert(streq(value, v2));
        !           212:        value = hl->get_match(hl, k3, (hashtable_equals_t)equal_match);
        !           213:        ck_assert(value != NULL);
        !           214:        ck_assert(streq(value, v3));
        !           215:        value = hl->get_match(hl, k4, (hashtable_equals_t)equal_match);
        !           216:        ck_assert(value != NULL);
        !           217:        ck_assert(streq(value, v3));
        !           218: }
        !           219: END_TEST
        !           220: 
        !           221: START_TEST(test_get_match_sorted)
        !           222: {
        !           223:        hashlist_t *hl;
        !           224:        char *k1 = "key1_a", *k2 = "key2", *k3 = "key1_b", *k4 = "key1_c";
        !           225:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
        !           226: 
        !           227:        hl = (hashlist_t*)create_hashtable(HASHLIST_FUZZY_SORTED);
        !           228: 
        !           229:        /* since the keys are sorted, the insertion order doesn't matter */
        !           230:        ht->put(ht, k3, v3);
        !           231:        ht->put(ht, k2, v2);
        !           232:        ht->put(ht, k1, v1);
        !           233:        ht->put(ht, k4, v1);
        !           234:        ht->remove(ht, k1);
        !           235:        ht->put(ht, k1, v1);
        !           236:        ck_assert_int_eq(ht->get_count(ht), 4);
        !           237:        ck_assert(streq(ht->get(ht, k1), v1));
        !           238:        ck_assert(streq(ht->get(ht, k2), v2));
        !           239:        ck_assert(streq(ht->get(ht, k3), v3));
        !           240:        ck_assert(streq(ht->get(ht, k4), v1));
        !           241: 
        !           242:        value = hl->get_match(hl, k1, (hashtable_equals_t)equal_match);
        !           243:        ck_assert(value != NULL);
        !           244:        ck_assert(streq(value, v1));
        !           245:        value = hl->get_match(hl, k2, (hashtable_equals_t)equal_match);
        !           246:        ck_assert(value != NULL);
        !           247:        ck_assert(streq(value, v2));
        !           248:        value = hl->get_match(hl, k3, (hashtable_equals_t)equal_match);
        !           249:        ck_assert(value != NULL);
        !           250:        ck_assert(streq(value, v1));
        !           251:        value = hl->get_match(hl, k4, (hashtable_equals_t)equal_match);
        !           252:        ck_assert(value != NULL);
        !           253:        ck_assert(streq(value, v1));
1.1       misho     254: }
                    255: END_TEST
                    256: 
                    257: /*******************************************************************************
                    258:  * remove
                    259:  */
                    260: 
                    261: static void do_remove(char *k1, char *k2, char *k3)
                    262: {
                    263:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
                    264: 
                    265:        ht->put(ht, k1, v1);
                    266:        ht->put(ht, k2, v2);
                    267:        ht->put(ht, k3, v3);
                    268: 
                    269:        value = ht->remove(ht, k2);
                    270:        ck_assert_int_eq(ht->get_count(ht), 2);
                    271:        ck_assert(streq(ht->get(ht, k1), v1));
                    272:        ck_assert(streq(ht->get(ht, k3), v3));
                    273:        ck_assert(streq(value, v2));
                    274:        ck_assert(ht->get(ht, k2) == NULL);
                    275: 
                    276:        value = ht->remove(ht, k2);
                    277:        ck_assert_int_eq(ht->get_count(ht), 2);
                    278:        ck_assert(value == NULL);
                    279: 
                    280:        value = ht->remove(ht, k1);
                    281:        value = ht->remove(ht, k3);
                    282:        ck_assert_int_eq(ht->get_count(ht), 0);
                    283:        ck_assert(ht->get(ht, k1) == NULL);
                    284:        ck_assert(ht->get(ht, k2) == NULL);
                    285:        ck_assert(ht->get(ht, k3) == NULL);
                    286: }
                    287: 
                    288: START_TEST(test_remove)
                    289: {
                    290:        char *k1 = "key1", *k2 = "key2", *k3 = "key3";
                    291: 
                    292:        do_remove(k1, k2, k3);
1.1.1.2 ! misho     293:        do_remove(k3, k2, k1);
        !           294:        do_remove(k1, k3, k2);
1.1       misho     295: }
                    296: END_TEST
                    297: 
                    298: START_TEST(test_remove_one_bucket)
                    299: {
                    300:        char *k1 = "key1_a", *k2 = "key1_b", *k3 = "key1_c";
                    301: 
                    302:        do_remove(k1, k2, k3);
1.1.1.2 ! misho     303:        do_remove(k3, k2, k1);
        !           304:        do_remove(k1, k3, k2);
1.1       misho     305: }
                    306: END_TEST
                    307: 
                    308: /*******************************************************************************
                    309:  * enumerator
                    310:  */
                    311: 
                    312: START_TEST(test_enumerator)
                    313: {
                    314:        char *k1 = "key1", *k2 = "key2", *k3 = "key3", *key;
                    315:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value;
                    316:        enumerator_t *enumerator;
                    317:        int count;
                    318: 
                    319:        ht->put(ht, k1, v1);
                    320:        ht->put(ht, k2, v2);
                    321:        ht->put(ht, k3, v3);
                    322: 
                    323:        count = 0;
                    324:        enumerator = ht->create_enumerator(ht);
                    325:        while (enumerator->enumerate(enumerator, &key, &value))
                    326:        {
                    327:                ck_assert(streq(key, k1) || streq(key, k2) || streq(key, k3));
                    328:                ck_assert(streq(value, v1) || streq(value, v2) || streq(value, v3));
                    329:                ck_assert(!streq(key, k1) || streq(value, v1));
                    330:                ck_assert(!streq(key, k2) || streq(value, v2));
                    331:                ck_assert(!streq(key, k3) || streq(value, v3));
                    332:                count++;
                    333:        }
                    334:        enumerator->destroy(enumerator);
                    335:        ck_assert_int_eq(count, 3);
                    336: 
                    337:        count = 0;
                    338:        enumerator = ht->create_enumerator(ht);
                    339:        while (enumerator->enumerate(enumerator, NULL, NULL))
                    340:        {
                    341:                count++;
                    342:        }
                    343:        enumerator->destroy(enumerator);
                    344:        ck_assert_int_eq(count, 3);
                    345: 
                    346:        value = ht->remove(ht, k1);
                    347:        value = ht->remove(ht, k2);
                    348:        value = ht->remove(ht, k3);
                    349: 
                    350:        count = 0;
                    351:        enumerator = ht->create_enumerator(ht);
                    352:        while (enumerator->enumerate(enumerator, &key, &value))
                    353:        {
                    354:                count++;
                    355:        }
                    356:        enumerator->destroy(enumerator);
                    357:        ck_assert_int_eq(count, 0);
                    358: }
                    359: END_TEST
                    360: 
1.1.1.2 ! misho     361: START_TEST(test_enumerator_order)
        !           362: {
        !           363:        char *k1 = "key1", *k2 = "key2", *k3 = "key3", *key;
        !           364:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *v4 = "val4", *value;
        !           365:        enumerator_t *enumerator;
        !           366:        int count;
        !           367: 
        !           368:        ht->put(ht, k1, v1);
        !           369:        ht->put(ht, k2, v2);
        !           370:        ht->put(ht, k3, v3);
        !           371: 
        !           372:        count = 0;
        !           373:        enumerator = ht->create_enumerator(ht);
        !           374:        while (enumerator->enumerate(enumerator, &key, &value))
        !           375:        {
        !           376:                switch (count)
        !           377:                {
        !           378:                        case 0:
        !           379:                                ck_assert(streq(key, k1) && streq(value, v1));
        !           380:                                break;
        !           381:                        case 1:
        !           382:                                ck_assert(streq(key, k2) && streq(value, v2));
        !           383:                                break;
        !           384:                        case 2:
        !           385:                                ck_assert(streq(key, k3) && streq(value, v3));
        !           386:                                break;
        !           387:                }
        !           388:                count++;
        !           389:        }
        !           390:        enumerator->destroy(enumerator);
        !           391:        ck_assert_int_eq(count, 3);
        !           392: 
        !           393:        value = ht->remove(ht, k2);
        !           394:        ht->put(ht, k2, v2);
        !           395:        ht->put(ht, k1, v4);
        !           396: 
        !           397:        count = 0;
        !           398:        enumerator = ht->create_enumerator(ht);
        !           399:        while (enumerator->enumerate(enumerator, &key, &value))
        !           400:        {
        !           401:                switch (count)
        !           402:                {
        !           403:                        case 0:
        !           404:                                ck_assert(streq(key, k1) && streq(value, v4));
        !           405:                                break;
        !           406:                        case 1:
        !           407:                                ck_assert(streq(key, k3) && streq(value, v3));
        !           408:                                break;
        !           409:                        case 2:
        !           410:                                ck_assert(streq(key, k2) && streq(value, v2));
        !           411:                                break;
        !           412:                }
        !           413:                count++;
        !           414:        }
        !           415:        enumerator->destroy(enumerator);
        !           416:        ck_assert_int_eq(count, 3);
        !           417: }
        !           418: END_TEST
        !           419: 
1.1       misho     420: /*******************************************************************************
                    421:  * remove_at
                    422:  */
                    423: 
                    424: static void do_remove_at(char *k1, char *k2, char *k3)
                    425: {
                    426:        char *v1 = "val1", *v2 = "val2", *v3 = "val3", *value, *key;
                    427:        enumerator_t *enumerator;
                    428: 
                    429:        ht->put(ht, k1, v1);
                    430:        ht->put(ht, k2, v2);
                    431:        ht->put(ht, k3, v3);
                    432: 
                    433:        enumerator = ht->create_enumerator(ht);
                    434:        ht->remove_at(ht, enumerator);
                    435:        while (enumerator->enumerate(enumerator, &key, &value))
                    436:        {
                    437:                if (streq(key, k2))
                    438:                {
                    439:                        ht->remove_at(ht, enumerator);
                    440:                }
                    441:        }
                    442:        enumerator->destroy(enumerator);
                    443: 
                    444:        ck_assert_int_eq(ht->get_count(ht), 2);
                    445:        ck_assert(ht->get(ht, k1) != NULL);
                    446:        ck_assert(ht->get(ht, k3) != NULL);
                    447:        ck_assert(ht->get(ht, k2) == NULL);
                    448: 
                    449:        ht->put(ht, k2, v2);
                    450: 
                    451:        ck_assert_int_eq(ht->get_count(ht), 3);
                    452:        ck_assert(ht->get(ht, k1) != NULL);
                    453:        ck_assert(ht->get(ht, k2) != NULL);
                    454:        ck_assert(ht->get(ht, k3) != NULL);
                    455: 
                    456:        enumerator = ht->create_enumerator(ht);
                    457:        while (enumerator->enumerate(enumerator, &key, &value))
                    458:        {
                    459:                ht->remove_at(ht, enumerator);
                    460:        }
                    461:        enumerator->destroy(enumerator);
                    462: 
                    463:        ck_assert_int_eq(ht->get_count(ht), 0);
                    464:        ck_assert(ht->get(ht, k1) == NULL);
                    465:        ck_assert(ht->get(ht, k2) == NULL);
                    466:        ck_assert(ht->get(ht, k3) == NULL);
                    467: }
                    468: 
                    469: START_TEST(test_remove_at)
                    470: {
                    471:        char *k1 = "key1", *k2 = "key2", *k3 = "key3";
                    472: 
                    473:        do_remove_at(k1, k2, k3);
                    474: }
                    475: END_TEST
                    476: 
                    477: START_TEST(test_remove_at_one_bucket)
                    478: {
                    479:        char *k1 = "key1_a", *k2 = "key1_b", *k3 = "key1_c";
                    480: 
                    481:        do_remove_at(k1, k2, k3);
                    482: }
                    483: END_TEST
                    484: 
1.1.1.2 ! misho     485: /*******************************************************************************
        !           486:  * many items
        !           487:  */
        !           488: 
        !           489: static u_int hash_int(int *key)
        !           490: {
        !           491:        return chunk_hash(chunk_create((u_char*)key, sizeof(int)));
        !           492: }
        !           493: 
        !           494: static bool equals_int(int *key1, int *key2)
        !           495: {
        !           496:        return *key1 == *key2;
        !           497: }
        !           498: 
        !           499: static int cmp_int(int *key1, int *key2)
        !           500: {
        !           501:        return *key1 - *key2;
        !           502: }
        !           503: 
        !           504: /**
        !           505:  * Create a specific hash table with integers as keys.
        !           506:  */
        !           507: static hashtable_t *create_int_hashtable(int i)
        !           508: {
        !           509:        hashlist_t *hl = NULL;
        !           510: 
        !           511:        DESTROY_IF(ht);
        !           512: 
        !           513:        switch (i)
        !           514:        {
        !           515:                case HASHTABLE_REGULAR:
        !           516:                        ht = hashtable_create((hashtable_hash_t)hash_int,
        !           517:                                                                  (hashtable_equals_t)equals_int, 0);
        !           518:                        break;
        !           519:                case HASHLIST_REGULAR:
        !           520:                        hl = hashlist_create((hashtable_hash_t)hash_int,
        !           521:                                                                 (hashtable_equals_t)equals_int, 0);
        !           522:                        break;
        !           523:                case HASHLIST_REGULAR_SORTED:
        !           524:                        hl = hashlist_create_sorted((hashtable_hash_t)hash_int,
        !           525:                                                                                (hashtable_cmp_t)cmp_int, 0);
        !           526:                        break;
        !           527:        }
        !           528:        if (hl)
        !           529:        {
        !           530:                ht = &hl->ht;
        !           531:        }
        !           532:        ck_assert_int_eq(ht->get_count(ht), 0);
        !           533:        return ht;
        !           534: }
        !           535: 
        !           536: START_SETUP(setup_ht_many)
        !           537: {
        !           538:        create_int_hashtable(_i >> 1);
        !           539: }
        !           540: END_SETUP
        !           541: 
        !           542: START_SETUP(setup_ht_lookups)
        !           543: {
        !           544:        create_int_hashtable(_i);
        !           545: }
        !           546: END_SETUP
        !           547: 
        !           548: START_TEARDOWN(teardown_ht_many)
        !           549: {
        !           550:        ht->destroy_function(ht, (void*)free);
        !           551:        ht = NULL;
        !           552: }
        !           553: END_TEARDOWN
        !           554: 
        !           555: START_TEST(test_many_items)
        !           556: {
        !           557:        u_int count = 100000;
        !           558:        int i, *val, r;
        !           559: 
        !           560: #define GET_VALUE(i) ({ (_i % 2) == 0 ? i : (count-1-i); })
        !           561: 
        !           562:        for (i = 0; i < count; i++)
        !           563:        {
        !           564:                val = malloc_thing(int);
        !           565:                *val = GET_VALUE(i);
        !           566:                ht->put(ht, val, val);
        !           567:        }
        !           568:        for (i = 0; i < count; i++)
        !           569:        {
        !           570:                r = GET_VALUE(i);
        !           571:                val = ht->get(ht, &r);
        !           572:                ck_assert_int_eq(GET_VALUE(i), *val);
        !           573:        }
        !           574:        ck_assert_int_eq(count, ht->get_count(ht));
        !           575:        for (i = 0; i < count; i++)
        !           576:        {
        !           577:                r = GET_VALUE(i);
        !           578:                free(ht->remove(ht, &r));
        !           579:        }
        !           580:        ck_assert_int_eq(0, ht->get_count(ht));
        !           581:        for (i = 0; i < count; i++)
        !           582:        {
        !           583:                val = malloc_thing(int);
        !           584:                *val = GET_VALUE(i);
        !           585:                ht->put(ht, val, val);
        !           586:        }
        !           587:        for (i = 0; i < count/2; i++)
        !           588:        {
        !           589:                free(ht->remove(ht, &i));
        !           590:        }
        !           591:        ck_assert_int_eq(count/2, ht->get_count(ht));
        !           592:        for (i = 0; i < count; i++)
        !           593:        {
        !           594:                val = malloc_thing(int);
        !           595:                *val = GET_VALUE(i);
        !           596:                free(ht->put(ht, val, val));
        !           597:        }
        !           598:        srandom(666);
        !           599:        for (i = 0; i < count; i++)
        !           600:        {
        !           601:                r = random() % count;
        !           602:                ht->get(ht, &r);
        !           603:        }
        !           604:        for (i = 0; i < count; i++)
        !           605:        {
        !           606:                free(ht->remove(ht, &i));
        !           607:        }
        !           608:        ck_assert_int_eq(0, ht->get_count(ht));
        !           609:        for (i = 0; i < 2*count; i++)
        !           610:        {
        !           611:                val = malloc_thing(int);
        !           612:                *val = i;
        !           613:                ht->put(ht, val, val);
        !           614:                free(ht->remove(ht, val));
        !           615:        }
        !           616: }
        !           617: END_TEST
        !           618: 
        !           619: START_TEST(test_many_lookups_success)
        !           620: {
        !           621:        u_int count = 25000, lookups = 1000000;
        !           622:        int i, *val, r;
        !           623: 
        !           624:        for (i = 0; i < count; i++)
        !           625:        {
        !           626:                val = malloc_thing(int);
        !           627:                *val = i;
        !           628:                ht->put(ht, val, val);
        !           629:        }
        !           630:        srandom(666);
        !           631:        for (i = 0; i < lookups; i++)
        !           632:        {
        !           633:                r = random() % count;
        !           634:                ht->get(ht, &r);
        !           635:        }
        !           636: }
        !           637: END_TEST
        !           638: 
        !           639: START_TEST(test_many_lookups_failure_larger)
        !           640: {
        !           641:        u_int count = 25000, lookups = 1000000;
        !           642:        int i, *val, r;
        !           643: 
        !           644:        for (i = 0; i < count; i++)
        !           645:        {
        !           646:                val = malloc_thing(int);
        !           647:                *val = i;
        !           648:                ht->put(ht, val, val);
        !           649:        }
        !           650:        srandom(666);
        !           651:        for (i = 0; i < lookups; i++)
        !           652:        {
        !           653:                r = random() % count + count;
        !           654:                ht->get(ht, &r);
        !           655:        }
        !           656: }
        !           657: END_TEST
        !           658: 
        !           659: START_TEST(test_many_lookups_failure_smaller)
        !           660: {
        !           661:        u_int count = 25000, lookups = 1000000;
        !           662:        int i, *val, r;
        !           663: 
        !           664:        for (i = 0; i < count; i++)
        !           665:        {
        !           666:                val = malloc_thing(int);
        !           667:                *val = i + count;
        !           668:                ht->put(ht, val, val);
        !           669:        }
        !           670:        srandom(666);
        !           671:        for (i = 0; i < lookups; i++)
        !           672:        {
        !           673:                r = random() % count;
        !           674:                ht->get(ht, &r);
        !           675:        }
        !           676: }
        !           677: END_TEST
        !           678: 
1.1       misho     679: Suite *hashtable_suite_create()
                    680: {
                    681:        Suite *s;
                    682:        TCase *tc;
                    683: 
                    684:        s = suite_create("hashtable");
                    685: 
                    686:        tc = tcase_create("put/get");
                    687:        tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
1.1.1.2 ! misho     688:        tcase_add_loop_test(tc, test_put_get, 0, HASHTABLE_MAX);
1.1       misho     689:        suite_add_tcase(s, tc);
                    690: 
                    691:        tc = tcase_create("get_match");
1.1.1.2 ! misho     692:        tcase_add_checked_fixture(tc, NULL, teardown_ht);
1.1       misho     693:        tcase_add_test(tc, test_get_match);
1.1.1.2 ! misho     694:        tcase_add_test(tc, test_get_match_remove);
        !           695:        tcase_add_test(tc, test_get_match_sorted);
1.1       misho     696:        suite_add_tcase(s, tc);
                    697: 
                    698:        tc = tcase_create("remove");
                    699:        tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
1.1.1.2 ! misho     700:        tcase_add_loop_test(tc, test_remove, 0, REGULAR_MAX);
        !           701:        tcase_add_loop_test(tc, test_remove_one_bucket, HASHTABLE_FUZZY, HASHTABLE_MAX);
1.1       misho     702:        suite_add_tcase(s, tc);
                    703: 
                    704:        tc = tcase_create("enumerator");
                    705:        tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
1.1.1.2 ! misho     706:        tcase_add_loop_test(tc, test_enumerator, 0, HASHTABLE_MAX);
        !           707:        tcase_add_test(tc, test_enumerator_order);
1.1       misho     708:        suite_add_tcase(s, tc);
                    709: 
                    710:        tc = tcase_create("remove_at");
                    711:        tcase_add_checked_fixture(tc, setup_ht, teardown_ht);
1.1.1.2 ! misho     712:        tcase_add_loop_test(tc, test_remove_at, 0, REGULAR_MAX);
        !           713:        tcase_add_loop_test(tc, test_remove_at_one_bucket, HASHTABLE_FUZZY, HASHTABLE_MAX);
        !           714:        suite_add_tcase(s, tc);
        !           715: 
        !           716:        tc = tcase_create("many items");
        !           717:        tcase_add_checked_fixture(tc, setup_ht_many, teardown_ht_many);
        !           718:        tcase_set_timeout(tc, 10);
        !           719:        tcase_add_loop_test(tc, test_many_items, 0, REGULAR_MAX << 1);
        !           720:        suite_add_tcase(s, tc);
        !           721: 
        !           722:        tc = tcase_create("many lookups");
        !           723:        tcase_add_checked_fixture(tc, setup_ht_lookups, teardown_ht_many);
        !           724:        tcase_add_loop_test(tc, test_many_lookups_success, 0, REGULAR_MAX);
        !           725:        tcase_add_loop_test(tc, test_many_lookups_failure_larger, 0, REGULAR_MAX);
        !           726:        tcase_add_loop_test(tc, test_many_lookups_failure_smaller, 0, REGULAR_MAX);
1.1       misho     727:        suite_add_tcase(s, tc);
                    728: 
                    729:        return s;
                    730: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>