|
|
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.