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