int dcemergeprojectionlists(NClist* dst, NClist* src) { int i; NClist* cat = nclistnew(); int ncstat = NC_NOERR; #ifdef DEBUG fprintf(stderr,"dapmergeprojection: dst = %s\n",dcetostring((DCEnode*)dst)); fprintf(stderr,"dapmergeprojection: src = %s\n",dcetostring((DCEnode*)src)); #endif /* get dst concat clone(src) */ nclistsetalloc(cat,nclistlength(dst)+nclistlength(src)); for(i=0;i<nclistlength(dst);i++) { DCEprojection* p = (DCEprojection*)nclistget(dst,i); nclistpush(cat,(void*)p); } for(i=0;i<nclistlength(src);i++) { DCEprojection* p = (DCEprojection*)nclistget(src,i); nclistpush(cat,(void*)dceclone((DCEnode*)p)); } nclistclear(dst); /* Repeatedly pull elements from the concat, merge with all duplicates, and stick into the dst */ while(nclistlength(cat) > 0) { DCEprojection* target = (DCEprojection*)nclistremove(cat,0); if(target == NULL) continue; if(target->discrim != CES_VAR) continue; for(i=0;i<nclistlength(cat);i++) { DCEprojection* p2 = (DCEprojection*)nclistget(cat,i); if(p2 == NULL) continue; if(p2->discrim != CES_VAR) continue; if(dcesamepath(target->var->segments, p2->var->segments)!=0) continue; /* This entry matches our current target; merge */ ncstat = dcemergeprojections(target,p2); /* null out this merged entry and release it */ nclistset(cat,i,(void*)NULL); dcefree((DCEnode*)p2); } /* Capture the clone */ nclistpush(dst,(void*)target); } nclistfree(cat); return ncstat; }
/* Given a set of projections and a projection representing a variable (from, say vara or prefetch) construct a single projection for fetching that variable with the proper constraints. */ int daprestrictprojection(NClist* projections, DCEprojection* var, DCEprojection** resultp) { int ncstat = NC_NOERR; int i; DCEprojection* result = NULL; #ifdef DEBUG1 fprintf(stderr,"restrictprojection.before: constraints=|%s| vara=|%s|\n", dumpprojections(projections), dumpprojection(var)); #endif ASSERT(var != NULL); /* the projection list will contain at most 1 match for the var by construction */ for(result=null,i=0;i<nclistlength(projections);i++) { DCEprojection* p1 = (DCEprojection*)nclistget(projections,i); if(p1 == NULL || p1->discrim != CES_VAR) continue; if(p1->var->annotation == var->var->annotation) { result = p1; break; } } if(result == NULL) { result = (DCEprojection*)dceclone((DCEnode*)var); /* use only the var projection */ goto done; } result = (DCEprojection*)dceclone((DCEnode*)result); /* so we can modify */ #ifdef DEBUG1 fprintf(stderr,"restrictprojection.choice: base=|%s| add=|%s|\n", dumpprojection(result),dumpprojection(var)); #endif /* We need to merge the projection from the projection list with the var projection */ ncstat = dcemergeprojections(result,var); /* result will be modified */ done: if(resultp) *resultp = result; #ifdef DEBUG fprintf(stderr,"restrictprojection.after=|%s|\n", dumpprojection(result)); #endif return ncstat; }