|
|
1.1 root 1: /*
2: * Join relations module
3: */
4:
5: #include <stdio.h>
6: #include <fcntl.h>
7: #include <string.h>
8: #include <malloc.h>
9:
10: #define DISP "dispatch"
11: #define NVEC 512
12: #define NBITS 32
13: #define B(b) (1 << (b))
14: #define Z ((char *) 0)
15:
16: typedef struct {
17: char *attr, *val;
18: int a;
19: } query_t;
20:
21: typedef struct {
22: int attrs, global, na;
23: char *pq, *args;
24: } rel_t;
25:
26: typedef struct {
27: int attrs, wrote;
28: char *base;
29: rel_t *rp;
30: } merge_t;
31:
32: typedef struct {
33: int attrs, list, argc;
34: char *pq, *base;
35: rel_t *rp;
36: query_t query[NVEC];
37: merge_t merge[NBITS];
38: rel_t rel[NBITS];
39: char *attr[NBITS];
40: char buf[5120];
41: } join_t;
42:
43: static char *mpqopen();
44: static int pqowrite(), key();
45: extern char *pq_open(), *path(), *strcon();
46:
47: char *
48: join_open(argv)
49: char *argv[];
50: {
51: join_t *join = (join_t *) malloc(sizeof (join_t));
52: rel_t *rp = join->rel, *dp = 0;
53: int na = 0, dups = 0, fd;
54: char *str, *nl, *dup;
55:
56: if ((fd = open(str = path(argv[0] ? argv[0] : DISP), O_RDONLY)) < 0) {
57: error(-1, "join %s", str);
58: free((char *) join);
59: return 0;
60: }
61: *(join->base = join->buf + read(fd, join->buf, sizeof join->buf)) = 0;
62: close(fd);
63:
64: if (*join->buf != '>') {
65: if ((join->pq = mpqopen(join->buf)) == 0) {
66: free((char *) join);
67: return 0;
68: }
69: return (char *) join;
70: }
71: join->pq = 0;
72: join->rp = 0;
73: join->list = 0;
74: join->attrs = 0;
75:
76: for (str = join->buf; nl = strchr(str, '\n'); str = ++nl)
77: if (*str == '>') {
78: *str++ = *nl = 0;
79: dup = strchr(str, '/');
80: rp->na = strvec(str, join->attr + na, "/ \t\n");
81: for (rp->attrs = 0; join->attr[na]; na++) {
82: rp->attrs |= B(na);
83: if (dup && join->attr[na] > dup)
84: dups |= B(na);
85: }
86: if (rp->na > 1) {
87: rp->global = rp->attrs & ~dups;
88: join->attrs |= B(key(rp->attrs)) | dups;
89: } else if (rp->na == 0)
90: dp = rp;
91: rp->args = nl + 1;
92: rp->pq = 0;
93: rp++;
94: }
95: if (dp)
96: dp->attrs = dp->global = join->attrs | B(na);
97: rp->args = 0;
98: return (char *) join;
99: }
100:
101: join_close(join)
102: join_t *join;
103: {
104: int rv = 0;
105: rel_t *rp;
106:
107: if (!join->pq) {
108: for (rp = join->rel; rp->args; rp++)
109: if (rp->pq && pq_close(rp->pq) == -1)
110: rv = -1;
111: } else
112: rv = pq_close(join->pq);
113: free((char *) join);
114: return rv;
115: }
116:
117: join_read(join, argv)
118: join_t *join;
119: char *argv[];
120: {
121: char *vec[NVEC];
122: int rv, i;
123: merge_t *mp;
124: query_t *qp;
125: char *cp;
126:
127: if (join->pq)
128: return pq_read(join->pq, argv);
129: while (join->list)
130: if (! (join->attrs & B(--join->list))) {
131: argv[0] = join->attr[join->list];
132: argv[1] = 0;
133: return 1;
134: }
135: if (join->rp)
136: return pq_read(join->rp->pq, argv);
137:
138: for (mp = join->merge; mp->rp && mp->wrote; mp++);
139: if (!mp->rp)
140: mp--;
141:
142: while (mp->rp)
143: if (!mp->wrote) {
144: cp = mp->base;
145: i = 0;
146: for (qp = join->query; qp->attr; qp++)
147: if (mp->rp->global & B(qp->a))
148: if (! (mp->attrs & B(qp->a))) {
149: vec[i++] = ++cp;
150: cp = strcon(cp,
151: join->attr[qp->a],
152: "=", qp->val, Z);
153: } else
154: vec[i++] = qp->attr;
155: vec[i] = 0;
156: mp->wrote++;
157: if (pqowrite(mp->rp, vec) == -1)
158: return -1;
159: } else if ((rv = pq_read(mp->rp->pq, vec)) > 0) {
160: cp = mp->base;
161: i = 0;
162: for (qp = join->query; qp->attr; qp++)
163: if (mp->rp->global & B(qp->a))
164: if (mp->attrs & B(qp->a)) {
165: qp->val = ++cp;
166: cp = strcon(cp, vec[i++], Z);
167: } else
168: i++;
169: (++mp)->base = cp;
170: } else if (rv == 0) {
171: if (mp == join->merge)
172: return 0;
173: (mp--)->wrote = 0;
174: } else
175: return rv;
176:
177: for (i = 0; i < join->argc; i++)
178: argv[i] = join->query[i].val;
179: argv[i] = 0;
180: return rv;
181: }
182:
183: join_write(join, argv)
184: join_t *join;
185: char *argv[];
186: {
187: int attrs = 0, select = 0;
188: char *cp = join->base, *s;
189: int argc, i;
190: query_t *qp;
191: merge_t *mp;
192: rel_t *rp;
193:
194: if (join->pq)
195: return pq_write(join->pq, argv);
196:
197: for (argc = 0, qp = join->query; argv[argc]; argc++, qp++) {
198: for (i = 0; s = join->attr[i]; i++)
199: if (eqattr(argv[argc], s))
200: break;
201: if (eqattr(argv[argc], "attribute"))
202: join->list = i;
203: attrs |= B(i);
204: qp->attr = s;
205: qp->val = 0;
206: qp->a = i;
207: }
208: for (rp = join->rel; rp->args; rp++)
209: if (! (attrs & ~rp->attrs) || rp->na == 1 && attrs & rp->attrs)
210: return pqowrite(join->rp = rp, argv);
211:
212: for (argc = 0, qp = join->query; argv[argc]; argc++, qp++)
213: if ((s = strchr(argv[argc], '=')) || !qp->attr) {
214: qp->attr = ++cp;
215: cp = strcon(cp, argv[argc], Z);
216: if (s)
217: select |= B(qp->a);
218: }
219: for (rp = join->rel; rp->args; rp++)
220: if (rp->na > 1 && attrs & rp->global
221: && ! (attrs & B(i = key(rp->attrs)))) {
222: attrs |= B(i);
223: qp->attr = join->attr[i];
224: qp->val = 0;
225: qp->a = i;
226: qp++;
227: }
228: join->argc = argc;
229: join->rp = 0;
230: qp->attr = 0;
231: mp = join->merge;
232: mp->base = cp;
233:
234: while (attrs) {
235: for (rp = join->rel; rp->args; rp++)
236: if (select & rp->global && attrs & rp->global) {
237: mp->attrs = attrs & rp->global;
238: select |= mp->attrs;
239: attrs &= ~rp->global;
240: mp->wrote = 0;
241: mp->rp = rp;
242: mp++;
243: break;
244: }
245: if (!rp->args)
246: select |= attrs;
247: }
248: mp->rp = 0;
249: return 1;
250: }
251:
252: static char *
253: mpqopen(args)
254: char *args;
255: {
256: char *str, *nl, *pq;
257: char *argv[512];
258: char buf[1024];
259:
260: for (str = strcpy(buf, args); nl = strchr(str, '\n'); str = ++nl) {
261: *nl = 0;
262: strvec(str, argv, " \t\n");
263: if (pq = pq_open(argv))
264: return pq;
265: }
266: if (str == buf)
267: error(0, "join: No modules");
268: return 0;
269: }
270:
271: static int
272: pqowrite(rp, argv)
273: rel_t *rp;
274: char *argv[];
275: {
276: return rp->pq || (rp->pq = mpqopen(rp->args)) ?
277: pq_write(rp->pq, argv) : -1;
278: }
279:
280: static int
281: key(a)
282: int a;
283: {
284: int i = 0;
285: while (! (a & B(i++)));
286: return --i;
287: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.