static void completesegments3(NClist* fullpath, NClist* segments) { int i,delta; /* add path nodes to segments to create full path */ delta = (nclistlength(fullpath) - nclistlength(segments)); ASSERT((delta >= 0)); for(i=0;i<delta;i++) { DCEsegment* seg = (DCEsegment*)dcecreate(CES_SEGMENT); CDFnode* node = (CDFnode*)nclistget(fullpath,i); seg->name = nulldup(node->ocname); seg->annotation = (void*)node; seg->rank = nclistlength(node->array.dimset0); #ifdef IGNORE for(j=0;j<seg->rank;j++) { CDFnode* dim = (CDFnode*)nclistget(node->array.dimset0,j); dcemakewholeslice(seg->slices+j,dim->dim.declsize); } #endif nclistinsert(segments,i,(ncelem)seg); } /* Now modify the segments to point to the appropriate node and fill in the slices. */ for(i=delta;i<nclistlength(segments);i++) { DCEsegment* seg = (DCEsegment*)nclistget(segments,i); CDFnode* node = (CDFnode*)nclistget(fullpath,i); seg->annotation = (void*)node; #ifdef IGNORE if(!seg->slicesdefined) { makewholesegment3(seg,node); } #endif } }
void restrictprojection34(NClist* varlist, NClist* projections) { int i,j,len; #ifdef DEBUG fprintf(stderr,"restriction.before=|%s|\n", dumpprojections(projections)); #endif if(nclistlength(varlist) == 0) goto done; /* nothing to add or remove */ /* If the projection list is empty, then add a projection for every variable in varlist */ if(nclistlength(projections) == 0) { NClist* path = nclistnew(); NClist* nodeset = NULL; /* Attempt to unify the vars into larger units (like a complete grid) */ nodeset = unifyprojectionnodes3(varlist); for(i=0;i<nclistlength(nodeset);i++) { CDFnode* var = (CDFnode*)nclistget(nodeset,i); #ifdef DEBUG fprintf(stderr,"restriction.candidate=|%s|\n",var->ncfullname); #endif DCEprojection* newp = (DCEprojection*)dcecreate(CES_PROJECT); newp->discrim = CES_VAR; newp->var = (DCEvar*)dcecreate(CES_VAR); newp->var->cdfleaf = var; nclistclear(path); collectnodepath3(var,path,!WITHDATASET); newp->var->segments = nclistnew(); for(j=0;j<nclistlength(path);j++) { CDFnode* node = (CDFnode*)nclistget(path,j); DCEsegment* newseg = (DCEsegment*)dcecreate(CES_SEGMENT); newseg->name = nulldup(node->name); makewholesegment3(newseg,node);/*treat as simple projections*/ newseg->cdfnode = node; nclistpush(newp->var->segments,(ncelem)newseg); } nclistpush(projections,(ncelem)newp); } nclistfree(path); nclistfree(nodeset); } else { /* Otherwise, walk all the projections and see if they intersect any of the variables. If not, then remove from the projection list. */ len = nclistlength(projections); for(i=len-1;i>=0;i--) {/* Walk backward to facilitate removal*/ int intersect = 0; DCEprojection* proj = (DCEprojection*)nclistget(projections,i); if(proj->discrim != CES_VAR) continue; for(j=0;j<nclistlength(varlist);j++) { CDFnode* var = (CDFnode*)nclistget(varlist,j); /* Note that intersection could go either way */ if(treecontains3(var,proj->var->cdfleaf) || treecontains3(proj->var->cdfleaf,var)) {intersect = 1; break;} } if(!intersect) { /* suppress this projection */ DCEprojection* p = (DCEprojection*)nclistremove(projections,i); dcefree((DCEnode*)p); } } /* Now looks for containment between projections and only keep the more restrictive. Is this algorithm stable against reordering?. */ for(;;) { int removed = 0; for(i=0;i<nclistlength(projections);i++) { DCEprojection* pi = (DCEprojection*)nclistget(projections,i); if(pi->discrim != CES_VAR) continue; for(j=0;j<i;j++) { DCEprojection* pj = (DCEprojection*)nclistget(projections,j); if(pj->discrim != CES_VAR) continue; if(treecontains3(pi->var->cdfleaf,pj->var->cdfleaf)) { DCEprojection* p = (DCEprojection*)nclistremove(projections,j); dcefree((DCEnode*)p); removed = 1; break; } else if(treecontains3(pj->var->cdfleaf,pi->var->cdfleaf)) { DCEprojection* p = (DCEprojection*)nclistremove(projections,i); dcefree((DCEnode*)p); removed = 1; break; } } } if(!removed) break; } } done: #ifdef DEBUG fprintf(stderr,"restriction.after=|%s|\n", dumpprojections(projections)); #endif return; }