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 * %sccs.include.redist.c%
9 */
10
11 #ifndef lint
12 static char sccsid[] = "@(#)append.c 8.1 (Berkeley) 06/06/93";
13 #endif /* not lint */
14
15 #include "sort.h"
16
17 #include <stdlib.h>
18 #include <string.h>
19
20 #define OUTPUT { \
21 if ((n = cpos - ppos) > 1) { \
22 for (; ppos < cpos; ++ppos) \
23 *ppos -= odepth; \
24 ppos -= n; \
25 radixsort(ppos, n, wts1, REC_D); \
26 for (; ppos < cpos; ppos++) { \
27 prec = (RECHEADER *) (*ppos - sizeof(TRECHEADER));\
28 put(prec, fd); \
29 } \
30 } else put(prec, fd); \
31 }
32
33 /*
34 * copy sorted lines to output; check for uniqueness
35 */
36 void
append(keylist,nelem,depth,fd,put,ftbl)37 append(keylist, nelem, depth, fd, put, ftbl)
38 u_char **keylist;
39 int nelem;
40 register int depth;
41 FILE *fd;
42 void (*put)(RECHEADER *, FILE *);
43 struct field *ftbl;
44 {
45 register u_char *wts, *wts1;
46 register n, odepth;
47 register u_char **cpos, **ppos, **lastkey;
48 register u_char *cend, *pend, *start;
49 register struct recheader *crec, *prec;
50
51 if (*keylist == '\0' && UNIQUE)
52 return;
53 wts1 = wts = ftbl[0].weights;
54 if ((!UNIQUE) && SINGL_FLD) {
55 if (ftbl[0].flags & F && ftbl[0].flags & R)
56 wts1 = Rascii;
57 else if (ftbl[0].flags & F)
58 wts1 = ascii;
59 odepth = depth;
60 }
61 lastkey = keylist + nelem;
62 depth += sizeof(TRECHEADER);
63 if (SINGL_FLD && (UNIQUE || wts1 != wts)) {
64 ppos = keylist;
65 prec = (RECHEADER *) (*ppos - depth);
66 if (UNIQUE)
67 put(prec, fd);
68 for (cpos = keylist+1; cpos < lastkey; cpos++) {
69 crec = (RECHEADER *) (*cpos - depth);
70 if (crec->length == prec->length) {
71 pend = (u_char *) &prec->offset + prec->length;
72 cend = (u_char *) &crec->offset + crec->length;
73 for (start = *cpos; cend >= start; cend--) {
74 if (wts[*cend] != wts[*pend])
75 break;
76 pend--;
77 }
78 if (pend + 1 != *ppos) {
79 if (!UNIQUE) {
80 OUTPUT;
81 } else
82 put(crec, fd);
83 ppos = cpos;
84 prec = crec;
85 }
86 } else {
87 if (!UNIQUE) {
88 OUTPUT;
89 } else
90 put(crec, fd);
91 ppos = cpos;
92 prec = crec;
93 }
94 }
95 if (!UNIQUE) { OUTPUT; }
96 } else if (UNIQUE) {
97 ppos = keylist;
98 prec = (RECHEADER *) (*ppos - depth);
99 put(prec, fd);
100 for (cpos = keylist+1; cpos < lastkey; cpos++) {
101 crec = (RECHEADER *) (*cpos - depth);
102 if (crec->offset == prec->offset) {
103 pend = (u_char *) &prec->offset + prec->offset;
104 cend = (u_char *) &crec->offset + crec->offset;
105 for (start = *cpos; cend >= start; cend--) {
106 if (wts[*cend] != wts[*pend])
107 break;
108 pend--;
109 }
110 if (pend + 1 != *ppos) {
111 ppos = cpos;
112 prec = crec;
113 put(prec, fd);
114 }
115 } else {
116 ppos = cpos;
117 prec = crec;
118 put(prec, fd);
119 }
120 }
121 } else for (cpos = keylist; cpos < lastkey; cpos++) {
122 crec = (RECHEADER *) (*cpos - depth);
123 put(crec, fd);
124 }
125 }
126
127 /*
128 * output the already sorted eol bin.
129 */
130 void
rd_append(binno,infl0,nfiles,outfd,buffer,bufend)131 rd_append(binno, infl0, nfiles, outfd, buffer, bufend)
132 u_char *buffer, *bufend;
133 int binno, nfiles;
134 union f_handle infl0;
135 FILE *outfd;
136 {
137 struct recheader *rec;
138 rec = (RECHEADER *) buffer;
139 if (!getnext(binno, infl0, nfiles, (RECHEADER *) buffer, bufend, 0)) {
140 putline(rec, outfd);
141 while (getnext(binno, infl0, nfiles, (RECHEADER *) buffer,
142 bufend, 0) == 0) {
143 if (!UNIQUE)
144 putline(rec, outfd);
145 }
146 }
147 }
148
149 /*
150 * append plain text--used after sorting the biggest bin.
151 */
152 void
concat(a,b)153 concat(a, b)
154 FILE *a, *b;
155 {
156 int nread;
157 char buffer[4096];
158
159 rewind(b);
160 while ((nread = fread(buffer, 1, 4096, b)) > 0)
161 EWRITE(buffer, 1, nread, a);
162 }
163