e3735538f52a85aafb9d7a3bb355314d7d8df37e
[ircu2.10.12-pk.git] / libs / dbprim / tests / t_ht_flush.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 #define TABLE1  (void *)0x87654321
30
31 #define OBJECT0 (void *)0x01234567
32 #define OBJECT1 (void *)0x12345678
33 #define OBJECT2 (void *)0x23456789
34 #define OBJECT3 (void *)0x3456789a
35 #define OBJECT4 (void *)0x456789ab
36 #define OBJECT5 (void *)0x56789abc
37 #define OBJECT6 (void *)0x6789abcd
38 #define OBJECT7 (void *)0x789abcde
39
40 #define DEADINT 0xdeadbeef
41 #define DEADPTR (void *)0xdeadbeef
42
43 struct flushcheck {
44   hash_table_t *ent_table;
45   hash_entry_t *ent_array;
46   unsigned int  ent_mask;
47 };
48
49 #define BIT(n)  (1 << (n))
50 #define BITMASK 0x0000000f
51
52 /* Check return value of add operation and report PASS/FAIL */
53 static void
54 check_result(unsigned long result, unsigned long expected, char *test,
55              char *info, int die)
56 {
57   if (result != expected) {
58     printf("FAIL/%s:%s incorrectly returned %lu (expected %lu)\n", test, info,
59            result, expected);
60     if (die)
61       exit(0);
62   } else
63     printf("PASS/%s:%s correctly returned %lu\n", test, info, result);
64 }
65
66 static unsigned long
67 check_func(hash_table_t *table, db_key_t *key)
68 {
69   return dk_len(key);
70 }
71
72 static unsigned long
73 check_comp(hash_table_t *table, db_key_t *key1, db_key_t *key2)
74 {
75   return (!(dk_len(key1) == dk_len(key2) && dk_key(key1) == dk_key(key2)));
76 }
77
78 static unsigned long
79 check_flush(hash_table_t *table, hash_entry_t *ent, void *extra)
80 {
81   struct flushcheck *itcheck;
82
83   itcheck = extra;
84
85   /* OK, verify that the hash table is the same as the one we expect */
86   if (table != itcheck->ent_table)
87     printf("FAIL/ht_flush_functab_e%d:Hash tables do not match\n",
88            dk_len(he_key(ent)));
89   else
90     printf("PASS/ht_flush_functab_e%d:Hash tables match\n",
91            dk_len(he_key(ent)));
92
93   /* Now verify that everything matches up... */
94   if (ent != &itcheck->ent_array[dk_len(he_key(ent))])
95     printf("FAIL/ht_flush_funcent_e%d:Entries do not match\n",
96            dk_len(he_key(ent)));
97   else
98     printf("PASS/ht_flush_funcent_e%d:Entries match\n", dk_len(he_key(ent)));
99
100   /* Finally, set the visited bitmask */
101   itcheck->ent_mask |= BIT(dk_len(he_key(ent)));
102
103   return (itcheck->ent_mask & ~BIT(dk_len(he_key(ent)))) ? 0 : EINVAL;
104 }
105
106 static void
107 check_count(hash_table_t *tab, unsigned long count, char *test, char *comment)
108 {
109   if (ht_count(tab) != count)
110     printf("FAIL/%s:%s (count %ld, supposed to be %ld)\n", test, comment,
111            ht_count(tab), count);
112   else
113     printf("PASS/%s:%s (count %ld)\n", test, comment, count);
114 }
115
116 int
117 main(int argc, char **argv)
118 {
119   int i;
120   hash_table_t table[] = { /* some tables to operate on */
121     HASH_TABLE_INIT(0, check_func, check_comp, 0, TABLE0),
122     HASH_TABLE_INIT(0, check_func, check_comp, 0, TABLE1),
123     { DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADINT, DEADPTR,
124       (hash_func_t)DEADPTR, (hash_comp_t)DEADPTR, (hash_resize_t)DEADPTR,
125       DEADPTR } /* table[2] */
126   };
127   hash_entry_t entry[] = { /* some entries to operate on */
128     HASH_ENTRY_INIT(OBJECT0),
129     HASH_ENTRY_INIT(OBJECT1),
130     HASH_ENTRY_INIT(OBJECT2),
131     HASH_ENTRY_INIT(OBJECT3),
132     HASH_ENTRY_INIT(OBJECT4),
133     HASH_ENTRY_INIT(OBJECT5),
134     HASH_ENTRY_INIT(OBJECT6),
135     HASH_ENTRY_INIT(OBJECT7),
136   };
137   db_key_t key[] = { /* some keys... */
138     DB_KEY_INIT("obj0", 0),
139     DB_KEY_INIT("obj1", 1),
140     DB_KEY_INIT("obj2", 2),
141     DB_KEY_INIT("obj3", 3),
142     DB_KEY_INIT("obj4", 4),
143     DB_KEY_INIT("obj5", 5),
144     DB_KEY_INIT("obj6", 6),
145     DB_KEY_INIT("obj7", 7)
146   };
147   struct flushcheck itcheck = { 0, 0, 0 };
148
149   /* initialize the tables with a size */
150   if (ht_init(&table[0], 0, check_func, check_comp, 0, TABLE0, 4) ||
151       ht_init(&table[1], 0, check_func, check_comp, 0, TABLE1, 4))
152     return -1; /* failed to initialize test */
153
154   /* Add some entries to various hash tables */
155   for (i = 0; i < 4; i++)
156     if (ht_add(&table[0], &entry[i], &key[i]) ||
157         ht_add(&table[1], &entry[i + 4], &key[i + 4]))
158       return -1; /* failed to initialize test */
159
160   /* Check handling of bad arguments */
161   check_result(ht_flush(0, 0, 0), DB_ERR_BADARGS, "ht_flush_noargs",
162                "ht_flush() with no valid arguments", 0);
163   check_result(ht_flush(&table[2], check_flush, &itcheck), DB_ERR_BADARGS,
164                "ht_flush_badtable", "ht_flush() with bad table", 0);
165
166   /* Freeze the table temporarily */
167   ht_flags(&table[0]) |= HASH_FLAG_FREEZE;
168   /* check if frozen tables are excluded */
169   check_result(ht_flush(&table[0], check_flush, &itcheck), DB_ERR_FROZEN,
170                "ht_flush_frozen", "ht_flush() on frozen table", 0);
171   /* Unfreeze the table */
172   ht_flags(&table[0]) &= ~HASH_FLAG_FREEZE;
173
174   /* Check to see if ht_flush() operates properly with no flush function */
175   check_result(ht_flush(&table[1], 0, 0), 0, "ht_flush_nofunc",
176                "ht_flush() with no flush function", 0);
177   check_count(&table[1], 0, "ht_flush_nofunc_count",
178               "Check count after flush with no flush function");
179
180   /* Check to see if ht_flush() returns what the iter function returns */
181   itcheck.ent_table = &table[0];
182   itcheck.ent_array = entry;
183   itcheck.ent_mask = 0;
184   check_result(ht_flush(&table[0], check_flush, &itcheck), EINVAL,
185                "ht_flush_funcreturn",
186                "ht_flush() returning flush function return value", 0);
187   check_count(&table[0], 3, "ht_flush_funcreturn_count",
188               "Check count after flush with flush function returning error");
189
190   /* Now iterate through the list */
191   check_result(ht_flush(&table[0], check_flush, &itcheck), 0,
192                "ht_flush_function", "ht_flush() flush", 0);
193   check_count(&table[0], 0, "ht_flush_function_count",
194               "Check count after flush with flush function");
195
196   /* Did it iterate through them all? */
197   if (itcheck.ent_mask == BITMASK)
198     printf("PASS/ht_flush_func_mask:ht_flush() visited all items\n");
199   else
200     printf("FAIL/ht_flush_func_mask:ht_flush() visited only items in bitmask "
201            "0x%02x\n", itcheck.ent_mask);
202
203   return 0;
204 }