Accept topic changes from servers that do not send topic-set timestamps (fixes SF...
[ircu2.10.12-pk.git] / libs / dbprim / tests / t_ht_iter.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 <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include "dbprim.h"
26 #include "dbprim_int.h"
27
28 #define TABLE0  (void *)0x76543210
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 #define OBJECT6 (void *)0x6789abcd
37 #define OBJECT7 (void *)0x789abcde
38
39 #define DEADINT 0xdeadbeef
40 #define DEADPTR (void *)0xdeadbeef
41
42 struct itercheck {
43   hash_table_t *ent_table;
44   hash_entry_t *ent_array;
45   unsigned int  ent_mask;
46 };
47
48 #define BIT(n)  (1 << (n))
49 #define BITMASK 0x000000ff
50
51 /* Check return value of add operation and report PASS/FAIL */
52 static void
53 check_result(unsigned long result, unsigned long expected, char *test,
54              char *info, int die)
55 {
56   if (result != expected) {
57     printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
58            result, expected);
59     if (die)
60       exit(0);
61   } else
62     printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
63 }
64
65 static unsigned long
66 check_func(hash_table_t *table, db_key_t *key)
67 {
68   return dk_len(key);
69 }
70
71 static unsigned long
72 check_comp(hash_table_t *table, db_key_t *key1, db_key_t *key2)
73 {
74   return (!(dk_len(key1) == dk_len(key2) && dk_key(key1) == dk_key(key2)));
75 }
76
77 static unsigned long
78 check_iter(hash_table_t *table, hash_entry_t *ent, void *extra)
79 {
80   struct itercheck *itcheck;
81
82   itcheck = extra;
83
84   /* If we were told to return an error, return one */
85   if (!itcheck->ent_array)
86     return EINVAL;
87
88   /* OK, verify that the hash table is the same as the one we expect */
89   if (table != itcheck->ent_table)
90     printf("FAIL/ht_iter_functab_e%d:Hash tables do not match\n",
91            dk_len(he_key(ent)));
92   else
93     printf("PASS/ht_iter_functab_e%d:Hash tables match\n",
94            dk_len(he_key(ent)));
95
96   /* Now verify that everything matches up... */
97   if (ent != &itcheck->ent_array[dk_len(he_key(ent))])
98     printf("FAIL/ht_iter_funcent_e%d:Entries do not match\n",
99            dk_len(he_key(ent)));
100   else
101     printf("PASS/ht_iter_funcent_e%d:Entries match\n", dk_len(he_key(ent)));
102
103   /* Finally, set the visited bitmask */
104   itcheck->ent_mask |= BIT(dk_len(he_key(ent)));
105
106   return 0;
107 }
108
109 int
110 main(int argc, char **argv)
111 {
112   int i;
113   hash_table_t table[] = { /* some tables to operate on */
114     HASH_TABLE_INIT(0, check_func, check_comp, 0, TABLE0),
115     { DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADPTR,
116       (hash_func_t)DEADPTR, (hash_comp_t)DEADPTR, (hash_resize_t)DEADPTR,
117       DEADPTR } /* table[1] */
118   };
119   hash_entry_t entry[] = { /* some entries to operate on */
120     HASH_ENTRY_INIT(OBJECT0),
121     HASH_ENTRY_INIT(OBJECT1),
122     HASH_ENTRY_INIT(OBJECT2),
123     HASH_ENTRY_INIT(OBJECT3),
124     HASH_ENTRY_INIT(OBJECT4),
125     HASH_ENTRY_INIT(OBJECT5),
126     HASH_ENTRY_INIT(OBJECT6),
127     HASH_ENTRY_INIT(OBJECT7),
128   };
129   db_key_t key[] = { /* some keys... */
130     DB_KEY_INIT("obj0", 0),
131     DB_KEY_INIT("obj1", 1),
132     DB_KEY_INIT("obj2", 2),
133     DB_KEY_INIT("obj3", 3),
134     DB_KEY_INIT("obj4", 4),
135     DB_KEY_INIT("obj5", 5),
136     DB_KEY_INIT("obj6", 6),
137     DB_KEY_INIT("obj7", 7)
138   };
139   struct itercheck itcheck = { 0, 0, 0 };
140
141   /* initialize the tables with a size */
142   if (ht_init(&table[0], 0, check_func, check_comp, 0, TABLE0, 8))
143     return -1; /* failed to initialize test */
144
145   /* Add some entries to various hash tables */
146   for (i = 0; i < 8; i++)
147     if (ht_add(&table[0], &entry[i], &key[i]))
148       return -1; /* failed to initialize test */
149
150   /* Check handling of bad arguments */
151   check_result(ht_iter(0, 0, 0), DB_ERR_BADARGS, "ht_iter_noargs",
152                "ht_iter() with no valid arguments", 0);
153   check_result(ht_iter(&table[1], check_iter, &itcheck), DB_ERR_BADARGS,
154                "ht_iter_badtable", "ht_iter() with bad table", 0);
155   check_result(ht_iter(&table[0], 0, &itcheck), DB_ERR_BADARGS,
156                "ht_iter_baditer", "ht_iter() with bad iteration function", 0);
157
158   /* Freeze the table temporarily */
159   ht_flags(&table[0]) |= HASH_FLAG_FREEZE;
160   /* check if frozen tables are excluded */
161   check_result(ht_iter(&table[0], check_iter, &itcheck), DB_ERR_FROZEN,
162                "ht_iter_frozen", "ht_iter() on frozen table", 0);
163   /* Unfreeze the table */
164   ht_flags(&table[0]) &= ~HASH_FLAG_FREEZE;
165
166   /* Check to see if ht_iter() returns what the iter function returns */
167   check_result(ht_iter(&table[0], check_iter, &itcheck), EINVAL,
168                "ht_iter_funcreturn",
169                "ht_iter() returning iteration function return value", 0);
170
171   /* Now iterate through the list */
172   itcheck.ent_table = &table[0];
173   itcheck.ent_array = entry;
174   itcheck.ent_mask = 0;
175   check_result(ht_iter(&table[0], check_iter, &itcheck), 0, "ht_iter_function",
176                "ht_iter() iteration", 0);
177
178   /* Did it iterate through them all? */
179   if (itcheck.ent_mask == BITMASK)
180     printf("PASS/ht_iter_func_mask:ht_iter() visited all items\n");
181   else
182     printf("FAIL/ht_iter_func_mask:ht_iter() visited only items in bitmask "
183            "0x%02x\n", itcheck.ent_mask);
184
185   return 0;
186 }