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