2 ** Copyright (C) 2002 by Kevin L. Mitchell <klmitch@mit.edu>
4 ** This library is free software; you can redistribute it and/or
5 ** modify it under the terms of the GNU Library General Public
6 ** License as published by the Free Software Foundation; either
7 ** version 2 of the License, or (at your option) any later version.
9 ** This library is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ** Library General Public License for more details.
14 ** You should have received a copy of the GNU Library General Public
15 ** License along with this library; if not, write to the Free
16 ** Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include "dbprim_int.h"
27 #define TABLE0 (void *)0x76543210
28 #define TABLE1 (void *)0x87654321
30 #define OBJECT0 (void *)0x01234567
31 #define OBJECT1 (void *)0x12345678
32 #define OBJECT2 (void *)0x23456789
33 #define OBJECT3 (void *)0x3456789a
34 #define OBJECT4 (void *)0x456789ab
35 #define OBJECT5 (void *)0x56789abc
37 #define DEADINT 0xdeadbeef
38 #define DEADPTR (void *)0xdeadbeef
40 /* Check return value of add operation and report PASS/FAIL */
42 check_result(unsigned long result, unsigned long expected, char *test,
45 if (result != expected) {
46 printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
51 printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
55 check_func(hash_table_t *table, db_key_t *key)
61 check_comp(hash_table_t *table, db_key_t *key1, db_key_t *key2)
63 return (!(dk_len(key1) == dk_len(key2) && dk_key(key1) == dk_key(key2)));
67 main(int argc, char **argv)
69 hash_table_t table[] = { /* some tables to operate on */
70 HASH_TABLE_INIT(0, check_func, check_comp, 0, TABLE0),
71 HASH_TABLE_INIT(0, check_func, check_comp, 0, TABLE1),
72 { DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADPTR,
73 (hash_func_t)DEADPTR, (hash_comp_t)DEADPTR, (hash_resize_t)DEADPTR,
74 DEADPTR } /* table[2] */
76 hash_entry_t entry[] = { /* some entries to operate on */
77 HASH_ENTRY_INIT(OBJECT0),
78 HASH_ENTRY_INIT(OBJECT1),
79 HASH_ENTRY_INIT(OBJECT2),
80 HASH_ENTRY_INIT(OBJECT3),
81 HASH_ENTRY_INIT(OBJECT4),
82 HASH_ENTRY_INIT(OBJECT5),
83 { DEADINT, { DEADINT, DEADPTR, DEADPTR, DEADPTR, DEADPTR, DEADINT },
84 DEADPTR, DEADINT, { DEADPTR, DEADINT }, DEADPTR } /* entry[6] */
86 hash_entry_t *entry_p;
87 db_key_t key[] = { /* some keys... */
88 DB_KEY_INIT("obj0", 0),
89 DB_KEY_INIT("obj1", 1),
90 DB_KEY_INIT("obj2", 2),
91 DB_KEY_INIT("obj3", 3),
92 DB_KEY_INIT("obj4", 4),
93 DB_KEY_INIT("obj5", 5),
94 DB_KEY_INIT("obj6", 6)
97 /* initialize the tables with a size */
98 if (ht_init(&table[0], 0, check_func, check_comp, 0, TABLE0, 7) ||
99 ht_init(&table[1], 0, check_func, check_comp, 0, TABLE1, 7))
100 return -1; /* failed to initialize test */
102 /* Check ht_find()'s handling of bad arguments */
103 check_result(ht_find(0, 0, 0), DB_ERR_BADARGS, "ht_find_noargs",
104 "ht_find() with no valid arguments", 0);
105 check_result(ht_find(&table[2], 0, &key[6]), DB_ERR_BADARGS,
106 "ht_find_badtable", "ht_find() with bad table", 0);
107 check_result(ht_find(&table[0], 0, 0), DB_ERR_BADARGS,
108 "ht_find_badkey", "ht_find() with bad key", 0);
110 /* Check if empty tables return DB_ERR_NOENTRY */
111 check_result(ht_find(&table[0], 0, &key[6]), DB_ERR_NOENTRY,
112 "ht_find_emptytable", "ht_find() with empty table", 1);
114 /* Check ht_add()'s handling of bad arguments */
115 check_result(ht_add(0, 0, 0), DB_ERR_BADARGS, "ht_add_noargs",
116 "ht_add() with no valid arguments", 0);
117 check_result(ht_add(&table[2], &entry[0], &key[0]), DB_ERR_BADARGS,
118 "ht_add_badtable", "ht_add() with bad table", 1);
119 check_result(ht_add(&table[0], &entry[6], &key[6]), DB_ERR_BADARGS,
120 "ht_add_badentry", "ht_add() with bad entry", 1);
121 check_result(ht_add(&table[0], &entry[0], 0), DB_ERR_BADARGS, "ht_add_nokey",
122 "ht_add() with no key", 1);
124 /* Freeze the table temporarily */
125 ht_flags(&table[0]) |= HASH_FLAG_FREEZE;
126 /* Check adds to frozen tables */
127 check_result(ht_add(&table[0], &entry[0], &key[0]), DB_ERR_FROZEN,
128 "ht_add_frozen", "ht_add() on frozen table", 1);
129 /* Unfreeze the table */
130 ht_flags(&table[0]) &= ~HASH_FLAG_FREEZE;
132 /* Add an element to a hash table */
133 check_result(ht_add(&table[1], &entry[5], &key[5]), 0, "ht_add_t1e5",
134 "Add entry 5 to table 1", 1);
136 /* Now try to add the same element to another hash table */
137 check_result(ht_add(&table[0], &entry[5], &key[5]), DB_ERR_BUSY,
138 "ht_add_busy", "Add busy entry 5 to table 0", 1);
140 /* Try ht_find() to see if it can find elements */
141 check_result(ht_find(&table[1], &entry_p, &key[5]), 0, "ht_find_t1e5",
142 "Look up entry 5 in table 1", 1);
143 if (entry_p != &entry[5]) {
144 printf("FAIL/ht_find_t1e5_entry:Attempt to look up entry 5 retrieved "
145 "%p (correct answer is %p)\n", (void *)entry_p, (void *)&entry[5]);
148 printf("PASS/ht_find_t1e5_entry:Retrieved correct entry %p\n",
151 /* Try looking up an element that isn't there in a populated table */
152 check_result(ht_find(&table[1], 0, &key[6]), DB_ERR_NOENTRY,
153 "ht_find_t1e6", "Look up non-existant entry 5 in table 1", 1);
155 /* Now we know that ht_find() works properly--finish testing ht_add() */
156 check_result(ht_add(&table[1], &entry[0], &key[5]), DB_ERR_DUPLICATE,
157 "ht_add_duplicate", "Attempt to add duplicate entry to table",
160 /* Now try adding several entries to the table */
161 check_result(ht_add(&table[0], &entry[0], &key[0]), 0, "ht_add_t0e0",
162 "Add entry 0 to table 0", 1);
163 check_result(ht_add(&table[0], &entry[1], &key[1]), 0, "ht_add_t0e1",
164 "Add entry 1 to table 0", 1);
165 check_result(ht_add(&table[0], &entry[2], &key[2]), 0, "ht_add_t0e2",
166 "Add entry 2 to table 0", 1);
167 check_result(ht_add(&table[0], &entry[3], &key[3]), 0, "ht_add_t0e3",
168 "Add entry 3 to table 0", 1);
169 check_result(ht_add(&table[0], &entry[4], &key[4]), 0, "ht_add_t0e4",
170 "Add entry 4 to table 0", 1);
172 /* Check to see if an element can be found */
173 check_result(ht_find(&table[0], 0, &key[2]), 0, "ht_find_t0e2",
174 "Find entry 2 in table 0", 1);