1 /* $Id: trunc.c,v 1.27 2002-08-02 19:26:55 adam Exp $
2 Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
46 int (*cmp)(const void *p1, const void *p2);
53 static void heap_swap (struct trunc_info *ti, int i1, int i2)
58 ti->ptr[i1] = ti->ptr[i2];
62 static void heap_delete (struct trunc_info *ti)
64 int cur = 1, child = 2;
66 heap_swap (ti, 1, ti->heapnum--);
67 while (child <= ti->heapnum) {
68 if (child < ti->heapnum &&
69 (*ti->cmp)(ti->heap[ti->ptr[child]],
70 ti->heap[ti->ptr[1+child]]) > 0)
72 if ((*ti->cmp)(ti->heap[ti->ptr[cur]],
73 ti->heap[ti->ptr[child]]) > 0)
75 heap_swap (ti, cur, child);
84 static void heap_insert (struct trunc_info *ti, const char *buf, int indx)
88 cur = ++(ti->heapnum);
89 memcpy (ti->heap[ti->ptr[cur]], buf, ti->keysize);
90 ti->indx[ti->ptr[cur]] = indx;
92 while (parent && (*ti->cmp)(ti->heap[ti->ptr[parent]],
93 ti->heap[ti->ptr[cur]]) > 0)
95 heap_swap (ti, cur, parent);
101 static struct trunc_info *heap_init (int size, int key_size,
102 int (*cmp)(const void *p1,
105 struct trunc_info *ti = (struct trunc_info *) xmalloc (sizeof(*ti));
110 ti->keysize = key_size;
112 ti->indx = (int *) xmalloc (size * sizeof(*ti->indx));
113 ti->heap = (char **) xmalloc (size * sizeof(*ti->heap));
114 ti->ptr = (int *) xmalloc (size * sizeof(*ti->ptr));
115 ti->swapbuf = (char *) xmalloc (ti->keysize);
116 ti->tmpbuf = (char *) xmalloc (ti->keysize);
117 ti->buf = (char *) xmalloc (size * ti->keysize);
118 for (i = size; --i >= 0; )
121 ti->heap[i] = ti->buf + ti->keysize * i;
126 static void heap_close (struct trunc_info *ti)
137 static RSET rset_trunc_r (ZebraHandle zi, const char *term, int length,
138 const char *flags, ISAMS_P *isam_p, int from, int to,
139 int merge_chunk, int preserve_position,
144 rset_temp_parms parms;
146 parms.cmp = key_compare_it;
147 parms.key_size = sizeof(struct it_key);
148 parms.temp_path = res_get (zi->res, "setTmpDir");
149 parms.rset_term = rset_term_create (term, length, flags, term_type);
150 result = rset_create (rset_kind_temp, &parms);
151 result_rsfd = rset_open (result, RSETF_WRITE);
153 if (to - from > merge_chunk)
158 int i, i_add = (to-from)/merge_chunk + 1;
159 struct trunc_info *ti;
161 int rsmax = (to-from)/i_add + 1;
163 rset = (RSET *) xmalloc (sizeof(*rset) * rsmax);
164 rsfd = (RSFD *) xmalloc (sizeof(*rsfd) * rsmax);
166 for (i = from; i < to; i += i_add)
169 rset[rscur] = rset_trunc_r (zi, term, length, flags,
171 merge_chunk, preserve_position,
174 rset[rscur] = rset_trunc_r (zi, term, length, flags,
176 merge_chunk, preserve_position,
180 ti = heap_init (rscur, sizeof(struct it_key), key_compare_it);
181 for (i = rscur; --i >= 0; )
183 rsfd[i] = rset_open (rset[i], RSETF_READ);
184 if (rset_read (rset[i], rsfd[i], ti->tmpbuf, &term_index))
185 heap_insert (ti, ti->tmpbuf, i);
188 rset_close (rset[i], rsfd[i]);
189 rset_delete (rset[i]);
194 int n = ti->indx[ti->ptr[1]];
196 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
200 if (!rset_read (rset[n], rsfd[n], ti->tmpbuf, &term_index))
203 rset_close (rset[n], rsfd[n]);
204 rset_delete (rset[n]);
207 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
210 heap_insert (ti, ti->tmpbuf, n);
219 else if (zi->reg->isam)
223 struct trunc_info *ti;
225 ispt = (ISPT *) xmalloc (sizeof(*ispt) * (to-from));
227 ti = heap_init (to-from, sizeof(struct it_key),
229 for (i = to-from; --i >= 0; )
231 ispt[i] = is_position (zi->reg->isam, isam_p[from+i]);
232 if (is_readkey (ispt[i], ti->tmpbuf))
233 heap_insert (ti, ti->tmpbuf, i);
235 is_pt_free (ispt[i]);
239 int n = ti->indx[ti->ptr[1]];
241 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
242 if (preserve_position)
244 /* section that preserve all keys */
246 if (is_readkey (ispt[n], ti->tmpbuf))
247 heap_insert (ti, ti->tmpbuf, n);
249 is_pt_free (ispt[n]);
253 /* section that preserve all keys with unique sysnos */
256 if (!is_readkey (ispt[n], ti->tmpbuf))
259 is_pt_free (ispt[n]);
262 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
265 heap_insert (ti, ti->tmpbuf, n);
274 else if (zi->reg->isamc)
278 struct trunc_info *ti;
280 ispt = (ISAMC_PP *) xmalloc (sizeof(*ispt) * (to-from));
282 ti = heap_init (to-from, sizeof(struct it_key),
284 for (i = to-from; --i >= 0; )
286 ispt[i] = isc_pp_open (zi->reg->isamc, isam_p[from+i]);
287 if (isc_pp_read (ispt[i], ti->tmpbuf))
288 heap_insert (ti, ti->tmpbuf, i);
290 isc_pp_close (ispt[i]);
294 int n = ti->indx[ti->ptr[1]];
296 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
297 if (preserve_position)
300 if (isc_pp_read (ispt[n], ti->tmpbuf))
301 heap_insert (ti, ti->tmpbuf, n);
303 isc_pp_close (ispt[n]);
309 if (!isc_pp_read (ispt[n], ti->tmpbuf))
312 isc_pp_close (ispt[n]);
315 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
318 heap_insert (ti, ti->tmpbuf, n);
328 else if (zi->reg->isamd)
332 struct trunc_info *ti;
334 ispt = (ISAMD_PP *) xmalloc (sizeof(*ispt) * (to-from));
336 ti = heap_init (to-from, sizeof(struct it_key),
338 for (i = to-from; --i >= 0; )
340 logf(LOG_FATAL, "isam_d does not (currently) support truncs");
342 /*ispt[i] = isamd_pp_open (zi->reg->isamd, isam_p[from+i]); */
343 if (isamd_pp_read (ispt[i], ti->tmpbuf))
344 heap_insert (ti, ti->tmpbuf, i);
346 isamd_pp_close (ispt[i]);
350 int n = ti->indx[ti->ptr[1]];
352 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
354 /* section that preserve all keys */
356 if (isamd_pp_read (ispt[n], ti->tmpbuf))
357 heap_insert (ti, ti->tmpbuf, n);
359 isamd_pp_close (ispt[n]);
361 /* section that preserve all keys with unique sysnos */
364 if (!isamd_pp_read (ispt[n], ti->tmpbuf))
367 isamd_pp_close (ispt[n]);
370 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
373 heap_insert (ti, ti->tmpbuf, n);
382 else if (zi->reg->isams)
386 struct trunc_info *ti;
388 ispt = (ISAMS_PP *) xmalloc (sizeof(*ispt) * (to-from));
390 ti = heap_init (to-from, sizeof(struct it_key),
392 for (i = to-from; --i >= 0; )
394 ispt[i] = isams_pp_open (zi->reg->isams, isam_p[from+i]);
395 if (isams_pp_read (ispt[i], ti->tmpbuf))
396 heap_insert (ti, ti->tmpbuf, i);
398 isams_pp_close (ispt[i]);
402 int n = ti->indx[ti->ptr[1]];
404 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
407 if (!isams_pp_read (ispt[n], ti->tmpbuf))
410 isams_pp_close (ispt[n]);
413 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
416 heap_insert (ti, ti->tmpbuf, n);
424 else if (zi->reg->isamb)
428 struct trunc_info *ti;
430 ispt = (ISAMB_PP *) xmalloc (sizeof(*ispt) * (to-from));
432 ti = heap_init (to-from, sizeof(struct it_key),
434 for (i = to-from; --i >= 0; )
436 ispt[i] = isamb_pp_open (zi->reg->isamb, isam_p[from+i]);
437 if (isamb_pp_read (ispt[i], ti->tmpbuf))
438 heap_insert (ti, ti->tmpbuf, i);
440 isamb_pp_close (ispt[i]);
444 int n = ti->indx[ti->ptr[1]];
446 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
448 if (preserve_position)
451 if (isamb_pp_read (ispt[n], ti->tmpbuf))
452 heap_insert (ti, ti->tmpbuf, n);
454 isamb_pp_close (ispt[n]);
460 if (!isamb_pp_read (ispt[n], ti->tmpbuf))
463 isamb_pp_close (ispt[n]);
466 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
469 heap_insert (ti, ti->tmpbuf, n);
479 logf (LOG_WARN, "Unknown isam set in rset_trunc_r");
481 rset_close (result, result_rsfd);
485 static int isams_trunc_cmp (const void *p1, const void *p2)
487 ISAMS_P i1 = *(ISAMS_P*) p1;
488 ISAMS_P i2 = *(ISAMS_P*) p2;
493 static int isam_trunc_cmp (const void *p1, const void *p2)
495 ISAM_P i1 = *(ISAM_P*) p1;
496 ISAM_P i2 = *(ISAM_P*) p2;
499 d = is_type (i1) - is_type (i2);
502 return is_block (i1) - is_block (i2);
505 static int isamc_trunc_cmp (const void *p1, const void *p2)
507 ISAMC_P i1 = *(ISAMC_P*) p1;
508 ISAMC_P i2 = *(ISAMC_P*) p2;
511 d = isc_type (i1) - isc_type (i2);
514 return isc_block (i1) - isc_block (i2);
516 static int isamd_trunc_cmp (const void *p1, const void *p2)
518 ISAMD_P i1 = *(ISAMD_P*) p1;
519 ISAMD_P i2 = *(ISAMD_P*) p2;
522 d = isamd_type (i1) - isamd_type (i2);
525 return isamd_block (i1) - isamd_block (i2);
528 RSET rset_trunc (ZebraHandle zi, ISAMS_P *isam_p, int no,
529 const char *term, int length, const char *flags,
530 int preserve_position, int term_type)
532 logf (LOG_DEBUG, "rset_trunc no=%d", no);
535 rset_null_parms parms;
536 parms.rset_term = rset_term_create (term, length, flags, term_type);
537 return rset_create (rset_kind_null, &parms);
543 rset_isams_parms parms;
546 parms.is = zi->reg->isams;
547 parms.rset_term = rset_term_create (term, length, flags,
549 return rset_create (rset_kind_isams, &parms);
551 qsort (isam_p, no, sizeof(*isam_p), isams_trunc_cmp);
553 else if (zi->reg->isam)
557 rset_isam_parms parms;
560 parms.is = zi->reg->isam;
561 parms.rset_term = rset_term_create (term, length, flags,
563 return rset_create (rset_kind_isam, &parms);
565 qsort (isam_p, no, sizeof(*isam_p), isam_trunc_cmp);
567 else if (zi->reg->isamc)
571 rset_isamc_parms parms;
573 parms.key_size = sizeof(struct it_key);
574 parms.cmp = key_compare_it;
576 parms.is = zi->reg->isamc;
577 parms.rset_term = rset_term_create (term, length, flags,
579 return rset_create (rset_kind_isamc, &parms);
584 rset_m_or_parms parms;
586 parms.key_size = sizeof(struct it_key);
587 parms.cmp = key_compare_it;
588 parms.isc = zi->reg->isamc;
589 parms.isam_positions = isam_p;
590 parms.no_isam_positions = no;
591 parms.no_save_positions = 100000;
592 parms.rset_term = rset_term_create (term, length, flags,
594 return rset_create (rset_kind_m_or, &parms);
597 qsort (isam_p, no, sizeof(*isam_p), isamc_trunc_cmp);
599 else if (zi->reg->isamd)
603 rset_isamd_parms parms;
605 logf(LOG_FATAL, "isam_d does not (currently) support truncs");
607 /* parms.pos = *isam_p; */
608 parms.is = zi->reg->isamd;
609 parms.rset_term = rset_term_create (term, length, flags,
611 return rset_create (rset_kind_isamd, &parms);
613 #if NEW_TRUNC_NOT_DONE_FOR_ISAM_D
616 rset_m_or_parms parms;
618 parms.key_size = sizeof(struct it_key);
619 parms.cmp = key_compare_it;
621 parms.isamd=zi->reg->isamd;
622 parms.isam_positions = isam_p;
623 parms.no_isam_positions = no;
624 parms.no_save_positions = 100000;
625 parms.rset_term = rset_term_create (term, length, flags);
626 return rset_create (rset_kind_m_or, &parms);
629 qsort (isam_p, no, sizeof(*isam_p), isamd_trunc_cmp);
631 else if (zi->reg->isamb)
635 rset_isamb_parms parms;
637 parms.key_size = sizeof(struct it_key);
638 parms.cmp = key_compare_it;
640 parms.is = zi->reg->isamb;
641 parms.rset_term = rset_term_create (term, length, flags,
643 return rset_create (rset_kind_isamb, &parms);
645 qsort (isam_p, no, sizeof(*isam_p), isamd_trunc_cmp);
649 logf (LOG_WARN, "Unknown isam set in rset_trunc");
650 return rset_create (rset_kind_null, NULL);
652 return rset_trunc_r (zi, term, length, flags, isam_p, 0, no, 100,
653 preserve_position, term_type);