1 /* $Id: trunc.c,v 1.28.2.3 2005-01-23 15:06:21 adam Exp $
2 Copyright (C) 1995-2005
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;
147 parms.cmp = key_compare_it;
148 parms.key_size = sizeof(struct it_key);
149 parms.temp_path = res_get (zi->res, "setTmpDir");
150 parms.rset_term = rset_term_create (term, length, flags, term_type);
151 result = rset_create (rset_kind_temp, &parms);
152 result_rsfd = rset_open (result, RSETF_WRITE);
154 if (to - from > merge_chunk)
159 int i, i_add = (to-from)/merge_chunk + 1;
160 struct trunc_info *ti;
162 int rsmax = (to-from)/i_add + 1;
164 rset = (RSET *) xmalloc (sizeof(*rset) * rsmax);
165 rsfd = (RSFD *) xmalloc (sizeof(*rsfd) * rsmax);
167 for (i = from; i < to; i += i_add)
170 rset[rscur] = rset_trunc_r (zi, term, length, flags,
172 merge_chunk, preserve_position,
175 rset[rscur] = rset_trunc_r (zi, term, length, flags,
177 merge_chunk, preserve_position,
181 ti = heap_init (rscur, sizeof(struct it_key), key_compare_it);
182 for (i = rscur; --i >= 0; )
184 rsfd[i] = rset_open (rset[i], RSETF_READ);
185 if (rset_read (rset[i], rsfd[i], ti->tmpbuf, &term_index))
186 heap_insert (ti, ti->tmpbuf, i);
189 rset_close (rset[i], rsfd[i]);
190 rset_delete (rset[i]);
195 int n = ti->indx[ti->ptr[1]];
197 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
202 if (!rset_read (rset[n], rsfd[n], ti->tmpbuf, &term_index))
205 rset_close (rset[n], rsfd[n]);
206 rset_delete (rset[n]);
209 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
212 heap_insert (ti, ti->tmpbuf, n);
221 else if (zi->reg->isam)
225 struct trunc_info *ti;
227 ispt = (ISPT *) xmalloc (sizeof(*ispt) * (to-from));
229 ti = heap_init (to-from, sizeof(struct it_key),
231 for (i = to-from; --i >= 0; )
233 ispt[i] = is_position (zi->reg->isam, isam_p[from+i]);
234 if (is_readkey (ispt[i], ti->tmpbuf))
235 heap_insert (ti, ti->tmpbuf, i);
237 is_pt_free (ispt[i]);
241 int n = ti->indx[ti->ptr[1]];
243 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
245 if (preserve_position)
247 /* section that preserve all keys */
249 if (is_readkey (ispt[n], ti->tmpbuf))
250 heap_insert (ti, ti->tmpbuf, n);
252 is_pt_free (ispt[n]);
256 /* section that preserve all keys with unique sysnos */
259 if (!is_readkey (ispt[n], ti->tmpbuf))
262 is_pt_free (ispt[n]);
265 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
268 heap_insert (ti, ti->tmpbuf, n);
277 else if (zi->reg->isamc)
281 struct trunc_info *ti;
283 ispt = (ISAMC_PP *) xmalloc (sizeof(*ispt) * (to-from));
285 ti = heap_init (to-from, sizeof(struct it_key),
287 for (i = to-from; --i >= 0; )
289 ispt[i] = isc_pp_open (zi->reg->isamc, isam_p[from+i]);
290 if (isc_pp_read (ispt[i], ti->tmpbuf))
291 heap_insert (ti, ti->tmpbuf, i);
293 isc_pp_close (ispt[i]);
297 int n = ti->indx[ti->ptr[1]];
299 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
301 if (preserve_position)
304 if (isc_pp_read (ispt[n], ti->tmpbuf))
305 heap_insert (ti, ti->tmpbuf, n);
307 isc_pp_close (ispt[n]);
313 if (!isc_pp_read (ispt[n], ti->tmpbuf))
316 isc_pp_close (ispt[n]);
319 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
322 heap_insert (ti, ti->tmpbuf, n);
332 else if (zi->reg->isamd)
336 struct trunc_info *ti;
338 ispt = (ISAMD_PP *) xmalloc (sizeof(*ispt) * (to-from));
340 ti = heap_init (to-from, sizeof(struct it_key),
342 for (i = to-from; --i >= 0; )
344 logf(LOG_FATAL, "isam_d does not (currently) support truncs");
346 /*ispt[i] = isamd_pp_open (zi->reg->isamd, isam_p[from+i]); */
347 if (isamd_pp_read (ispt[i], ti->tmpbuf))
348 heap_insert (ti, ti->tmpbuf, i);
350 isamd_pp_close (ispt[i]);
354 int n = ti->indx[ti->ptr[1]];
356 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
359 /* section that preserve all keys */
361 if (isamd_pp_read (ispt[n], ti->tmpbuf))
362 heap_insert (ti, ti->tmpbuf, n);
364 isamd_pp_close (ispt[n]);
366 /* section that preserve all keys with unique sysnos */
369 if (!isamd_pp_read (ispt[n], ti->tmpbuf))
372 isamd_pp_close (ispt[n]);
375 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
378 heap_insert (ti, ti->tmpbuf, n);
387 else if (zi->reg->isams)
391 struct trunc_info *ti;
394 ispt = (ISAMS_PP *) xmalloc (sizeof(*ispt) * (to-from));
396 ti = heap_init (to-from, sizeof(struct it_key),
398 for (i = to-from; --i >= 0; )
400 ispt[i] = isams_pp_open (zi->reg->isams, isam_p[from+i]);
401 if (isams_pp_read (ispt[i], ti->tmpbuf))
402 heap_insert (ti, ti->tmpbuf, i);
404 isams_pp_close (ispt[i]);
408 int n = ti->indx[ti->ptr[1]];
410 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
414 if (!isams_pp_read (ispt[n], ti->tmpbuf))
417 isams_pp_close (ispt[n]);
420 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
423 heap_insert (ti, ti->tmpbuf, n);
431 else if (zi->reg->isamb)
435 struct trunc_info *ti;
437 ispt = (ISAMB_PP *) xmalloc (sizeof(*ispt) * (to-from));
439 ti = heap_init (to-from, sizeof(struct it_key),
441 for (i = to-from; --i >= 0; )
443 if (isam_p[from+i]) {
444 ispt[i] = isamb_pp_open (zi->reg->isamb, isam_p[from+i]);
445 if (isamb_pp_read (ispt[i], ti->tmpbuf))
446 heap_insert (ti, ti->tmpbuf, i);
448 isamb_pp_close (ispt[i]);
453 int n = ti->indx[ti->ptr[1]];
455 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
458 if (preserve_position)
461 if (isamb_pp_read (ispt[n], ti->tmpbuf))
462 heap_insert (ti, ti->tmpbuf, n);
464 isamb_pp_close (ispt[n]);
470 if (!isamb_pp_read (ispt[n], ti->tmpbuf))
473 isamb_pp_close (ispt[n]);
476 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
479 heap_insert (ti, ti->tmpbuf, n);
489 logf (LOG_WARN, "Unknown isam set in rset_trunc_r");
491 parms.rset_term->nn = nn;
492 rset_close (result, result_rsfd);
496 static int isams_trunc_cmp (const void *p1, const void *p2)
498 ISAMS_P i1 = *(ISAMS_P*) p1;
499 ISAMS_P i2 = *(ISAMS_P*) p2;
504 static int isam_trunc_cmp (const void *p1, const void *p2)
506 ISAM_P i1 = *(ISAM_P*) p1;
507 ISAM_P i2 = *(ISAM_P*) p2;
510 d = is_type (i1) - is_type (i2);
513 return is_block (i1) - is_block (i2);
516 static int isamc_trunc_cmp (const void *p1, const void *p2)
518 ISAMC_P i1 = *(ISAMC_P*) p1;
519 ISAMC_P i2 = *(ISAMC_P*) p2;
522 d = isc_type (i1) - isc_type (i2);
525 return isc_block (i1) - isc_block (i2);
527 static int isamd_trunc_cmp (const void *p1, const void *p2)
529 ISAMD_P i1 = *(ISAMD_P*) p1;
530 ISAMD_P i2 = *(ISAMD_P*) p2;
533 d = isamd_type (i1) - isamd_type (i2);
536 return isamd_block (i1) - isamd_block (i2);
539 RSET rset_trunc (ZebraHandle zi, ISAMS_P *isam_p, int no,
540 const char *term, int length, const char *flags,
541 int preserve_position, int term_type)
543 logf (LOG_DEBUG, "rset_trunc no=%d", no);
546 rset_null_parms parms;
547 parms.rset_term = rset_term_create (term, length, flags, term_type);
548 return rset_create (rset_kind_null, &parms);
554 rset_isams_parms parms;
557 parms.is = zi->reg->isams;
558 parms.rset_term = rset_term_create (term, length, flags,
560 return rset_create (rset_kind_isams, &parms);
562 qsort (isam_p, no, sizeof(*isam_p), isams_trunc_cmp);
564 else if (zi->reg->isam)
568 rset_isam_parms parms;
571 parms.is = zi->reg->isam;
572 parms.rset_term = rset_term_create (term, length, flags,
574 return rset_create (rset_kind_isam, &parms);
576 qsort (isam_p, no, sizeof(*isam_p), isam_trunc_cmp);
578 else if (zi->reg->isamc)
582 rset_isamc_parms parms;
584 parms.key_size = sizeof(struct it_key);
585 parms.cmp = key_compare_it;
587 parms.is = zi->reg->isamc;
588 parms.rset_term = rset_term_create (term, length, flags,
590 return rset_create (rset_kind_isamc, &parms);
595 rset_m_or_parms parms;
597 parms.key_size = sizeof(struct it_key);
598 parms.cmp = key_compare_it;
599 parms.isc = zi->reg->isamc;
600 parms.isam_positions = isam_p;
601 parms.no_isam_positions = no;
602 parms.no_save_positions = 100000;
603 parms.rset_term = rset_term_create (term, length, flags,
605 return rset_create (rset_kind_m_or, &parms);
608 qsort (isam_p, no, sizeof(*isam_p), isamc_trunc_cmp);
610 else if (zi->reg->isamd)
614 rset_isamd_parms parms;
616 logf(LOG_FATAL, "isam_d does not (currently) support truncs");
618 /* parms.pos = *isam_p; */
619 parms.is = zi->reg->isamd;
620 parms.rset_term = rset_term_create (term, length, flags,
622 return rset_create (rset_kind_isamd, &parms);
624 #if NEW_TRUNC_NOT_DONE_FOR_ISAM_D
627 rset_m_or_parms parms;
629 parms.key_size = sizeof(struct it_key);
630 parms.cmp = key_compare_it;
632 parms.isamd=zi->reg->isamd;
633 parms.isam_positions = isam_p;
634 parms.no_isam_positions = no;
635 parms.no_save_positions = 100000;
636 parms.rset_term = rset_term_create (term, length, flags);
637 return rset_create (rset_kind_m_or, &parms);
640 qsort (isam_p, no, sizeof(*isam_p), isamd_trunc_cmp);
642 else if (zi->reg->isamb)
646 rset_isamb_parms parms;
648 parms.key_size = sizeof(struct it_key);
649 parms.cmp = key_compare_it;
651 parms.is = zi->reg->isamb;
652 parms.rset_term = rset_term_create (term, length, flags,
654 if (res_get(zi->res, "rsetforward"))
655 return rset_create (rset_kind_isamb_forward, &parms);
657 return rset_create (rset_kind_isamb, &parms);
659 qsort (isam_p, no, sizeof(*isam_p), isamd_trunc_cmp);
663 logf (LOG_WARN, "Unknown isam set in rset_trunc");
664 return rset_create (rset_kind_null, NULL);
666 return rset_trunc_r (zi, term, length, flags, isam_p, 0, no, 100,
667 preserve_position, term_type);