Home | History | Annotate | Line # | Download | only in sort
append.c revision 1.1.1.1
      1 /*-
      2  * Copyright (c) 1993
      3  *	The Regents of the University of California.  All rights reserved.
      4  *
      5  * This code is derived from software contributed to Berkeley by
      6  * Peter McIlroy.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed by the University of
     19  *	California, Berkeley and its contributors.
     20  * 4. Neither the name of the University nor the names of its contributors
     21  *    may be used to endorse or promote products derived from this software
     22  *    without specific prior written permission.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34  * SUCH DAMAGE.
     35  */
     36 
     37 #ifndef lint
     38 static char sccsid[] = "@(#)append.c	8.1 (Berkeley) 6/6/93";
     39 #endif /* not lint */
     40 
     41 #include "sort.h"
     42 
     43 #include <stdlib.h>
     44 #include <string.h>
     45 
     46 #define OUTPUT {							\
     47 	if ((n = cpos - ppos) > 1) {					\
     48 		for (; ppos < cpos; ++ppos)				\
     49 			*ppos -= odepth;				\
     50 		ppos -= n;						\
     51 		radixsort(ppos, n, wts1, REC_D);			\
     52 		for (; ppos < cpos; ppos++) {				\
     53 			prec = (RECHEADER *) (*ppos - sizeof(TRECHEADER));\
     54 			put(prec, fd);					\
     55 		}							\
     56 	} else put(prec, fd);						\
     57 }
     58 
     59 /*
     60  * copy sorted lines to output; check for uniqueness
     61  */
     62 void
     63 append(keylist, nelem, depth, fd, put, ftbl)
     64 	u_char **keylist;
     65 	int nelem;
     66 	register int depth;
     67 	FILE *fd;
     68 	void (*put)(RECHEADER *, FILE *);
     69 	struct field *ftbl;
     70 {
     71 	register u_char *wts, *wts1;
     72 	register n, odepth;
     73 	register u_char **cpos, **ppos, **lastkey;
     74 	register u_char *cend, *pend, *start;
     75 	register struct recheader *crec, *prec;
     76 
     77 	if (*keylist == '\0' && UNIQUE)
     78 		return;
     79 	wts1 = wts = ftbl[0].weights;
     80 	if ((!UNIQUE) && SINGL_FLD) {
     81 		if (ftbl[0].flags & F && ftbl[0].flags & R)
     82 			wts1 = Rascii;
     83 		else if (ftbl[0].flags & F)
     84 			wts1 = ascii;
     85 		odepth = depth;
     86 	}
     87 	lastkey = keylist + nelem;
     88 	depth += sizeof(TRECHEADER);
     89 	if (SINGL_FLD && (UNIQUE || wts1 != wts)) {
     90 		ppos = keylist;
     91 		prec = (RECHEADER *) (*ppos - depth);
     92 		if (UNIQUE)
     93 			put(prec, fd);
     94 		for (cpos = keylist+1; cpos < lastkey; cpos++) {
     95 			crec = (RECHEADER *) (*cpos - depth);
     96 			if (crec->length  == prec->length) {
     97 				pend = (u_char *) &prec->offset + prec->length;
     98 				cend = (u_char *) &crec->offset + crec->length;
     99 				for (start = *cpos; cend >= start; cend--) {
    100 					if (wts[*cend] != wts[*pend])
    101 						break;
    102 					pend--;
    103 				}
    104 				if (pend + 1 != *ppos) {
    105 					if (!UNIQUE) {
    106 						OUTPUT;
    107 					} else
    108 						put(crec, fd);
    109 					ppos = cpos;
    110 					prec = crec;
    111 				}
    112 			} else {
    113 				if (!UNIQUE) {
    114 					OUTPUT;
    115 				} else
    116 					put(crec, fd);
    117 				ppos = cpos;
    118 				prec = crec;
    119 			}
    120 		}
    121 		if (!UNIQUE)  { OUTPUT; }
    122 	} else if (UNIQUE) {
    123 		ppos = keylist;
    124 		prec = (RECHEADER *) (*ppos - depth);
    125 		put(prec, fd);
    126 		for (cpos = keylist+1; cpos < lastkey; cpos++) {
    127 			crec = (RECHEADER *) (*cpos - depth);
    128 			if (crec->offset == prec->offset) {
    129 				pend = (u_char *) &prec->offset + prec->offset;
    130 				cend = (u_char *) &crec->offset + crec->offset;
    131 				for (start = *cpos; cend >= start; cend--) {
    132 					if (wts[*cend] != wts[*pend])
    133 						break;
    134 					pend--;
    135 				}
    136 				if (pend + 1 != *ppos) {
    137 					ppos = cpos;
    138 					prec = crec;
    139 					put(prec, fd);
    140 				}
    141 			} else {
    142 				ppos = cpos;
    143 				prec = crec;
    144 				put(prec, fd);
    145 			}
    146 		}
    147 	} else for (cpos = keylist; cpos < lastkey; cpos++) {
    148 		crec = (RECHEADER *) (*cpos - depth);
    149 		put(crec, fd);
    150 	}
    151 }
    152 
    153 /*
    154  * output the already sorted eol bin.
    155  */
    156 void
    157 rd_append(binno, infl0, nfiles, outfd, buffer, bufend)
    158 	u_char *buffer, *bufend;
    159 	int binno, nfiles;
    160 	union f_handle infl0;
    161 	FILE *outfd;
    162 {
    163 	struct recheader *rec;
    164 	rec = (RECHEADER *) buffer;
    165 	if (!getnext(binno, infl0, nfiles, (RECHEADER *) buffer, bufend, 0)) {
    166 		putline(rec, outfd);
    167 		while (getnext(binno, infl0, nfiles, (RECHEADER *) buffer,
    168 			bufend, 0) == 0) {
    169 			if (!UNIQUE)
    170 				putline(rec, outfd);
    171 		}
    172 	}
    173 }
    174 
    175 /*
    176  * append plain text--used after sorting the biggest bin.
    177  */
    178 void
    179 concat(a, b)
    180 	FILE *a, *b;
    181 {
    182         int nread;
    183         char buffer[4096];
    184 
    185 	rewind(b);
    186         while ((nread = fread(buffer, 1, 4096, b)) > 0)
    187                 EWRITE(buffer, 1, nread, a);
    188 }
    189