Bump copyright year
[idzebra-moved-to-github.git] / dict / scantest.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 1994-2010 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <yaz/log.h>
24 #include <yaz/test.h>
25 #include <yaz/options.h>
26 #include <idzebra/dict.h>
27
28 struct handle_info {
29     int b;
30     int a;
31     int start_cut;
32     int end_cut;
33     char **ar;
34 };
35
36 static int handler(char *name, const char *info, int pos, void *client)
37 {
38     struct handle_info *hi = (struct handle_info *) client;
39     int idx;
40     if (pos > 0)
41         idx = hi->a - pos + hi->b;
42     else
43         idx = -pos - 1;
44
45     yaz_log(YLOG_DEBUG, "pos=%d idx=%d name=%s", pos, idx, name);
46     if (idx < 0)
47         return 0;
48     if (idx < hi->start_cut || idx >= hi->end_cut)
49     {
50         return 1;
51     }
52
53     hi->ar[idx] = malloc(strlen(name)+1);
54     strcpy(hi->ar[idx], name);
55
56     return 0;
57 }
58
59 int do_scan(Dict dict, int before, int after, const char *sterm,
60             char **cmp_strs,
61             int verbose, int start_cut, int end_cut)
62 {
63     struct handle_info hi;
64     char scan_term[1024];
65
66     int i;
67     int errors = 0;
68
69     strcpy(scan_term, sterm);
70     hi.start_cut = start_cut;
71     hi.end_cut = end_cut;
72     hi.a = after;
73     hi.b = before;
74     hi.ar = malloc(sizeof(char*) * (after+before+1));
75     for (i = 0; i<after+before; i++)
76         hi.ar[i] = 0;
77     yaz_log(YLOG_DEBUG, "dict_scan before=%d after=%d term=%s",
78             before, after, scan_term);
79     dict_scan (dict, scan_term, &before, &after, &hi, handler);
80     for (i = 0; i < hi.a+hi.b; i++)
81     {
82         if (!cmp_strs)
83         {
84             if (i >= start_cut &&  i < end_cut)
85             {
86                 if (!hi.ar[i])
87                 {
88                     printf ("--> FAIL i=%d hi.ar[i] == NULL\n", i);
89                     errors++;
90                 }
91             }
92             else
93             {
94                 if (hi.ar[i])
95                 {
96                     printf ("--> FAIL i=%d hi.ar[i] = %s\n", i, hi.ar[i]);
97                     errors++;
98                 }
99             }
100         }
101         else
102         {
103             if (i >= start_cut && i < end_cut)
104             {
105                 if (!hi.ar[i])
106                 {
107                     printf ("--> FAIL i=%d strs == NULL\n", i);
108                     errors++;
109                 }
110                 else if (!cmp_strs[i])
111                 {
112                     printf ("--> FAIL i=%d cmp_strs == NULL\n", i);
113                     errors++;
114                 }
115                 else if (strcmp(cmp_strs[i], hi.ar[i]))
116                 {
117                     printf ("--> FAIL i=%d expected %s\n", i, cmp_strs[i]);
118                     errors++;
119                 }
120             }
121             else
122             {
123                 if (hi.ar[i])
124                 {
125                     printf ("--> FAIL i=%d hi.ar[i] != NULL\n", i);
126                     errors++;
127                 }
128             }
129         }
130         if (verbose || errors)
131         {
132             if (i == hi.b)
133                 printf ("* ");
134             else
135                 printf ("  ");
136             if (hi.ar[i])
137                 printf ("%s", hi.ar[i]);
138             else
139                 printf ("NULL");
140             putchar('\n');
141         }
142         if (hi.ar[i])
143             free(hi.ar[i]);
144     }
145     free(hi.ar);
146     return errors;
147 }
148
149 static void tst(Dict dict, int start, int number)
150 {
151     int i;
152
153     /* insert again with original value again */
154     for (i = start; i < number; i += 100)
155     {
156         int v = i;
157         char w[32];
158         sprintf(w, "%d", i);
159         YAZ_CHECK_EQ(dict_insert(dict, w, sizeof(v), &v), 2);
160     }
161     /* insert again with different value */
162     for (i = start; i < number; i += 100)
163     {
164         int v = i-1;
165         char w[32];
166         sprintf(w, "%d", i);
167         YAZ_CHECK_EQ(dict_insert(dict, w, sizeof(v), &v), 1);
168     }
169     /* insert again with original value again */
170     for (i = start; i < number; i += 100)
171     {
172         int v = i;
173         char w[32];
174         sprintf(w, "%d", i);
175         YAZ_CHECK_EQ(dict_insert(dict, w, sizeof(v), &v), 1);
176     }
177
178     {
179         char *cs[] = {
180             "4497",
181             "4498",
182             "4499",
183             "45"};
184         YAZ_CHECK_EQ(do_scan(dict, 2, 2, "4499", cs, 0, 0, 3), 0);
185     }
186     {
187         char *cs[] = {
188             "4498",
189             "4499",
190             "45",
191             "450"};
192         YAZ_CHECK_EQ(do_scan(dict, 2, 2, "45", cs, 0, 0, 3), 0);
193     }
194
195     for (i = 0; i < 20; i++)
196         YAZ_CHECK_EQ(do_scan(dict, 20, 20, "45", 0, 0, 20-i, 20+i), 0);
197 }
198
199 int main(int argc, char **argv)
200 {
201     BFiles bfs = 0;
202     Dict dict = 0;
203     int i;
204     int ret;
205     int before = 0, after = 0, number = 10000;
206     char scan_term[1024];
207     char *arg;
208
209     YAZ_CHECK_INIT(argc, argv);
210
211     strcpy(scan_term, "1004");
212     while ((ret = options("b:a:t:n:v:", argv, argc, &arg)) != -2)
213     {
214         switch(ret)
215         {
216         case 0:
217             break;
218         case 'b':
219             before = atoi(arg);
220             break;
221         case 'a':
222             after = atoi(arg);
223             break;
224         case 't':
225             if (strlen(arg) >= sizeof(scan_term)-1)
226             {
227                 fprintf(stderr, "scan term too long\n");
228                 exit(1);
229             }
230             strcpy(scan_term, arg);
231             break;
232         case 'n':
233             number = atoi(arg);
234             break;
235         case 'v':
236             yaz_log_init_level(yaz_log_mask_str(arg));
237         }
238     }
239
240     bfs = bfs_create(".:100M", 0);
241     YAZ_CHECK(bfs);
242     if (bfs)
243     {
244         bf_reset(bfs);
245         dict = dict_open(bfs, "dict", 10, 1, 0, 0);
246         YAZ_CHECK(dict);
247     }
248     if (dict)
249     {
250         int start = 10;
251         /* Insert "10", "11", "12", .. "99", "100", ... number */
252         for (i = start; i<number; i++)
253         {
254             char w[32];
255             sprintf(w, "%d", i);
256             YAZ_CHECK_EQ(dict_insert(dict, w, sizeof(int), &i), 0);
257         }
258
259         if (after > 0 || before > 0)
260             do_scan(dict, before, after, scan_term, 0, 1, 0, after+1);
261         else
262             tst(dict, start, number);
263
264         dict_close(dict);
265     }
266     if (bfs)
267         bfs_destroy(bfs);
268     YAZ_CHECK_TERM;
269 }
270 /*
271  * Local variables:
272  * c-basic-offset: 4
273  * c-file-style: "Stroustrup"
274  * indent-tabs-mode: nil
275  * End:
276  * vim: shiftwidth=4 tabstop=8 expandtab
277  */
278