Accept topic changes from servers that do not send topic-set timestamps (fixes SF...
[ircu2.10.12-pk.git] / libs / dbprim / tests / t_ht_addfind.c
1 /*
2 ** Copyright (C) 2002 by Kevin L. Mitchell <klmitch@mit.edu>
3 **
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.
8 **
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.
13 **
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,
17 ** MA 02111-1307, USA
18 **
19 ** @(#)$Id$
20 */
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include "dbprim.h"
25 #include "dbprim_int.h"
26
27 #define TABLE0  (void *)0x76543210
28 #define TABLE1  (void *)0x87654321
29
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
36
37 #define DEADINT 0xdeadbeef
38 #define DEADPTR (void *)0xdeadbeef
39
40 /* Check return value of add operation and report PASS/FAIL */
41 static void
42 check_result(unsigned long result, unsigned long expected, char *test,
43              char *info, int die)
44 {
45   if (result != expected) {
46     printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
47            result, expected);
48     if (die)
49       exit(0);
50   } else
51     printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
52 }
53
54 static unsigned long
55 check_func(hash_table_t *table, db_key_t *key)
56 {
57   return dk_len(key);
58 }
59
60 static unsigned long
61 check_comp(hash_table_t *table, db_key_t *key1, db_key_t *key2)
62 {
63   return (!(dk_len(key1) == dk_len(key2) && dk_key(key1) == dk_key(key2)));
64 }
65
66 int
67 main(int argc, char **argv)
68 {
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] */
75   };
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] */
85   };
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)
95   };
96
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 */
101
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);
109
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);
113
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);
123
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;
131
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);
135
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);
139
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]);
146     return 0;
147   } else
148     printf("PASS/ht_find_t1e5_entry:Retrieved correct entry %p\n",
149            (void *)entry_p);
150
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);
154
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",
158                1);
159
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);
171
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);
175
176   return 0;
177 }