Hits per term. Returned in SearchResult-1
[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.17 2002-03-20 20:24:30 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     return 0;
241 }
242
243 static int r_read_or (RSFD rfd, void *buf, int *term_index)
244 {
245     struct rset_bool_rfd *p = (struct rset_bool_rfd *) rfd;
246     struct rset_bool_info *info = p->info;
247
248     while (p->more_l || p->more_r)
249     {
250         int cmp;
251
252         if (p->more_l && p->more_r)
253             cmp = (*info->cmp)(p->buf_l, p->buf_r);
254         else if (p->more_r)
255             cmp = 2;
256         else
257             cmp = -2;
258         if (!cmp)
259         {
260             memcpy (buf, p->buf_l, info->key_size);
261             *term_index = p->term_index_l;
262             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
263                                    &p->term_index_l);
264             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
265                                    &p->term_index_r);
266             return 1;
267         }
268         else if (cmp > 0)
269         {
270             memcpy (buf, p->buf_r, info->key_size);
271             *term_index = p->term_index_r + info->term_index_s;
272             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
273                                    &p->term_index_r);
274             return 1;
275         }
276         else
277         {
278             memcpy (buf, p->buf_l, info->key_size);
279             *term_index = p->term_index_l;
280             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
281                                    &p->term_index_l);
282             return 1;
283         }
284     }
285     return 0;
286 }
287
288 static int r_read_not (RSFD rfd, void *buf, int *term_index)
289 {
290     struct rset_bool_rfd *p = (struct rset_bool_rfd *) rfd;
291     struct rset_bool_info *info = p->info;
292
293     while (p->more_l || p->more_r)
294     {
295         int cmp;
296
297         if (p->more_l && p->more_r)
298             cmp = (*info->cmp)(p->buf_l, p->buf_r);
299         else if (p->more_r)
300             cmp = 2;
301         else
302             cmp = -2;
303         if (cmp < -1)
304         {
305             memcpy (buf, p->buf_l, info->key_size);
306             *term_index = p->term_index_l;
307             p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
308                                    &p->term_index_l);
309             return 1;
310         }
311         else if (cmp > 1)
312             p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
313                                    &p->term_index_r);
314         else
315         {
316             memcpy (buf, p->buf_l, info->key_size);
317             do
318             {
319                 p->more_l = rset_read (info->rset_l, p->rfd_l, p->buf_l,
320                                        &p->term_index_l);
321                 if (!p->more_l)
322                     break;
323                 cmp = (*info->cmp)(p->buf_l, buf);
324             } while (cmp >= -1 && cmp <= 1);
325             do
326             {
327                 p->more_r = rset_read (info->rset_r, p->rfd_r, p->buf_r,
328                                        &p->term_index_r);
329                 if (!p->more_r)
330                     break;
331                 cmp = (*info->cmp)(p->buf_r, buf);
332             } while (cmp >= -1 && cmp <= 1);
333         }
334     }
335     return 0;
336 }
337
338
339 static int r_write (RSFD rfd, const void *buf)
340 {
341     logf (LOG_FATAL, "bool set type is read-only");
342     return -1;
343 }
344