/* Make sure that the slice declsizes are all defined for this projection */ static NCerror qualifyprojectionsizes3(DCEprojection* proj) { int i,j; ASSERT(proj->discrim == CES_VAR); for(i=0;i<nclistlength(proj->var->segments);i++) { DCEsegment* seg = (DCEsegment*)nclistget(proj->var->segments,i); NClist* dimset = NULL; int rank; ASSERT(seg->cdfnode != NULL); /* Must use dimensions0 (the original set) because the segments are wrt the underlying dce DDS */ dimset = seg->cdfnode->array.dimensions0; rank = nclistlength(dimset); for(j=0;j<rank;j++) { CDFnode* dim = (CDFnode*)nclistget(dimset,j); seg->slices[j].declsize = dim->dim.declsize; } } return NC_NOERR; }
void freenccache(NCDAPCOMMON* nccomm, NCcache* cache) { int i; if(cache == NULL) return; freenccachenode(nccomm,cache->prefetch); for(i=0;i<nclistlength(cache->nodes);i++) { freenccachenode(nccomm,(NCcachenode*)nclistget(cache->nodes,i)); } nclistfree(cache->nodes); nullfree(cache); }
size_t dapdimproduct(NClist* dimensions) { size_t size = 1; unsigned int i; if(dimensions == NULL) return size; for(i=0;i<nclistlength(dimensions);i++) { CDFnode* dim = (CDFnode*)nclistget(dimensions,i); size *= dim->dim.declsize; } return size; }
char* dumpselection(NCselection* sel) { NCbytes* buf = ncbytesnew(); NCbytes* segbuf = ncbytesnew(); char* sstring; NClist* segments = NULL; int j; if(sel == NULL) return nulldup(""); segments = sel->lhs->var->segments; ncbytescat(buf,"&"); tostringncsegments(segments,segbuf); ncbytescat(buf,ncbytescontents(segbuf)); ncbytescat(buf,opstrings[sel->operator]); ncbytescat(buf,"{"); for(j=0;j<nclistlength(sel->rhs);j++) { NCvalue* value = (NCvalue*)nclistget(sel->rhs,j); NCconstant* con = value->constant; char tmp[64]; if(j > 0) ncbytescat(buf,","); switch (value->discrim) { case NS_STR: ncbytescat(buf,con->text); break; case NS_CONST: switch (con->discrim) { case NS_INT: snprintf(tmp,sizeof(tmp),"%lld",con->intvalue); ncbytescat(buf,tmp); break; case NS_FLOAT: snprintf(tmp,sizeof(tmp),"%g",con->floatvalue); ncbytescat(buf,tmp); break; default: PANIC1("unexpected discriminator %d",(int)con->discrim); } break; case NS_VAR: segments = value->var->segments; ncbytesclear(segbuf); tostringncsegments(segments,segbuf); ncbytescat(buf,ncbytescontents(segbuf)); break; default: PANIC1("unexpected discriminator %d",(int)value->discrim); } } ncbytescat(buf,"}"); sstring = ncbytesdup(buf); ncbytesfree(buf); ncbytesfree(segbuf); return sstring; }
static int iscacheableprojection(DCEprojection* proj) { int i,cacheable; if(proj->discrim != CES_VAR) return 0; cacheable = 1; /* assume so */ for(i=0;i<nclistlength(proj->var->segments);i++) { DCEsegment* segment = (DCEsegment*)nclistget(proj->var->segments,i); if(!iswholesegment(segment)) {cacheable = 0; break;} } return cacheable; }
static NCerror repairgrids(NCDAPCOMMON* ncc, NClist* repairlist) { NCerror ncstat = NC_NOERR; int i; assert(nclistlength(repairlist) % 2 == 0); for(i=0;i<nclistlength(repairlist);i+=2) { CDFnode* node = (CDFnode*)nclistget(repairlist,i); CDFnode* pattern = (CDFnode*)nclistget(repairlist,i+1); int index = findin(node->container,node); int tindex = findin(pattern->container,pattern); ncstat = structwrap(ncc, node,node->container,index, pattern->container,tindex); #ifdef DEBUG fprintf(stderr,"repairgrids: %s -> %s\n", ocfqn(node->ocnode),ocfqn(pattern->ocnode)); #endif } return ncstat; }
/* Given an existing candidate, see if we prefer newchoice */ static CDFnode* prefer(CDFnode* candidate, CDFnode* newchoice) { nc_type newtyp; nc_type cantyp; int newisstring; int canisstring; int newisscalar; int canisscalar; /* always choose !null over null */ if(newchoice == NULL) return candidate; if(candidate == NULL) return newchoice; newtyp = newchoice->etype; cantyp = candidate->etype; newisstring = (newtyp == NC_STRING || newtyp == NC_URL); canisstring = (cantyp == NC_STRING || cantyp == NC_URL); newisscalar = (nclistlength(newchoice->array.dimset0) == 0); canisscalar = (nclistlength(candidate->array.dimset0) == 0); ASSERT(candidate->nctype == NC_Atomic && newchoice->nctype == NC_Atomic); /* choose non-string over string */ if(canisstring && !newisstring) return newchoice; if(!canisstring && newisstring) return candidate; /* choose scalar over array */ if(canisscalar && !newisscalar) return candidate; if(!canisscalar && newisscalar) return candidate; /* otherwise choose existing candidate */ return candidate; }
static int printMetaData(D4printer* out, NCD4node* node, int depth) { int ret = NC_NOERR; int i; if(nclistlength(node->dims) > 0) { for(i=0;i<nclistlength(node->dims);i++) { NCD4node* dim = (NCD4node*)nclistget(node->dims,i); printDimref(out,dim,depth); CAT("\n"); } } if(nclistlength(node->maps) > 0) { for(i=0;i<nclistlength(node->maps);i++) { NCD4node* mapref = (NCD4node*)nclistget(node->maps,i); printMap(out,mapref,depth); CAT("\n"); } } if(nclistlength(node->attributes) > 0) { for(i=0;i<nclistlength(node->attributes);i++) { NCD4node* attr = (NCD4node*)nclistget(node->attributes,i); printAttribute(out,attr,depth); CAT("\n"); } } return THROW(ret); }
/* A variable is prefetchable if 1. it is atomic 2. it's size is sufficiently small 3. it is not contained in sequence or a dimensioned structure. */ NCerror markprefetch(NCDAPCOMMON* nccomm) { int i,j; NClist* allvars = nccomm->cdf.fullddsroot->tree->varnodes; assert(allvars != NULL); /* mark those variables of sufficiently small size */ for(i=0;i<nclistlength(allvars);i++) { CDFnode* var = (CDFnode*)nclistget(allvars,i); size_t nelems; /* If var is not atomic, then it is not prefetchable */ if(var->nctype != NC_Atomic) continue; /* if var is under a sequence, then never prefetch */ if(dapinsequence(var)) continue; /* Compute the # of elements in the variable */ for(nelems=1,j=0;j<nclistlength(var->array.dimsettrans);j++) { CDFnode* dim = (CDFnode*)nclistget(var->array.dimsettrans,j); nelems *= dim->dim.declsize; } if(nelems <= nccomm->cdf.smallsizelimit && FLAGSET(nccomm->controls,NCF_PREFETCH)) { var->prefetchable = 1; if(SHOWFETCH) { extern char* ocfqn(OCddsnode); char *tmp = ocfqn(var->ocnode); nclog(NCLOGDBG,"prefetchable: %s=%lu", tmp,(unsigned long)nelems); free(tmp); } } } return NC_NOERR; }
static NCerror mergeprojection31(DCEprojection* dst, DCEprojection* src) { NCerror ncstat = NC_NOERR; int i,j; /* merge segment by segment; |dst->segments| == |src->segments| by construction */ ASSERT((dst->discrim == CES_VAR && src->discrim == CES_VAR)); ASSERT((nclistlength(dst->var->segments) == nclistlength(src->var->segments))); for(i=0;i<nclistlength(dst->var->segments);i++) { DCEsegment* dstseg = (DCEsegment*)nclistget(dst->var->segments,i); DCEsegment* srcseg = (DCEsegment*)nclistget(src->var->segments,i); ASSERT((dstseg->cdfnode == srcseg->cdfnode)); /* by construction */ for(j=0;j<nclistlength(dstseg->slices);j++) { dceslicemerge(&dstseg->slices[j],&srcseg->slices[j]); } } return ncstat; }
static int treecontains3(CDFnode* var, CDFnode* root) { int i; if(root->visible == 0) return 0; if(var == root) return 1; for(i=0;i<nclistlength(root->subnodes);i++) { CDFnode* subnode = (CDFnode*)nclistget(root->subnodes,i); if(treecontains3(var,subnode)) return 1; } return 0; }
char* simplepathstring(NClist* names, char* separator) { int i; size_t len; char* result; if(nclistlength(names) == 0) return nulldup(""); for(len=0,i=0;i<nclistlength(names);i++) { char* name = (char*)nclistget(names,i); len += strlen(name); len += strlen(separator); } len++; /* room for strlcat to null terminate */ result = (char*)malloc(len+1); result[0] = '\0'; for(i=0;i<nclistlength(names);i++) { char* segment = (char*)nclistget(names,i); if(i > 0) strlcat(result,separator,len); strlcat(result,segment,len); } return result; }
static unsigned long cdftotalsize3(NClist* dimensions) { unsigned int i; unsigned long total = 1; if(dimensions != NULL) { for(i=0;i<nclistlength(dimensions);i++) { CDFnode* dim = (CDFnode*)nclistget(dimensions,i); total *= dim->dim.declsize; } } return total; }
NCerror fixgrids(NCDAPCOMMON* nccomm) { unsigned int i; NClist* gridnodes = nccomm->cdf.ddsroot->tree->gridnodes; for(i=0; i<nclistlength(gridnodes); i++) { CDFnode* grid = (CDFnode*)nclistget(gridnodes,i); (void)fixgrid(nccomm,grid); /* Ignore mal-formed grids */ } return NC_NOERR; }
static NClist* nc_urlparamlookup(NClist* params, const char* pname) { int i; if(params == NULL || pname == NULL) return NULL; for(i=0;i<nclistlength(params);i+=2) { char* name = (char*)nclistget(params,i); if(strcmp(pname,name)==0) { return (NClist*)nclistget(params,i+1); } } return NULL; }
char* dumpconstraint(NCconstraint* con) { NCbytes* buf = ncbytesnew(); char* result = NULL; if(nclistlength(con->projections)==0 && nclistlength(con->selections)==0) goto done; if(nclistlength(con->projections) > 0) { char* pstring = dumpprojections(con->projections); ncbytescat(buf,pstring); efree(pstring); } if(nclistlength(con->selections) > 0) { char* sstring = dumpselections(con->selections); ncbytescat(buf,sstring); efree(sstring); } done: result = ncbytesdup(buf); ncbytesfree(buf); return result; }
static int mergeprojection(DCEprojection* dst, DCEprojection* src) { int ncstat = NC_NOERR; int i,j; /* merge segment by segment; |dst->segments| == |src->segments| by construction */ assert((dst->discrim == CES_VAR && src->discrim == CES_VAR)); assert((nclistlength(dst->var->segments) == nclistlength(src->var->segments))); for(i=0;i<nclistlength(dst->var->segments);i++) { DCEsegment* dstseg = (DCEsegment*)nclistget(dst->var->segments,i); DCEsegment* srcseg = (DCEsegment*)nclistget(src->var->segments,i); for(j=0;j<dstseg->rank;j++) { dceslicemerge(dstseg->slices+j, srcseg->slices+j); } } return ncstat; }
static int slicematch(NClist* seglist1, NClist* seglist2) { int i,j; if((seglist1 == NULL || seglist2 == NULL) && seglist1 != seglist2) return 0; if(nclistlength(seglist1) != nclistlength(seglist2)) return 0; for(i=0;i<nclistlength(seglist1);i++) { DCEsegment* seg1 = (DCEsegment*)nclistget(seglist1,i); DCEsegment* seg2 = (DCEsegment*)nclistget(seglist2,i); if(seg1->rank != seg2->rank) return 0; for(j=0;j<seg1->rank;j++) { if(seg1->slices[j].first != seg2->slices[j].first || seg1->slices[j].count != seg2->slices[j].count || seg1->slices[j].stride != seg2->slices[j].stride) return 0; } } return 1; }
void dcelisttobuffer(NClist* list, NCbytes* buf, char* sep) { int i; if(list == NULL || buf == NULL) return; if(sep == NULL) sep = ","; for(i=0;i<nclistlength(list);i++) { DCEnode* node = (DCEnode*)nclistget(list,i); if(node == NULL) continue; if(i>0) ncbytescat(buf,sep); dcetobuffer((DCEnode*)node,buf); } }
NClist* dceclonelist(NClist* list) { int i; NClist* clone; if(list == NULL) return NULL; clone = nclistnew(); for(i=0;i<nclistlength(list);i++) { DCEnode* node = (DCEnode*)nclistget(list,i); DCEnode* newnode = dceclone((DCEnode*)node); nclistpush(clone,(ncelem)newnode); } return clone; }
int iswholeprojection(DCEprojection* proj) { int i,whole; ASSERT((proj->discrim == CES_VAR)); whole = 1; /* assume so */ for(i=0;i<nclistlength(proj->var->segments);i++) { DCEsegment* segment = (DCEsegment*)nclistget(proj->var->segments,i); if(!iswholesegment(segment)) {whole = 0; break;} } return whole; }
Object segment(DCEparsestate* state, Object name, Object slices0) { int i; DCEsegment* segment = (DCEsegment*)dcecreate(CES_SEGMENT); NClist* slices = (NClist*)slices0; segment->name = strdup((char*)name); if(slices != NULL && nclistlength(slices) > 0) { segment->slicesdefined = 1; /* but not declsizes */ for(i=0;i<nclistlength(slices);i++) { DCEslice* slice = (DCEslice*)nclistget(slices,i); segment->slices[i] = *slice; free(slice); } nclistfree(slices); } else segment->slicesdefined = 0; #ifdef DEBUG fprintf(stderr," ce.segment: %s\n", dumpsegment(segment)); #endif return segment; }
/* Modify merged projection to include "addition" projection */ int dcemergeprojections(DCEprojection* merged, DCEprojection* addition) { int ncstat = NC_NOERR; int i,j; ASSERT((merged->discrim == CES_VAR && addition->discrim == CES_VAR)); ASSERT((nclistlength(merged->var->segments) == nclistlength(addition->var->segments))); for(i=0;i<nclistlength(merged->var->segments);i++) { DCEsegment* mergedseg = (DCEsegment*)nclistget(merged->var->segments,i); DCEsegment* addedseg = (DCEsegment*)nclistget(addition->var->segments,i); /* If one segment has larger rank, then copy the extra slices unchanged */ for(j=0;j<addedseg->rank;j++) { if(j < mergedseg->rank) dceslicecompose(mergedseg->slices+j,addedseg->slices+j,mergedseg->slices+j); else mergedseg->slices[j] = addedseg->slices[j]; } if(addedseg->rank > mergedseg->rank) mergedseg->rank = addedseg->rank; } return ncstat; }
static void dcedumprawlist(NClist* list, NCbytes* buf) { int i; if(list == NULL || buf == NULL) return; ncbytescat(buf,"("); for(i=0;i<nclistlength(list);i++) { DCEnode* node = (DCEnode*)nclistget(list,i); if(node == NULL) continue; if(i>0) ncbytescat(buf,","); dcedumpraw((DCEnode*)node,buf); } ncbytescat(buf,")"); }
/* return TRUE if found, false otherwise*/ int nchashremove(NChashmap* hm, nchashid hash) { int i,offset,len; NClist* seq; void** list; offset = (hash % hm->alloc); seq = hm->table[offset]; if(seq == NULL) return TRUE; len = nclistlength(seq); list = nclistcontents(seq); for(i=0;i<len;i+=2,list+=2) { if(hash==(nchashid)(*list)) { nclistremove(seq,i+1); nclistremove(seq,i); hm->size--; if(nclistlength(seq) == 0) {nclistfree(seq); hm->table[offset] = NULL;} return TRUE; } } return FALSE; }
/* Insert new client param (name,value); return value = 1 => not already defined 0 => param already defined (no change) */ static int nc_urlparaminsert(NClist* params, const char* clientparam, const char* value) { int i; if(params == NULL || clientparam == NULL) return 0; for(i=0;i<nclistlength(params);i+=2) { char* name = (char*)nclistget(params,i); if(strcmp(clientparam,name)==0) return 0; } /* not found, append */ nclistpush(params,(ncelem)strdup(clientparam)); nclistpush(params,(ncelem)nulldup(value)); return 1; }
NCerror dimimprint(NCDAPCOMMON* nccomm) { NCerror ncstat = NC_NOERR; NClist* allnodes; int i,j; CDFnode* basenode; allnodes = nccomm->cdf.ddsroot->tree->nodes; for(i=0;i<nclistlength(allnodes);i++) { CDFnode* node = (CDFnode*)nclistget(allnodes,i); int noderank, baserank; /* Do dimension imprinting */ basenode = node->basenode; if(basenode == NULL) continue; noderank = nclistlength(node->array.dimset0); baserank = nclistlength(basenode->array.dimset0); if(noderank == 0) continue; ASSERT(noderank == baserank); #ifdef DEBUG fprintf(stderr,"dimimprint %s/%d -> %s/%d\n", makecdfpathstring(basenode,"."), noderank, makecdfpathstring(node,"."), baserank); #endif for(j=0;j<noderank;j++) { CDFnode* dim = (CDFnode*)nclistget(node->array.dimset0,j); CDFnode* basedim = (CDFnode*)nclistget(basenode->array.dimset0,j); dim->dim.declsize0 = basedim->dim.declsize; #ifdef DEBUG fprintf(stderr,"dimimprint: %d: %lu -> %lu\n",i,basedim->dim.declsize,dim->dim.declsize0); #endif } } return ncstat; }
Object indexer(DCEparsestate* state, Object name, Object indices) { int i; NClist* list = (NClist*)indices; DCEsegment* seg = (DCEsegment*)dcecreate(CES_SEGMENT); seg->name = strdup((char*)name); for(i=0;i<nclistlength(list);i++) { DCEslice* slice = (DCEslice*)nclistget(list,i); seg->slices[i] = *slice; free(slice); } nclistfree(indices); return seg; }
/* Convert an NCprojection instance into a string that can be used with the url */ char* dumpprojections(NClist* projections) { int i; NCbytes* buf = ncbytesnew(); char* pstring; for(i=0;i<nclistlength(projections);i++) { NCprojection* p = (NCprojection*)nclistget(projections,i); if(i > 0) ncbytescat(buf,","); ncbytescat(buf,dumpprojection1(p)); } pstring = ncbytesdup(buf); ncbytesfree(buf); return pstring; }
int iswholeconstraint(DCEconstraint* con) { int i; if(con == NULL) return 1; if(con->projections != NULL) { for(i=0;i<nclistlength(con->projections);i++) { if(!iswholeprojection((DCEprojection*)nclistget(con->projections,i))) return 0; } } if(con->selections != NULL) return 0; return 1; }