int nclistsetlength(NClist* l, unsigned long sz) { if(l == NULL) return FALSE; if(sz > l->alloc && !nclistsetalloc(l,sz)) return FALSE; l->length = sz; return TRUE; }
/* Convert a CDFnode var to a projection; include pseudodimensions; always whole variable. */ int dapvar2projection(CDFnode* var, DCEprojection** projectionp) { int i,j; int ncstat = NC_NOERR; NClist* path = nclistnew(); NClist* segments; DCEprojection* projection = NULL; int dimindex; /* Collect the nodes needed to construct the projection segment */ collectnodepath3(var,path,!WITHDATASET); segments = nclistnew(); dimindex = 0; /* point to next subset of slices */ nclistsetalloc(segments,nclistlength(path)); for(i=0;i<nclistlength(path);i++) { DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT); CDFnode* n = (CDFnode*)nclistget(path,i); int localrank; NClist* dimset; segment->annotation = (void*)n; segment->name = nulldup(n->ocname); /* We need to assign whole slices to each segment */ localrank = nclistlength(n->array.dimsetplus); segment->rank = localrank; dimset = n->array.dimsetplus; for(j=0;j<localrank;j++) { DCEslice* slice; CDFnode* dim; slice = &segment->slices[j]; dim = (CDFnode*)nclistget(dimset,j); ASSERT(dim->dim.declsize0 > 0); dcemakewholeslice(slice,dim->dim.declsize0); } segment->slicesdefined = 1; segment->slicesdeclized = 1; dimindex += localrank; nclistpush(segments,(ncelem)segment); } projection = (DCEprojection*)dcecreate(CES_PROJECT); projection->discrim = CES_VAR; projection->var = (DCEvar*)dcecreate(CES_VAR); projection->var->annotation = (void*)var; projection->var->segments = segments; #ifdef DEBUG1 fprintf(stderr,"dapvar2projection: projection=%s\n", dumpprojection(projection)); #endif nclistfree(path); if(ncstat) dcefree((DCEnode*)projection); else if(projectionp) *projectionp = projection; return ncstat; }
int nclistpush(NClist* l, void* elem) { if(l == NULL) return FALSE; if(l->length >= l->alloc) nclistsetalloc(l,0); l->content[l->length] = elem; l->length++; return TRUE; }
/* Insert at position i of l; will push up elements i..|seq|. */ int nclistinsert(NClist* l, unsigned long index, void* elem) { int i; /* do not make unsigned */ if(l == NULL) return FALSE; if(index > l->length) return FALSE; nclistsetalloc(l,0); for(i=(int)l->length;i>index;i--) l->content[i] = l->content[i-1]; l->content[index] = elem; l->length++; return TRUE; }
/* Given two projection lists, merge src into dst taking overlapping projections into acct. Assume that name qualification has occured. Dst will be modified. */ NCerror mergeprojections3(NClist* dst, NClist* src) { int i; NClist* cat = nclistnew(); NCerror ncstat = NC_NOERR; #ifdef DEBUG fprintf(stderr,"mergeprojection: dst = %s\n",dumpprojections(dst)); fprintf(stderr,"mergeprojection: src = %s\n",dumpprojections(src)); #endif ASSERT(dst != NULL); /* 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,(ncelem)p); } if(src != NULL) for(i=0;i<nclistlength(src);i++) { DCEprojection* p = (DCEprojection*)nclistget(src,i); nclistpush(cat,(ncelem)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(target->var->cdfleaf != p2->var->cdfleaf) continue; /* This entry matches our current target; merge */ ncstat = mergeprojection31(target,p2); /* null out this merged entry and release it */ nclistset(cat,i,(ncelem)NULL); dcefree((DCEnode*)p2); } /* Capture the clone */ nclistpush(dst,(ncelem)target); } nclistfree(cat); return ncstat; }
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; }
NCerror buildvaraprojection3(Getvara* getvar, const size_t* startp, const size_t* countp, const ptrdiff_t* stridep, DCEprojection** projectionp) { int i,j; int ncrank; NCerror ncstat = NC_NOERR; CDFnode* var = getvar->target; NClist* vardims = var->array.dimensions; DCEprojection* projection = NULL; NClist* path = nclistnew(); NClist* segments = NULL; int dimindex; NClist* dimset = NULL; /* Collect the nodes needed to construct the projection segment */ collectnodepath3(var,path,!WITHDATASET); dimset = var->array.dimensions; ncrank = nclistlength(dimset); segments = nclistnew(); nclistsetalloc(segments,nclistlength(path)); for(i=0;i<nclistlength(path);i++) { DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT); CDFnode* n = (CDFnode*)nclistget(path,i); segment->cdfnode = n; ASSERT((segment->cdfnode != NULL)); segment->name = nulldup(n->name); segment->slicesdefined = 0; /* temporary */ segment->slicesdeclized = 0; /* temporary */ nclistpush(segments,(ncelem)segment); } projection = (DCEprojection*)dcecreate(CES_PROJECT); projection->discrim = CES_VAR; projection->var = (DCEvar*)dcecreate(CES_VAR); projection->var->cdfleaf = var; projection->var->segments = segments; /* We need to assign slices to each segment */ dimindex = 0; /* point to next subset of slices */ for(i=0;i<nclistlength(segments);i++) { DCEsegment* segment = (DCEsegment*)nclistget(segments,i); int localrank = nclistlength(segment->cdfnode->array.dimensions0); if(segment->cdfnode->array.stringdim != NULL) localrank++; if(segment->cdfnode->array.seqdim != NULL) localrank++; segment->rank = localrank; for(j=0;j<localrank;j++) { DCEslice* slice = &segment->slices[j]; CDFnode* dim = (CDFnode*)nclistget(vardims,dimindex+j); slice->first = startp[dimindex+j]; slice->stride = stridep[dimindex+j]; slice->count = countp[dimindex+j]; slice->length = slice->count * slice->stride; if(slice->length > dim->dim.declsize) slice->length = dim->dim.declsize; slice->stop = (slice->first + slice->length); if(slice->stop > dim->dim.declsize) slice->stop = dim->dim.declsize; slice->declsize = dim->dim.declsize; } segment->slicesdefined = 1; segment->slicesdeclized = 1; dimindex += localrank; ASSERT((dimindex <= ncrank)); } ASSERT((dimindex == ncrank)); if(projectionp) *projectionp = projection; nclistfree(path); if(ncstat) dcefree((DCEnode*)projection); return ncstat; }
/* See if we can unify sets of nodes to be projected into larger units. */ static NClist* unifyprojectionnodes3(NClist* varlist) { int i; NClist* nodeset = nclistnew(); NClist* containerset = nclistnew(); NClist* containernodes = nclistnew(); nclistsetalloc(nodeset,nclistlength(varlist)); nclistsetalloc(containerset,nclistlength(varlist)); /* Duplicate the varlist so we can modify it; simultaneously collect unique container set. */ for(i=0;i<nclistlength(varlist);i++) { CDFnode* var = (CDFnode*)nclistget(varlist,i); CDFnode* container = var->container; nclistpush(nodeset,(ncelem)var); switch (container->nctype) { case NC_Sequence: case NC_Structure: case NC_Grid: case NC_Dataset: /* add (uniquely) to container set */ if(!nclistcontains(containerset,(ncelem)container)) nclistpush(containerset,(ncelem)container); break; default: break; } } /* Now, try to find containers whose subnodes are all in the varlist; repeat until no more changes */ for(;;) { int changed = 0; for(i=0;i<nclistlength(containerset);i++) { int j, allfound; CDFnode* container = (CDFnode*)nclistget(containerset,i); if(container == NULL) continue; nclistclear(containernodes); for(allfound=1,j=0;j<nclistlength(container->subnodes);j++) { CDFnode* subnode = (CDFnode*)nclistget(container->subnodes,j); if(!nclistcontains(varlist,(ncelem)subnode)) {allfound=0;break;} nclistpush(containernodes,(ncelem)subnode); } if(allfound) { nclistpush(nodeset,(ncelem)container); nclistset(containerset,i,(ncelem)NULL); /* remove */ for(j=nclistlength(nodeset)-1;j>=0;j--) { /* walk backwards */ CDFnode* testnode = (CDFnode*)nclistget(nodeset,j); if(nclistcontains(containernodes,(ncelem)testnode)) nclistremove(nodeset,j);/* remove */ } changed = 1; } } if(!changed) break; /* apparently we have reached a stable situation */ } /* If there is only the dataset left as a projection, then remove it */ if(nclistlength(nodeset) == 1) { CDFnode* thenode = (CDFnode*)nclistget(nodeset,0); if(thenode->nctype == NC_Dataset) nclistclear(nodeset); } nclistfree(containerset); nclistfree(containernodes); return nodeset; }