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