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