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