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