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