2 * Copyright (C) 1994-1999, Index Data
4 * Sebastian Hammer, Adam Dickmeiss
7 * Revision 1.9 1999-07-13 14:45:42 adam
10 * Revision 1.8 1999/05/26 07:49:14 adam
13 * Revision 1.7 1998/09/22 10:03:46 adam
14 * Changed result sets to be persistent in the sense that they can
15 * be re-searched if needed.
16 * Fixed memory leak in rsm_or.
18 * Revision 1.6 1998/03/05 08:36:28 adam
19 * New result set model.
21 * Revision 1.5 1997/12/18 10:54:25 adam
22 * New method result set method rs_hits that returns the number of
23 * hits in result-set (if known). The ranked result set returns real
24 * number of hits but only when not combined with other operands.
26 * Revision 1.4 1997/10/31 12:37:55 adam
27 * Code calls xfree() instead of free().
29 * Revision 1.3 1997/09/09 13:38:16 adam
30 * Partial port to WIN95/NT.
32 * Revision 1.2 1996/12/23 15:30:49 adam
35 * Revision 1.1 1996/12/20 11:07:21 adam
36 * Implemented Multi-or result set.
50 static void *r_create(RSET ct, const struct rset_control *sel, void *parms);
51 static RSFD r_open (RSET ct, int flag);
52 static void r_close (RSFD rfd);
53 static void r_delete (RSET ct);
54 static void r_rewind (RSFD rfd);
55 static int r_count (RSET ct);
56 static int r_read (RSFD rfd, void *buf, int *term_index);
57 static int r_write (RSFD rfd, const void *buf);
59 static const struct rset_control control =
72 const struct rset_control *rset_kind_m_or = &control;
74 struct rset_mor_info {
77 int (*cmp)(const void *p1, const void *p2);
79 ISAM_P *isam_positions;
81 int no_isam_positions;
82 int no_save_positions;
83 struct rset_mor_rfd *rfd_list;
91 int (*cmp)(const void *p1, const void *p2);
103 struct rset_mor_rfd *next;
104 struct rset_mor_info *info;
105 struct trunc_info *ti;
108 static void heap_swap (struct trunc_info *ti, int i1, int i2)
113 ti->ptr[i1] = ti->ptr[i2];
117 static void heap_delete (struct trunc_info *ti)
119 int cur = 1, child = 2;
121 heap_swap (ti, 1, ti->heapnum--);
122 while (child <= ti->heapnum) {
123 if (child < ti->heapnum &&
124 (*ti->cmp)(ti->heap[ti->ptr[child]],
125 ti->heap[ti->ptr[1+child]]) > 0)
127 if ((*ti->cmp)(ti->heap[ti->ptr[cur]],
128 ti->heap[ti->ptr[child]]) > 0)
130 heap_swap (ti, cur, child);
139 static void heap_insert (struct trunc_info *ti, const char *buf, int indx)
143 cur = ++(ti->heapnum);
144 memcpy (ti->heap[ti->ptr[cur]], buf, ti->keysize);
145 ti->indx[ti->ptr[cur]] = indx;
147 while (parent && (*ti->cmp)(ti->heap[ti->ptr[parent]],
148 ti->heap[ti->ptr[cur]]) > 0)
150 heap_swap (ti, cur, parent);
157 struct trunc_info *heap_init (int size, int key_size,
158 int (*cmp)(const void *p1, const void *p2))
160 struct trunc_info *ti = (struct trunc_info *) xmalloc (sizeof(*ti));
165 ti->keysize = key_size;
167 ti->indx = (int *) xmalloc (size * sizeof(*ti->indx));
168 ti->heap = (char **) xmalloc (size * sizeof(*ti->heap));
169 ti->ptr = (int *) xmalloc (size * sizeof(*ti->ptr));
170 ti->swapbuf = (char *) xmalloc (ti->keysize);
171 ti->tmpbuf = (char *) xmalloc (ti->keysize);
172 ti->buf = (char *) xmalloc (size * ti->keysize);
173 for (i = size; --i >= 0; )
176 ti->heap[i] = ti->buf + ti->keysize * i;
181 static void heap_close (struct trunc_info *ti)
192 static void *r_create (RSET ct, const struct rset_control *sel, void *parms)
194 rset_m_or_parms *r_parms = (rset_m_or_parms *) parms;
195 struct rset_mor_info *info;
197 ct->flags |= RSET_FLAG_VOLATILE;
198 info = (struct rset_mor_info *) xmalloc (sizeof(*info));
199 info->key_size = r_parms->key_size;
200 assert (info->key_size > 1);
201 info->cmp = r_parms->cmp;
203 info->no_save_positions = r_parms->no_save_positions;
205 info->isc = r_parms->isc;
206 info->no_isam_positions = r_parms->no_isam_positions;
207 info->isam_positions = (ISAM_P *)
208 xmalloc (sizeof(*info->isam_positions) * info->no_isam_positions);
209 memcpy (info->isam_positions, r_parms->isam_positions,
210 sizeof(*info->isam_positions) * info->no_isam_positions);
211 info->rfd_list = NULL;
213 ct->no_rset_terms = 1;
214 ct->rset_terms = (RSET_TERM *) xmalloc (sizeof(*ct->rset_terms));
215 ct->rset_terms[0] = r_parms->rset_term;
219 static RSFD r_open (RSET ct, int flag)
221 struct rset_mor_rfd *rfd;
222 struct rset_mor_info *info = (struct rset_mor_info *) ct->buf;
225 if (flag & RSETF_WRITE)
227 logf (LOG_FATAL, "m_or set type is read-only");
230 rfd = (struct rset_mor_rfd *) xmalloc (sizeof(*rfd));
232 rfd->next = info->rfd_list;
234 info->rfd_list = rfd;
236 rfd->ispt = (ISAMC_PP *)
237 xmalloc (sizeof(*rfd->ispt) * info->no_isam_positions);
239 rfd->ti = heap_init (info->no_isam_positions, info->key_size, info->cmp);
241 ct->rset_terms[0]->nn = 0;
242 for (i = 0; i<info->no_isam_positions; i++)
244 rfd->ispt[i] = isc_pp_open (info->isc, info->isam_positions[i]);
246 ct->rset_terms[0]->nn += isc_pp_num (rfd->ispt[i]);
248 if (isc_pp_read (rfd->ispt[i], rfd->ti->tmpbuf))
249 heap_insert (rfd->ti, rfd->ti->tmpbuf, i);
252 isc_pp_close (rfd->ispt[i]);
256 rfd->position = info->no_save_positions;
261 static void r_close (RSFD rfd)
263 struct rset_mor_info *info = ((struct rset_mor_rfd*)rfd)->info;
264 struct rset_mor_rfd **rfdp;
267 for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next)
270 *rfdp = (*rfdp)->next;
272 heap_close (((struct rset_mor_rfd *) rfd)->ti);
273 for (i = 0; i<info->no_isam_positions; i++)
274 if (((struct rset_mor_rfd *) rfd)->ispt[i])
275 isc_pp_close (((struct rset_mor_rfd *) rfd)->ispt[i]);
276 xfree (((struct rset_mor_rfd *)rfd)->ispt);
280 logf (LOG_FATAL, "r_close but no rfd match!");
284 static void r_delete (RSET ct)
286 struct rset_mor_info *info = (struct rset_mor_info *) ct->buf;
289 assert (info->rfd_list == NULL);
290 xfree (info->isam_positions);
292 for (i = 0; i<ct->no_rset_terms; i++)
293 rset_term_destroy (ct->rset_terms[i]);
294 xfree (ct->rset_terms);
299 static void r_rewind (RSFD rfd)
303 static int r_count (RSET ct)
308 static int r_read (RSFD rfd, void *buf, int *term_index)
310 struct trunc_info *ti = ((struct rset_mor_rfd *) rfd)->ti;
311 int n = ti->indx[ti->ptr[1]];
316 memcpy (buf, ti->heap[ti->ptr[1]], ti->keysize);
317 if (((struct rset_mor_rfd *) rfd)->position)
319 if (isc_pp_read (((struct rset_mor_rfd *) rfd)->ispt[n], ti->tmpbuf))
322 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
323 ((struct rset_mor_rfd *) rfd)->position--;
324 heap_insert (ti, ti->tmpbuf, n);
332 if (!isc_pp_read (((struct rset_mor_rfd *) rfd)->ispt[n], ti->tmpbuf))
337 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
340 heap_insert (ti, ti->tmpbuf, n);
347 static int r_write (RSFD rfd, const void *buf)
349 logf (LOG_FATAL, "mor set type is read-only");