static NCerror moveto(NCDAPCOMMON* nccomm, Getvara* xgetvar, CDFnode* xrootnode, void* memory) { OCerror ocstat = OC_NOERR; NCerror ncstat = NC_NOERR; OCconnection conn = nccomm->oc.conn; OCdata xrootcontent; OCobject ocroot; NClist* path = nclistnew(); struct NCMEMORY memstate; memstate.next = (memstate.memory = memory); /* Get the root content*/ ocroot = xrootnode->tree->ocroot; xrootcontent = oc_data_new(conn); ocstat = oc_data_root(conn,ocroot,xrootcontent); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto done;} /* Remember: xgetvar->target is in DATADDS tree */ collectnodepath3(xgetvar->target,path,WITHDATASET); ncstat = movetor(nccomm,xrootcontent, path,0,xgetvar,0,&memstate, xgetvar->varaprojection->var->segments); done: nclistfree(path); oc_data_free(conn,xrootcontent); if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); return THROW(ncstat); }
NCerror buildcachenode34(NCDAPCOMMON* nccomm, NCconstraint* constraint, NClist* varlist, NCcachenode** cachep, int isprefetch) { NCerror ncstat = NC_NOERR; OCerror ocstat = OC_NOERR; OCconnection conn = nccomm->oc.conn; OCobject ocroot = OCNULL; CDFnode* dxdroot = NULL; NCcachenode* cachenode = NULL; char* ce = NULL; if(FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) ce = NULL; else ce = buildconstraintstring3(constraint); ocstat = dap_oc_fetch(nccomm,conn,ce,OCDATADDS,&ocroot); efree(ce); if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;} ncstat = buildcdftree34(nccomm,ocroot,OCDATA,&dxdroot); if(ncstat) {THROWCHK(ncstat); goto done;} /* regrid */ if(!FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE)) { ncstat = regrid3(dxdroot,nccomm->cdf.ddsroot,constraint->projections); if(ncstat) {THROWCHK(ncstat); goto done;} } /* create the cache node */ cachenode = createnccachenode(); cachenode->prefetch = isprefetch; cachenode->vars = nclistclone(varlist); cachenode->datadds = dxdroot; cachenode->constraint = clonencconstraint(constraint); cachenode->wholevariable = iswholeconstraint(cachenode->constraint); /* save the root content*/ cachenode->ocroot = ocroot; cachenode->content = oc_data_new(conn); ocstat = oc_data_root(conn,ocroot,cachenode->content); if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;} /* capture the packet size */ ocstat = oc_raw_xdrsize(conn,ocroot,&cachenode->xdrsize); if(ocstat) {THROWCHK(ocerrtoncerr(ocstat)); goto done;} #ifdef DEBUG fprintf(stderr,"buildcachenode: new cache node: %s\n", dumpcachenode(cachenode)); #endif /* Insert into the cache. If not caching, then remove any previous cache node */ if(!isprefetch) { NCcache* cache = nccomm->cdf.cache; if(cache->nodes == NULL) cache->nodes = nclistnew(); /* remove cache nodes to get below the max cache size */ while(cache->cachesize + cachenode->xdrsize > cache->cachelimit) { NCcachenode* node = (NCcachenode*)nclistremove(cache->nodes,0); #ifdef DEBUG fprintf(stderr,"buildcachenode: purge cache node: %s\n", dumpcachenode(cachenode)); #endif cache->cachesize -= node->xdrsize; freenccachenode(nccomm,node); } /* Remove cache nodes to get below the max cache count */ /* If not caching, then cachecount should be 0 */ while(nclistlength(cache->nodes) > cache->cachecount) { NCcachenode* node = (NCcachenode*)nclistremove(cache->nodes,0); #ifdef DEBUG fprintf(stderr,"buildcachenode: count purge cache node: %s\n", dumpcachenode(node)); #endif cache->cachesize -= node->xdrsize; freenccachenode(nccomm,node); } nclistpush(nccomm->cdf.cache->nodes,(ncelem)cachenode); cache->cachesize += cachenode->xdrsize; } #ifdef DEBUG fprintf(stderr,"buildcachenode: %s\n",dumpcachenode(cachenode)); #endif done: if(cachep) *cachep = cachenode; if(ocstat != OC_NOERR) ncstat = ocerrtoncerr(ocstat); if(ncstat) { freecdfroot34(dxdroot); freenccachenode(nccomm,cachenode); } return THROW(ncstat); }
static NCerror movetor(NCDAPCOMMON* nccomm, OCdata currentcontent, NClist* path, int depth, /* depth is position in segment list*/ Getvara* xgetvar, int dimindex, /* dimindex is position in xgetvar->slices*/ struct NCMEMORY* memory, NClist* segments) { int i; OCerror ocstat = OC_NOERR; NCerror ncstat = NC_NOERR; size_t fieldindex,gridindex,rank; OCconnection conn = nccomm->oc.conn; CDFnode* xnode = (CDFnode*)nclistget(path,depth); OCdata reccontent = OCNULL; OCdata dimcontent = OCNULL; OCdata fieldcontent = OCNULL; Dapodometer* odom = OCNULL; OCmode currentmode = OCNULLMODE; CDFnode* xnext; int hasstringdim = 0; size_t dimoffset; DCEsegment* segment; int newdepth; int caching = FLAGSET(nccomm->controls,NCF_CACHE); int unconstrainable = FLAGSET(nccomm->controls,NCF_UNCONSTRAINABLE); /* Note that we use depth-1 because the path contains the DATASET but the segment list does not */ segment = (DCEsegment*)nclistget(segments,depth-1); /*may be NULL*/ if(xnode->etype == NC_STRING || xnode->etype == NC_URL) hasstringdim = 1; ocstat = oc_data_mode(conn,currentcontent,¤tmode); #ifdef DEBUG2 fprintf(stderr,"moveto: nctype=%d currentmode=%d depth=%d dimindex=%d", xnode->nctype, currentmode, depth,dimindex); fprintf(stderr," segment=%s hasstringdim=%d\n", dcetostring((DCEnode*)segment),hasstringdim); #endif /* Switch on the combination of nctype and mode */ #define CASE(nc1,nc2) (nc1*1024+nc2) /* This must be consistent with the oc mode transition function */ switch (CASE(xnode->nctype,currentmode)) { default: PANIC2("Illegal combination: nctype=%d mode=%d", (int)xnode->nctype,(int)currentmode); break; case CASE(NC_Sequence,OCFIELDMODE): case CASE(NC_Dataset,OCFIELDMODE): case CASE(NC_Grid,OCFIELDMODE): case CASE(NC_Structure,OCFIELDMODE): /* currentcontent points to the grid/dataset/structure instance */ xnext = (CDFnode*)nclistget(path,depth+1); ASSERT((xnext != NULL)); fieldindex = findfield(xnode,xnext); /* If the next node is a virtual node, then we need to effectively ignore it and use the appropriate subnode. If the next node is a structuregrid node, then use it as is. */ if(xnext->virtual) { CDFnode* xgrid = xnext; xnext = (CDFnode*)nclistget(path,depth+2); /* real node */ gridindex = fieldindex; fieldindex = findfield(xgrid,xnext); fieldindex += gridindex; newdepth = depth+2; } else { newdepth = depth+1; } fieldcontent = oc_data_new(conn); ocstat = oc_data_ith(conn,currentcontent,fieldindex,fieldcontent); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} ncstat = movetor(nccomm,fieldcontent, path,newdepth,xgetvar,dimindex,memory, segments); break; case CASE(NC_Sequence,OCARRAYMODE): /* will actually always be scalar, but will have rank == 1 to account for the sequence dim */ case CASE(NC_Grid,OCARRAYMODE): /* will actually always be scalar */ case CASE(NC_Structure,OCARRAYMODE): /* figure out which slices refer to this node: dimindex upto dimindex+rank; */ ASSERT((segment != NULL)); rank = segment->rank; if(xnode->nctype == NC_Sequence) rank--; /* ignore the sequence dim */ if(rank == 0) { odom = newdapodometer1(1); } else if(caching || unconstrainable) { odom = newdapodometer(segment->slices,0,rank); } else { /*Since vara was projected out, build a simple odometer*/ odom = newsimpledapodometer(segment,rank); } while(dapodometermore(odom)) { OCmode mode; /* Compute which instance to move to*/ dimoffset = dapodometercount(odom); dimcontent = oc_data_new(conn); ocstat = oc_data_ith(conn,currentcontent,dimoffset,dimcontent); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} ocstat = oc_data_mode(conn,dimcontent,&mode); ASSERT((mode == OCFIELDMODE || (mode == OCSEQUENCEMODE && xnode->nctype == NC_Sequence))); ncstat = movetor(nccomm,dimcontent, path,depth, xgetvar,dimindex+rank, memory,segments); dapodometerincr(odom); } freedapodometer(odom); break; case CASE(NC_Sequence,OCSEQUENCEMODE): { DCEslice* uslice; ASSERT((segment != NULL)); /* Get and check the corresponding sequence dimension from DDS */ ASSERT((xnode->attachment != NULL)); /* use uslice to walk the sequence; however, watch out for the case when the user set a limit and that limit is not actually reached in this request. */ /* By construction, this sequence represents the first (and only) dimension of this segment */ uslice = &segment->slices[0]; reccontent = oc_data_new(conn); for(i=uslice->first;i<uslice->stop;i+=uslice->stride) { OCmode eos; ocstat = oc_data_ith(conn,currentcontent,i,reccontent); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} ocstat = oc_data_mode(conn,reccontent,&eos); if(ocstat != OC_NOERR) {THROWCHK(ocstat); goto fail;} if(eos == OCNULLMODE) { /* We asked for too much */ ncstat = THROW(NC_EINVALCOORDS); goto fail; } ncstat = movetor(nccomm,reccontent, path,depth, xgetvar,dimindex+1, memory,segments); if(ncstat != OC_NOERR) {THROWCHK(ncstat); goto fail;} } } break; case CASE(NC_Primitive,OCPRIMITIVEMODE): if(hasstringdim) ncstat = extractstring(nccomm, xgetvar, xnode, segment, conn, currentcontent, memory); else ncstat = extract(nccomm, xgetvar, xnode, segment, conn, currentcontent, memory); break; }