1 /* $Id: trunc.c,v 1.28 2003-03-26 16:41:48 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;
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 ispt[i] = isamb_pp_open (zi->reg->isamb, isam_p[from+i]);
444 if (isamb_pp_read (ispt[i], ti->tmpbuf))
445 heap_insert (ti, ti->tmpbuf, i);
447 isamb_pp_close (ispt[i]);
451 int n = ti->indx[ti->ptr[1]];
453 rset_write (result, result_rsfd, ti->heap[ti->ptr[1]]);
456 if (preserve_position)
459 if (isamb_pp_read (ispt[n], ti->tmpbuf))
460 heap_insert (ti, ti->tmpbuf, n);
462 isamb_pp_close (ispt[n]);
468 if (!isamb_pp_read (ispt[n], ti->tmpbuf))
471 isamb_pp_close (ispt[n]);
474 if ((*ti->cmp)(ti->tmpbuf, ti->heap[ti->ptr[1]]) > 1)
477 heap_insert (ti, ti->tmpbuf, n);
487 logf (LOG_WARN, "Unknown isam set in rset_trunc_r");
489 parms.rset_term->nn = nn;
490 rset_close (result, result_rsfd);
494 static int isams_trunc_cmp (const void *p1, const void *p2)
496 ISAMS_P i1 = *(ISAMS_P*) p1;
497 ISAMS_P i2 = *(ISAMS_P*) p2;
502 static int isam_trunc_cmp (const void *p1, const void *p2)
504 ISAM_P i1 = *(ISAM_P*) p1;
505 ISAM_P i2 = *(ISAM_P*) p2;
508 d = is_type (i1) - is_type (i2);
511 return is_block (i1) - is_block (i2);
514 static int isamc_trunc_cmp (const void *p1, const void *p2)
516 ISAMC_P i1 = *(ISAMC_P*) p1;
517 ISAMC_P i2 = *(ISAMC_P*) p2;
520 d = isc_type (i1) - isc_type (i2);
523 return isc_block (i1) - isc_block (i2);
525 static int isamd_trunc_cmp (const void *p1, const void *p2)
527 ISAMD_P i1 = *(ISAMD_P*) p1;
528 ISAMD_P i2 = *(ISAMD_P*) p2;
531 d = isamd_type (i1) - isamd_type (i2);
534 return isamd_block (i1) - isamd_block (i2);
537 RSET rset_trunc (ZebraHandle zi, ISAMS_P *isam_p, int no,
538 const char *term, int length, const char *flags,
539 int preserve_position, int term_type)
541 logf (LOG_DEBUG, "rset_trunc no=%d", no);
544 rset_null_parms parms;
545 parms.rset_term = rset_term_create (term, length, flags, term_type);
546 return rset_create (rset_kind_null, &parms);
552 rset_isams_parms parms;
555 parms.is = zi->reg->isams;
556 parms.rset_term = rset_term_create (term, length, flags,
558 return rset_create (rset_kind_isams, &parms);
560 qsort (isam_p, no, sizeof(*isam_p), isams_trunc_cmp);
562 else if (zi->reg->isam)
566 rset_isam_parms parms;
569 parms.is = zi->reg->isam;
570 parms.rset_term = rset_term_create (term, length, flags,
572 return rset_create (rset_kind_isam, &parms);
574 qsort (isam_p, no, sizeof(*isam_p), isam_trunc_cmp);
576 else if (zi->reg->isamc)
580 rset_isamc_parms parms;
582 parms.key_size = sizeof(struct it_key);
583 parms.cmp = key_compare_it;
585 parms.is = zi->reg->isamc;
586 parms.rset_term = rset_term_create (term, length, flags,
588 return rset_create (rset_kind_isamc, &parms);
593 rset_m_or_parms parms;
595 parms.key_size = sizeof(struct it_key);
596 parms.cmp = key_compare_it;
597 parms.isc = zi->reg->isamc;
598 parms.isam_positions = isam_p;
599 parms.no_isam_positions = no;
600 parms.no_save_positions = 100000;
601 parms.rset_term = rset_term_create (term, length, flags,
603 return rset_create (rset_kind_m_or, &parms);
606 qsort (isam_p, no, sizeof(*isam_p), isamc_trunc_cmp);
608 else if (zi->reg->isamd)
612 rset_isamd_parms parms;
614 logf(LOG_FATAL, "isam_d does not (currently) support truncs");
616 /* parms.pos = *isam_p; */
617 parms.is = zi->reg->isamd;
618 parms.rset_term = rset_term_create (term, length, flags,
620 return rset_create (rset_kind_isamd, &parms);
622 #if NEW_TRUNC_NOT_DONE_FOR_ISAM_D
625 rset_m_or_parms parms;
627 parms.key_size = sizeof(struct it_key);
628 parms.cmp = key_compare_it;
630 parms.isamd=zi->reg->isamd;
631 parms.isam_positions = isam_p;
632 parms.no_isam_positions = no;
633 parms.no_save_positions = 100000;
634 parms.rset_term = rset_term_create (term, length, flags);
635 return rset_create (rset_kind_m_or, &parms);
638 qsort (isam_p, no, sizeof(*isam_p), isamd_trunc_cmp);
640 else if (zi->reg->isamb)
644 rset_isamb_parms parms;
646 parms.key_size = sizeof(struct it_key);
647 parms.cmp = key_compare_it;
649 parms.is = zi->reg->isamb;
650 parms.rset_term = rset_term_create (term, length, flags,
652 return rset_create (rset_kind_isamb, &parms);
654 qsort (isam_p, no, sizeof(*isam_p), isamd_trunc_cmp);
658 logf (LOG_WARN, "Unknown isam set in rset_trunc");
659 return rset_create (rset_kind_null, NULL);
661 return rset_trunc_r (zi, term, length, flags, isam_p, 0, no, 100,
662 preserve_position, term_type);