Get rid of typedefs iSAMS_P, ISAMC_P, ISAMB_P and use ISAM_P instead.
[idzebra-moved-to-github.git] / isamb / tstisamb.c
1 /* $Id: tstisamb.c,v 1.20 2005-04-13 13:03:48 adam Exp $
2    Copyright (C) 1995-2005
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra.  If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.
21 */
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <yaz/log.h>
26 #include <yaz/xmalloc.h>
27 #include <idzebra/isamb.h>
28 #include <assert.h>
29
30 static void log_item(int level, const void *b, const char *txt)
31 {
32     int x;
33     memcpy(&x, b, sizeof(int));
34     yaz_log(YLOG_DEBUG, "%s %d", txt, x);
35 }
36
37 static void log_pr(const char *txt)
38 {
39     yaz_log(YLOG_DEBUG, "%s", txt);
40 }
41
42 int compare_item(const void *a, const void *b)
43 {
44     int ia, ib;
45
46     memcpy(&ia, a, sizeof(int));
47     memcpy(&ib, b, sizeof(int));
48     if (ia > ib)
49         return 1;
50     if (ia < ib)
51         return -1;
52    return 0;
53 }
54
55 void *code_start()
56 {
57     return 0;
58 }
59
60 void code_item(void *p, char **dst, const char **src)
61 {
62     memcpy (*dst, *src, sizeof(int));
63     (*dst) += sizeof(int);
64     (*src) += sizeof(int);
65 }
66
67 void code_reset(void *p)
68 {
69 }
70 void code_stop(void *p)
71 {
72 }
73
74 struct read_info {
75     int no;
76     int step;
77     int max;
78     int insertMode;
79 };
80
81 int code_read(void *vp, char **dst, int *insertMode)
82 {
83     struct read_info *ri = (struct read_info *)vp;
84     int x;
85
86     if (ri->no >= ri->max)
87         return 0;
88     x = ri->no;
89     memcpy (*dst, &x, sizeof(int));
90     (*dst)+=sizeof(int);
91
92     ri->no = ri->no + ri->step;
93     *insertMode = ri->insertMode;
94     return 1;
95 }
96
97 void tst_insert(ISAMB isb, int n)
98 {
99     ISAMC_I isamc_i;
100     ISAM_P isamc_p;
101     struct read_info ri;
102     ISAMB_PP pp;
103     char key_buf[10];
104     int nerrs = 0;
105
106     /* insert a number of entries */
107     ri.no = 0;
108     ri.step = 1;
109     ri.max = n;
110     ri.insertMode = 1;
111
112     isamc_i.clientData = &ri;
113     isamc_i.read_item = code_read;
114     
115     isamc_p = 0; /* new list */
116     isamb_merge (isb, &isamc_p , &isamc_i);
117
118     /* read the entries */
119     pp = isamb_pp_open (isb, isamc_p, 1);
120
121     ri.no = 0;
122     while(isamb_pp_read (pp, key_buf))
123     {
124         int x;
125         memcpy (&x, key_buf, sizeof(int));
126         if (x != ri.no)
127         {
128             yaz_log(YLOG_WARN, "isamb_pp_read. n=%d Got %d (expected %d)",
129                     n, x, ri.no);
130             nerrs++;
131         }
132         else if (nerrs)
133             yaz_log(YLOG_LOG, "isamb_pp_read. n=%d Got %d",
134                     n, x);
135
136         ri.no++;
137     }
138     if (ri.no != ri.max)
139     {
140         yaz_log(YLOG_WARN, "ri.max != ri.max (%d != %d)", ri.no, ri.max);
141         nerrs++;
142     }
143     isamb_dump(isb, isamc_p, log_pr);
144     isamb_pp_close(pp);
145
146     if (nerrs)
147         exit(3);
148     /* delete a number of entries (even ones) */
149     ri.no = 0;
150     ri.step = 2;
151     ri.max = n;
152     ri.insertMode = 0;
153
154     isamc_i.clientData = &ri;
155     isamc_i.read_item = code_read;
156     
157     isamb_merge (isb, &isamc_p , &isamc_i);
158
159     /* delete a number of entries (odd ones) */
160     ri.no = 1;
161     ri.step = 2;
162     ri.max = n;
163     ri.insertMode = 0;
164
165     isamc_i.clientData = &ri;
166     isamc_i.read_item = code_read;
167     
168     isamb_merge (isb, &isamc_p, &isamc_i);
169
170     if (isamc_p)
171     {
172         yaz_log(YLOG_WARN, "isamb_merge did not return empty list");
173         exit(3);
174     }
175 }
176
177 void tst_forward(ISAMB isb, int n)
178 {
179     ISAMC_I isamc_i;
180     ISAM_P isamc_p;
181     struct read_info ri;
182     int i;
183     ISAMB_PP pp;
184
185     /* insert a number of entries */
186     ri.no = 0;
187     ri.step = 1;
188     ri.max = n;
189     ri.insertMode = 1;
190
191     isamc_i.clientData = &ri;
192     isamc_i.read_item = code_read;
193     
194     isamc_p = 0;
195     isamb_merge (isb, &isamc_p, &isamc_i);
196
197     /* read the entries */
198     pp = isamb_pp_open (isb, isamc_p, 1);
199     
200     for (i = 0; i<ri.max; i +=2 )
201     {
202         int x = -1;
203         int xu = i;
204         isamb_pp_forward(pp, &x, &xu);
205         if (x != xu && xu != x+1)
206         {
207             yaz_log(YLOG_WARN, "isamb_pp_forward (1). Got %d (expected %d)",
208                     x, xu);
209             exit(4);
210         }
211         ri.no++;
212     }
213     isamb_pp_close(pp);
214     
215     pp = isamb_pp_open (isb, isamc_p, 1);
216     for (i = 0; i<ri.max; i += 100)
217     {
218         int x = -1;
219         int xu = i;
220         isamb_pp_forward(pp, &x, &xu);
221         if (x != xu && xu != x+1)
222         {
223             yaz_log(YLOG_WARN, "isamb_pp_forward (2). Got %d (expected %d)",
224                     x, xu);
225             exit(4);
226         }
227         ri.no++;
228     }
229     isamb_pp_close(pp);
230
231     isamb_unlink(isb, isamc_p);
232 }
233
234 void tst_x(ISAMB isb)
235 {
236     ISAMC_I isamc_i;
237     ISAM_P isamb_p = 0;
238     struct read_info ri;
239
240     isamc_i.clientData = &ri;
241     isamc_i.read_item = code_read;
242     ri.no = 1000;
243     ri.step = 1;
244     ri.max = 1500;
245
246     isamb_merge (isb, &isamb_p , &isamc_i);
247
248     ri.no = 1;
249     ri.step = 1;
250     ri.max = 500;
251
252     isamb_merge (isb, &isamb_p , &isamc_i);
253 }
254
255 void tst_append(ISAMB isb, int n)
256 {
257     ISAMC_I isamc_i;
258     ISAM_P isamb_p = 0;
259     struct read_info ri;
260     int i;
261     int chunk = 10;
262
263     for (i = 0; i < n; i += chunk)
264     {
265         /* insert a number of entries */
266         ri.no = 0;
267         ri.step = 1;
268         ri.max = i + chunk;
269         ri.insertMode = 1;
270         
271         isamc_i.clientData = &ri;
272         isamc_i.read_item = code_read;
273         
274         isamb_merge (isb, &isamb_p , &isamc_i);
275     }
276 }
277
278 int main(int argc, char **argv)
279 {
280     BFiles bfs;
281     ISAMB isb;
282     ISAMC_M method;
283     
284     if (argc == 2)
285         yaz_log_init_level(YLOG_ALL);
286         
287     /* setup method (attributes) */
288     method.compare_item = compare_item;
289     method.log_item = log_item;
290     method.codec.start = code_start;
291     method.codec.encode = code_item;
292     method.codec.decode = code_item;
293     method.codec.reset = code_reset;
294     method.codec.stop = code_stop;
295
296     /* create block system */
297     bfs = bfs_create(0, 0);
298     if (!bfs)
299     {
300         yaz_log(YLOG_WARN, "bfs_create failed");
301         exit(1);
302     }
303
304     bf_reset(bfs);
305
306     /* create isam handle */
307     isb = isamb_open (bfs, "isamb", 1, &method, 0);
308     if (!isb)
309     {
310         yaz_log(YLOG_WARN, "isamb_open failed");
311         exit(2);
312     }
313     tst_insert(isb, 1);
314     tst_insert(isb, 2);
315     tst_insert(isb, 20);
316     tst_insert(isb, 100);
317     tst_insert(isb, 500);
318     tst_insert(isb, 10000);
319
320     tst_forward(isb, 10000);
321
322     tst_x(isb);
323
324     tst_append(isb, 1000);
325     /* close isam handle */
326     isamb_close(isb);
327
328     /* exit block system */
329     bfs_destroy(bfs);
330     exit(0);
331     return 0;
332 }