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