rs_and reads all items
[idzebra-moved-to-github.git] / rset / rsbool.c
1 /*
2  * Copyright (C) 1994-2002, Index Data
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Id: rsbool.c,v 1.18 2002-04-18 19:48:28 adam Exp $
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <assert.h>
13
14 #include <rsbool.h>
15 #include <zebrautl.h>
16
17 static void *r_create(RSET ct, const struct rset_control *sel, void *parms);
18 static RSFD r_open (RSET ct, int flag);
19 static void r_close (RSFD rfd);
20 static void r_delete (RSET ct);
21 static void r_rewind (RSFD rfd);
22 static int r_count (RSET ct);
23 static int r_read_and (RSFD rfd, void *buf, int *term_index);
24 static int r_read_or (RSFD rfd, void *buf, int *term_index);
25 static int r_read_not (RSFD rfd, void *buf, int *term_index);
26 static int r_write (RSFD rfd, const void *buf);
27
28 static const struct rset_control control_and = 
29 {
30     "and",
31     r_create,
32     r_open,
33     r_close,
34     r_delete,
35     r_rewind,
36     r_count,
37     r_read_and,
38     r_write,
39 };
40
41 static const struct rset_control control_or = 
42 {
43     "or",
44     r_create,
45     r_open,
46     r_close,
47     r_delete,
48     r_rewind,
49     r_count,
50     r_read_or,
51     r_write,
52 };
53
54 static const struct rset_control control_not = 
55 {
56     "not",
57     r_create,
58     r_open,
59     r_close,
60     r_delete,
61     r_rewind,
62     r_count,
63     r_read_not,
64     r_write,
65 };
66
67
68 const struct rset_control *rset_kind_and = &control_and;
69 const struct rset_control *rset_kind_or = &control_or;
70 const struct rset_control *rset_kind_not = &control_not;
71
72 struct rset_bool_info {
73     int key_size;
74     RSET rset_l;
75     RSET rset_r;
76     int term_index_s;
77     int (*cmp)(const void *p1, const void *p2);
78     struct rset_bool_rfd *rfd_list;
79 };
80
81 struct rset_bool_rfd {
82     RSFD rfd_l;
83     RSFD rfd_r;
84     int  more_l;
85     int  more_r;
86     int term_index_l;
87     int term_index_r;
88     void *buf_l;
89     void *buf_r;
90     struct rset_bool_rfd *next;
91     struct rset_bool_info *info;
92 };    
93
94 static void *r_create (RSET ct, const struct rset_control *sel, void *parms)
95 {
96     rset_bool_parms *bool_parms = (rset_bool_parms *) parms;
97     struct rset_bool_info *info;
98
99     info = (struct rset_bool_info *) xmalloc (sizeof(*info));
100     info->key_size = bool_parms->key_size;
101     info->rset_l = bool_parms->rset_l;
102     info->rset_r = bool_parms->rset_r;
103     if (rset_is_volatile(info->rset_l) || rset_is_volatile(info->rset_r))
104         ct->flags |= RSET_FLAG_VOLATILE;
105     info->cmp = bool_parms->cmp;
106     info->rfd_list = NULL;
107     
108     info->term_index_s = info->rset_l->no_rset_terms;
109     ct->no_rset_terms =
110         info->rset_l->no_rset_terms + info->rset_r->no_rset_terms;
111     ct->rset_terms = (RSET_TERM *)
112         xmalloc (sizeof (*ct->rset_terms) * ct->no_rset_terms);
113
114     memcpy (ct->rset_terms, info->rset_l->rset_terms,
115             info->rset_l->no_rset_terms * sizeof(*ct->rset_terms));
116     memcpy (ct->rset_terms + info->rset_l->no_rset_terms,
117             info->rset_r->rset_terms,
118             info->rset_r->no_rset_terms * sizeof(*ct->rset_terms));
119     return info;
120 }
121
122 static RSFD r_open (RSET ct, int flag)
123 {
124     struct rset_bool_info *info = (struct rset_bool_info *) ct->buf;
125     struct rset_bool_rfd *rfd;
126
127     if (flag & RSETF_WRITE)
128     {
129         logf (LOG_FATAL, "bool set type is read-only");
130         return NULL;
131     }
132     rfd = (struct rset_bool_rfd *) xmalloc (sizeof(*rfd));
133     rfd->next = info->rfd_list;
134     info->rfd_list = rfd;
135     rfd->info = info;
136
137     rfd->buf_l = xmalloc (info->key_size);
138     rfd->buf_r = xmalloc (info->key_size);
139     rfd->rfd_l = rset_open (info->rset_l, RSETF_READ);
140     rfd->rfd_r = rset_open (info->rset_r, RSETF_READ);
141     rfd->more_l = rset_read (info->rset_l, rfd->rfd_l, rfd->buf_l,
142                              &rfd->term_index_l);
143     rfd->more_r = rset_read (info->rset_r, rfd->rfd_r, rfd->buf_r,
144                              &rfd->term_index_r);
145     return rfd;
146 }
147
148 static void r_close (RSFD rfd)
149 {
150     struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
151     struct rset_bool_rfd **rfdp;
152     
153     for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
154         if (*rfdp == rfd)
155         {
156             xfree ((*rfdp)->buf_l);
157             xfree ((*rfdp)->buf_r);
158             rset_close (info->rset_l, (*rfdp)->rfd_l);
159             rset_close (info->rset_r, (*rfdp)->rfd_r);
160             *rfdp = (*rfdp)->next;
161             xfree (rfd);
162             return;
163         }
164     logf (LOG_FATAL, "r_close but no rfd match!");
165     assert (0);
166 }
167
168 static void r_delete (RSET ct)
169 {
170     struct rset_bool_info *info = (struct rset_bool_info *) ct->buf;
171
172     assert (info->rfd_list == NULL);
173     xfree (ct->rset_terms);
174     rset_delete (info->rset_l);
175     rset_delete (info->rset_r);
176     xfree (info);
177 }
178
179 static void r_rewind (RSFD rfd)
180 {
181     struct rset_bool_info *info = ((struct rset_bool_rfd*)rfd)->info;
182     struct rset_bool_rfd *p = (struct rset_bool_rfd *) rfd;
183
184     logf (LOG_DEBUG, "rsbool_rewind");
185     rset_rewind (info->rset_l, p->rfd_l);
186     rset_rewind (info->rset_r, p->rfd_r);
187     p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l, &p->term_index_l);
188     p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r, &p->term_index_r);
189 }
190
191 static int r_count (RSET ct)
192 {
193     return 0;
194 }
195
196 static int r_read_and (RSFD rfd, void *buf, int *term_index)
197 {
198     struct rset_bool_rfd *p = (struct rset_bool_rfd *) rfd;
199     struct rset_bool_info *info = p->info;
200
201     while (p->more_l && p->more_r)
202     {
203         int cmp;
204
205         cmp = (*info->cmp)(p->buf_l, p->buf_r);
206         if (!cmp)
207         {
208             memcpy (buf, p->buf_l, info->key_size);
209             *term_index = p->term_index_l;
210             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
211                                    &p->term_index_l);
212             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
213                                    &p->term_index_r);
214             return 1;
215         }
216         else if (cmp == 1)
217         {
218             memcpy (buf, p->buf_r, info->key_size);
219
220             *term_index = p->term_index_r + info->term_index_s;
221             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
222                                    &p->term_index_r);
223             return 1;
224         }
225         else if (cmp == -1)
226         {
227             memcpy (buf, p->buf_l, info->key_size);
228             *term_index = p->term_index_l;
229             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
230                                    &p->term_index_l);
231             return 1;
232         }
233         else if (cmp > 1)
234             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
235                                    &p->term_index_r);
236         else
237             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
238                                    &p->term_index_l);
239     }
240     while (p->more_l)
241             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
242                                    &p->term_index_l);
243     while (p->more_r)
244             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
245                                    &p->term_index_r);
246     return 0;
247 }
248
249 static int r_read_or (RSFD rfd, void *buf, int *term_index)
250 {
251     struct rset_bool_rfd *p = (struct rset_bool_rfd *) rfd;
252     struct rset_bool_info *info = p->info;
253
254     while (p->more_l || p->more_r)
255     {
256         int cmp;
257
258         if (p->more_l && p->more_r)
259             cmp = (*info->cmp)(p->buf_l, p->buf_r);
260         else if (p->more_r)
261             cmp = 2;
262         else
263             cmp = -2;
264         if (!cmp)
265         {
266             memcpy (buf, p->buf_l, info->key_size);
267             *term_index = p->term_index_l;
268             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
269                                    &p->term_index_l);
270             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
271                                    &p->term_index_r);
272             return 1;
273         }
274         else if (cmp > 0)
275         {
276             memcpy (buf, p->buf_r, info->key_size);
277             *term_index = p->term_index_r + info->term_index_s;
278             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
279                                    &p->term_index_r);
280             return 1;
281         }
282         else
283         {
284             memcpy (buf, p->buf_l, info->key_size);
285             *term_index = p->term_index_l;
286             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
287                                    &p->term_index_l);
288             return 1;
289         }
290     }
291     return 0;
292 }
293
294 static int r_read_not (RSFD rfd, void *buf, int *term_index)
295 {
296     struct rset_bool_rfd *p = (struct rset_bool_rfd *) rfd;
297     struct rset_bool_info *info = p->info;
298
299     while (p->more_l || p->more_r)
300     {
301         int cmp;
302
303         if (p->more_l && p->more_r)
304             cmp = (*info->cmp)(p->buf_l, p->buf_r);
305         else if (p->more_r)
306             cmp = 2;
307         else
308             cmp = -2;
309         if (cmp < -1)
310         {
311             memcpy (buf, p->buf_l, info->key_size);
312             *term_index = p->term_index_l;
313             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
314                                    &p->term_index_l);
315             return 1;
316         }
317         else if (cmp > 1)
318             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
319                                    &p->term_index_r);
320         else
321         {
322             memcpy (buf, p->buf_l, info->key_size);
323             do
324             {
325                 p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
326                                        &p->term_index_l);
327                 if (!p->more_l)
328                     break;
329                 cmp = (*info->cmp)(p->buf_l, buf);
330             } while (cmp >= -1 && cmp <= 1);
331             do
332             {
333                 p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
334                                        &p->term_index_r);
335                 if (!p->more_r)
336                     break;
337                 cmp = (*info->cmp)(p->buf_r, buf);
338             } while (cmp >= -1 && cmp <= 1);
339         }
340     }
341     return 0;
342 }
343
344
345 static int r_write (RSFD rfd, const void *buf)
346 {
347     logf (LOG_FATAL, "bool set type is read-only");
348     return -1;
349 }
350