1eb402ca08cbe24b6742886f0a330fa2f82ef641
[idzebra-moved-to-github.git] / isamb / tstisamb.c
1 /* $Id: tstisamb.c,v 1.12 2004-12-08 14:02:37 adam Exp $
2    Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
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 <string.h>
24 #include <yaz/xmalloc.h>
25 #include <yaz/ylog.h>
26 #include <idzebra/isamb.h>
27 #include <assert.h>
28
29 static void log_item(int level, const void *b, const char *txt)
30 {
31     int x;
32     memcpy(&x, b, sizeof(int));
33     yaz_log(YLOG_DEBUG, "%s %d", txt, x);
34 }
35
36 static void log_pr(const char *txt)
37 {
38     yaz_log(YLOG_DEBUG, "%s", txt);
39 }
40
41 int compare_item(const void *a, const void *b)
42 {
43     int ia, ib;
44
45     memcpy(&ia, a, sizeof(int));
46     memcpy(&ib, b, sizeof(int));
47     return ia - ib;
48 }
49
50 void *code_start()
51 {
52     return 0;
53 }
54
55 void code_item(void *p, char **dst, const char **src)
56 {
57     memcpy (*dst, *src, sizeof(int));
58     (*dst) += sizeof(int);
59     (*src) += sizeof(int);
60 }
61
62 void code_reset(void *p)
63 {
64 }
65 void code_stop(void *p)
66 {
67 }
68
69 struct read_info {
70     int no;
71     int step;
72     int max;
73     int insertMode;
74 };
75
76 int code_read(void *vp, char **dst, int *insertMode)
77 {
78     struct read_info *ri = (struct read_info *)vp;
79     int x;
80
81     if (ri->no >= ri->max)
82         return 0;
83     x = ri->no;
84     memcpy (*dst, &x, sizeof(int));
85     (*dst)+=sizeof(int);
86
87     ri->no += ri->step;
88     *insertMode = ri->insertMode;
89     return 1;
90 }
91
92 void tst_forward(ISAMB isb, int n)
93 {
94     ISAMC_I isamc_i;
95     ISAMC_P isamc_p;
96     struct read_info ri;
97     int i;
98     ISAMB_PP pp;
99
100     /* insert a number of entries */
101     ri.no = 0;
102     ri.step = 1;
103     ri.max = n;
104     ri.insertMode = 1;
105
106     isamc_i.clientData = &ri;
107     isamc_i.read_item = code_read;
108     
109     isamc_p = isamb_merge (isb, 0 /* new list */ , &isamc_i);
110
111     /* read the entries */
112     pp = isamb_pp_open (isb, isamc_p, 2);
113     
114     for (i = 0; i<ri.max; i +=2 )
115     {
116         int x = -1;
117         int xu = i;
118         isamb_pp_forward(pp, &x, &xu);
119         if (x != xu && xu != x+1)
120         {
121             yaz_log(YLOG_WARN, "isamb_pp_forward (1). Got %d (expected %d)",
122                     x, xu);
123             exit(4);
124         }
125         ri.no++;
126     }
127     isamb_pp_close(pp);
128     
129     pp = isamb_pp_open (isb, isamc_p, 2);
130     for (i = 0; i<ri.max; i += 100)
131     {
132         int x = -1;
133         int xu = i;
134         isamb_pp_forward(pp, &x, &xu);
135         if (x != xu && xu != x+1)
136         {
137             yaz_log(YLOG_WARN, "isamb_pp_forward (2). Got %d (expected %d)",
138                     x, xu);
139             exit(4);
140         }
141         ri.no++;
142     }
143     isamb_pp_close(pp);
144
145     isamb_unlink(isb, isamc_p);
146 }
147
148 void tst_insert(ISAMB isb, int n)
149 {
150     ISAMC_I isamc_i;
151     ISAMC_P isamc_p;
152     struct read_info ri;
153     ISAMB_PP pp;
154     char key_buf[10];
155
156     /* insert a number of entries */
157     ri.no = 0;
158     ri.step = 1;
159     ri.max = n;
160     ri.insertMode = 1;
161
162     isamc_i.clientData = &ri;
163     isamc_i.read_item = code_read;
164     
165     isamc_p = isamb_merge (isb, 0 /* new list */ , &isamc_i);
166
167     /* read the entries */
168     pp = isamb_pp_open (isb, isamc_p, 2);
169     
170     ri.no = 0;
171     while(isamb_pp_read (pp, key_buf))
172     {
173         int x;
174         memcpy (&x, key_buf, sizeof(int));
175         if (x != ri.no)
176         {
177             yaz_log(YLOG_WARN, "isamb_pp_read. Got %d (expected %d)",
178                     x, ri.no);
179             exit(3);
180         }
181         ri.no++;
182     }
183     if (ri.no != ri.max)
184     {
185         yaz_log(YLOG_WARN, "ri.max != ri.max (%d != %d)", ri.no, ri.max);
186         exit(3);
187     }
188     isamb_pp_close(pp);
189
190     isamb_dump(isb, isamc_p, log_pr);
191
192     /* delete a number of entries (even ones) */
193     ri.no = 0;
194     ri.step = 2;
195     ri.max = n;
196     ri.insertMode = 0;
197
198     isamc_i.clientData = &ri;
199     isamc_i.read_item = code_read;
200     
201     isamc_p = isamb_merge (isb, isamc_p , &isamc_i);
202
203     /* delete a number of entries (odd ones) */
204     ri.no = 1;
205     ri.step = 2;
206     ri.max = n;
207     ri.insertMode = 0;
208
209     isamc_i.clientData = &ri;
210     isamc_i.read_item = code_read;
211     
212     isamc_p = isamb_merge (isb, isamc_p , &isamc_i);
213
214     if (isamc_p)
215     {
216         yaz_log(YLOG_WARN, "isamb_merge did not return empty list");
217         exit(3);
218     }
219 }
220
221 int main(int argc, char **argv)
222 {
223     BFiles bfs;
224     ISAMB isb;
225     ISAMC_M method;
226     
227     if (argc == 2)
228         yaz_log_init_level(YLOG_ALL);
229         
230     /* setup method (attributes) */
231     method.compare_item = compare_item;
232     method.log_item = log_item;
233     method.codec.start = code_start;
234     method.codec.encode = code_item;
235     method.codec.decode = code_item;
236     method.codec.reset = code_reset;
237     method.codec.stop = code_stop;
238
239     /* create block system */
240     bfs = bfs_create(0, 0);
241     if (!bfs)
242     {
243         yaz_log(YLOG_WARN, "bfs_create failed");
244         exit(1);
245     }
246
247     bf_reset(bfs);
248
249     /* create isam handle */
250     isb = isamb_open (bfs, "isamb", 1, &method, 0);
251     if (!isb)
252     {
253         yaz_log(YLOG_WARN, "isamb_open failed");
254         exit(2);
255     }
256     tst_insert(isb, 1);
257     tst_insert(isb, 2);
258     tst_insert(isb, 20);
259     tst_insert(isb, 100);
260     tst_insert(isb, 500);
261     tst_insert(isb, 10000);
262     tst_forward(isb, 10000);
263     /* close isam handle */
264     isamb_close(isb);
265
266     /* exit block system */
267     bfs_destroy(bfs);
268     exit(0);
269     return 0;
270 }