Annotation of 42BSD/ingres/source/decomp/reduction.c, revision 1.1.1.1

1.1       root        1: # include      <ingres.h>
                      2: # include      <symbol.h>
                      3: # include      <aux.h>
                      4: # include      <tree.h>
                      5: # include      "globs.h"
                      6: # include      <sccs.h>
                      7: 
                      8: SCCSID(@(#)reduction.c 7.1     2/5/81)
                      9: 
                     10: /*
                     11: **     Reduction -- This file contains routines related to the
                     12: **     reduction algorithm. The routines are all called by
                     13: **     decision().
                     14: **
                     15: **     Included are:
                     16: **
                     17: **             algorithm -- groups clauses according to common variables
                     18: **
                     19: **             buildlist -- build linked list of clauses from a query tree
                     20: **
                     21: **             construct -- build query trees from link lists of clauses
                     22: **
                     23: **             order     -- order a linked list of clauses into the prefered
                     24: **                             execution sequence
                     25: */
                     26: /*
                     27: **     Algorithm - determine whether query is connected or not
                     28: **
                     29: **     Algorithm takes a linked list of query components
                     30: **     and groups them according to the variables involved
                     31: **     in each component. If the query is fully interconnected
                     32: **     then algorithm returns TRUE else it returns FALSE.
                     33: **
                     34: **     By definition a constant clause (one involving zero variables)
                     35: **     is considered to use all variables. Without this rule,
                     36: **     a query with a null target list would always break into
                     37: **     two pieces.
                     38: **
                     39: **     Whether a query is fully connected is independent
                     40: **     of whether there are any one variable components
                     41: **     or not. This includes the target list. After applying
                     42: **     the algorithm, a scan is made to see how many multi-var
                     43: **     components are present. If there are two or more multi-var
                     44: **     components then the query is disconnected.
                     45: **
                     46: **     Trace Flags:
                     47: **             38
                     48: */
                     49: 
                     50: algorithm(clist, varmap)
                     51: struct complist        *clist;
                     52: int            varmap;
                     53: {
                     54:        register struct complist        *chead, *cnext;
                     55:        register int                    var;
                     56:        int                             vmap;
                     57:        struct complist                 *cprev, *cl;
                     58: 
                     59:        vmap = varmap;
                     60:        for (var = 1; vmap; var <<= 1)
                     61:        {
                     62:                if ((vmap & var) == 0)
                     63:                        continue;
                     64:                vmap &= ~var;   /* remove var */
                     65: 
                     66:                /* done if query is already a single piece */
                     67:                if (clist->nextcomp == 0)
                     68:                        break;
                     69: 
                     70:                /* find first component using variable var */
                     71:                for (chead = clist; chead; chead = chead->nextcomp)
                     72:                {
                     73:                        if (chead->bitmap == 0 || (chead->bitmap & var))
                     74:                        {
                     75:                                /* this component uses variable var */
                     76: 
                     77:                                cprev = chead;
                     78:                
                     79:                                /* look for other components using variable var */
                     80:                                for (cnext = chead->nextcomp; cnext; cnext = cnext->nextcomp)
                     81:                                {
                     82:                                        if (cnext->bitmap == 0 || (cnext->bitmap & var))
                     83:                                        {
                     84:                
                     85:                                                /*
                     86:                                                ** Found a component. Remove it from "next"
                     87:                                                ** link and put it with head piece
                     88:                                                */
                     89:                
                     90:                                                /* remove piece */
                     91:                                                cprev->nextcomp = cnext->nextcomp;
                     92:                
                     93:                                                /* fix up bit map */
                     94:                                                chead->bitmap |= cnext->bitmap;
                     95:                
                     96:                                                /* find end of head component */
                     97:                                                for (cl = chead; cl->linkcomp; cl = cl->linkcomp);
                     98:                
                     99:                                                /* connect with head piece */
                    100:                                                cl->linkcomp = cnext;
                    101:                                        }
                    102:                                        else
                    103:                                                cprev = cnext;
                    104:                                }
                    105:                        }
                    106:                }
                    107:        }
                    108: 
                    109:        /* return whether connected or not connected */
                    110:        for (var =0, chead = clist; chead; chead = chead->nextcomp)
                    111:                if (bitcnt(chead->bitmap) > 1)
                    112:                        var++; /* this component involves 2 or more vars */
                    113: 
                    114:        return (var < 2); /* return TRUE if zero or one component multi-var */
                    115: }
                    116: /*
                    117: **     Buildlist -- Build a component list from a query tree.
                    118: **
                    119: **     Each ROOT and AND node is treated as a separate component
                    120: **     and a linked list is built connecting them. The ROOT node
                    121: **     MUST be the first element. This list will later be manipulated
                    122: **     by algorithm() to determine the structure of the query.
                    123: **
                    124: **     Returns:
                    125: **             Head of the list
                    126: */
                    127: 
                    128: struct complist *
                    129: buildlist(root1, buf)
                    130: QTREE  *root1;
                    131: char   *buf;
                    132: {
                    133:        register struct complist        *head, *next;
                    134:        register QTREE                  *root;
                    135:        struct complist                 *ret;
                    136:        extern char                     *need();
                    137: 
                    138:        ret = (struct complist *) need(buf, 0);
                    139:        head = 0;
                    140: 
                    141:        for (root = root1; root->sym.type != QLEND; root = root->right)
                    142:        {
                    143:                next = (struct complist *) need(buf, sizeof (*next));
                    144:                next->clause = root;
                    145:                next->nextcomp = next->linkcomp = 0;
                    146:                next->bitmap = root->sym.value.sym_root.lvarm;
                    147: 
                    148:                if (head)
                    149:                        head->nextcomp = next;
                    150:                head = next;
                    151:        }
                    152:        return (ret);
                    153: }
                    154: /*
                    155: **  Construct -- construct a tree from a list component
                    156: **
                    157: **     Construct takes a list head and builds a querytree
                    158: **     from the components in the list. If the head component
                    159: **     is the ROOT of the original query, then
                    160: **     the original ROOT node is reused.
                    161: **
                    162: */
                    163: 
                    164: QTREE *
                    165: construct(root, listhead, buf)
                    166: QTREE          *root;
                    167: struct complist        *listhead;
                    168: char           *buf;
                    169: {
                    170:        register QTREE                  *ret, *q;
                    171:        register struct complist        *clist;
                    172:        extern QTREE                    *makroot();
                    173: 
                    174:        clist = listhead;
                    175: 
                    176:        /* determine ROOT of tree */
                    177:        if (root == clist->clause)
                    178:        {
                    179:                q = root;
                    180:                clist = clist->linkcomp;
                    181:        }
                    182:        else
                    183:        {
                    184:                q = makroot(buf);
                    185:        }
                    186:        ret = q;
                    187:        for (; clist; clist = clist->linkcomp)
                    188:        {
                    189:                q->right = clist->clause;
                    190:                q = q->right;
                    191:        }
                    192: 
                    193:        q->right = De.de_qle;
                    194: 
                    195:        mapvar(ret, 1);
                    196: #      ifdef xDTR1
                    197:        if (tTf(38, 0))
                    198:        {
                    199:                printf("Construct\n");
                    200:                treepr(ret);
                    201:        }
                    202: #      endif
                    203:        return (ret);
                    204: }
                    205: /*
                    206: **  Order -- order a link list set of query components.
                    207: **
                    208: **     Takes a list of components and orders them:
                    209: **             first - disjoint components
                    210: **             second - reduction pieces
                    211: **             last - the original target list piece
                    212: **
                    213: **     Return:
                    214: **             new head of list
                    215: */
                    216: 
                    217: struct complist *
                    218: order(clist, ovlapvar)
                    219: struct complist        *clist;
                    220: int            ovlapvar;
                    221: {
                    222:        register struct complist        *cl, *joint, *disjoint;
                    223:        struct complist                 *xd, *xj, *tlpiece, *ret;
                    224:        QTREE                           *tmp;
                    225:        int                             map;
                    226: 
                    227:        tlpiece = clist;        /* target list piece always first */
                    228:        disjoint = joint = 0;
                    229:        map = ovlapvar >= 0 ? 1 << ovlapvar : 0;
                    230: 
                    231:        /* examine each irreducible component for disjointness */
                    232:        for (cl = tlpiece->nextcomp; cl; cl = cl->nextcomp)
                    233:        {
                    234:                if (cl->bitmap & map)
                    235:                {
                    236:                        /* joint piece */
                    237:                        if (joint == 0)
                    238:                        {
                    239:                                joint = cl;
                    240:                                xj = cl;
                    241:                        }
                    242:                        else
                    243:                        {
                    244:                                joint->nextcomp = cl;
                    245:                                joint = cl;
                    246:                        }
                    247:                }
                    248:                else
                    249:                {
                    250:                        /* disjoint piece */
                    251:                        if (disjoint == 0)
                    252:                        {
                    253:                                disjoint = cl;
                    254:                                xd = cl;
                    255:                        }
                    256:                        else
                    257:                        {
                    258:                                disjoint->nextcomp = cl;
                    259:                                disjoint = cl;
                    260:                        }
                    261:                }
                    262: 
                    263:        }
                    264:        /* we now have all disjoint, joint and tl pieces */
                    265:        /* order them in order (1) xd, (2) xj, (3) tlpiece */
                    266: 
                    267:        ret = tlpiece;
                    268:        tlpiece->nextcomp = 0;
                    269: 
                    270:        if (joint)
                    271:        {
                    272:                ret = xj;
                    273:                joint->nextcomp = tlpiece;
                    274:                if ((tlpiece->bitmap & (~map)) == 0)
                    275:                {
                    276:                        /*
                    277:                        ** This is the special case of the target list
                    278:                        ** being one (or zero) variable and that variable
                    279:                        ** is the overlap variable. If left as is, the
                    280:                        ** reduction will take one step more than is
                    281:                        ** necessary. The target list piece is combined
                    282:                        ** with the last joint piece and processed together.
                    283:                        **
                    284:                        ** An example of when this will happen is:
                    285:                        ** ret(p.a) : p.b = s.b ^ p.c = y.c
                    286:                        **
                    287:                        ** Reduction would split this up into
                    288:                        ** (1) ret (p.a,p.b) : p.c = y.c
                    289:                        ** (2) ret (p.a) : p.b = s.b
                    290:                        ** (3) ret (p.a)
                    291:                        **
                    292:                        ** Here we are allowing pieces (2) & (3) to be done together
                    293:                        */
                    294: 
                    295:                        for (cl = joint; cl->linkcomp; cl = cl->linkcomp);
                    296: 
                    297:                        cl->linkcomp = tlpiece;
                    298:                        joint->nextcomp = 0;
                    299: 
                    300:                        /* switch tl clause to top of complist */
                    301:                        tmp = joint->clause;
                    302:                        joint->clause = tlpiece->clause;
                    303:                        tlpiece->clause = tmp;
                    304:                }
                    305:        }
                    306: 
                    307:        if (disjoint)
                    308:        {
                    309:                ret = xd;
                    310:                disjoint->nextcomp = joint ? xj : tlpiece;
                    311:        }
                    312: 
                    313:        return (ret);
                    314: }

unix.superglobalmegacorp.com

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