Annotation of researchv10dc/cmd/post/join.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.