/********************************************************************* * Copyright 2018, UCAR/Unidata * See netcdf/COPYRIGHT file for copying and redistribution conditions. *********************************************************************/ #include "dapincludes.h" #include "dapodom.h" /**********************************************/ /* Define methods for a dimension dapodometer*/ /* Build an odometer covering slices startslice up to, but not including, stopslice */ Dapodometer* dapodom_fromsegment(DCEsegment* segment, size_t startindex, size_t stopindex) { int i; Dapodometer* odom; assert(stopindex > startindex); assert((stopindex - startindex) <= NC_MAX_VAR_DIMS); odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); MEMCHECK(odom,NULL); odom->rank = (stopindex - startindex); for(i=0;irank;i++) { odom->start[i] = segment->slices[i+startindex].first; odom->stride[i] = segment->slices[i+startindex].stride; odom->stop[i] = (segment->slices[i+startindex].last + 1); /* should the above line be instead? odom->stop[i] = odom->start[i] + (odom->count[i]*odom->stride[i]); */ #if 0 odom->count[i] = segment->slices[i+startindex].count; #endif odom->declsize[i] = segment->slices[i+startindex].declsize; odom->index[i] = odom->start[i]; } return odom; } Dapodometer* dapodom_new(size_t rank, const size_t* start, const size_t* count, const ptrdiff_t* stride, const size_t* size) { int i; Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); MEMCHECK(odom,NULL); odom->rank = rank; assert(odom->rank <= NC_MAX_VAR_DIMS); for(i=0;irank;i++) { size_t istart,icount,istop,ideclsize; ptrdiff_t istride; istart = (start != NULL ? start[i] : 0); icount = (count != NULL ? count[i] : (size != NULL ? size[i] : 1)); istride = (size_t)(stride != NULL ? stride[i] : 1); istop = istart + icount*istride; ideclsize = (size != NULL ? size[i]: (istop - istart)); odom->start[i] = istart; odom->stop[i] = istop; odom->stride[i] = istride; odom->declsize[i] = ideclsize; odom->index[i] = odom->start[i]; } return odom; } void dapodom_free(Dapodometer* odom) { if(odom) free(odom); } #if 0 char* dapodom_print(Dapodometer* odom) { int i; static char line[1024]; char tmp[64]; line[0] = '\0'; if(odom->rank == 0) { strlcat(line,"[]",sizeof(line)); } else for(i=0;irank;i++) { sprintf(tmp,"[%lu/%lu:%lu:%lu]", (size_t)odom->index[i], (size_t)odom->start[i], (size_t)odom->stride[i], (size_t)odom->length[i]); strlcat(line,tmp,sizeof(line)); } return line; } #endif int dapodom_more(Dapodometer* odom) { return (odom->index[0] < odom->stop[0]); } /* Convert current dapodometer settings to a single integer count*/ off_t dapodom_count(Dapodometer* odom) { int i; off_t offset = 0; for(i=0;irank;i++) { offset *= odom->declsize[i]; offset += odom->index[i]; } return offset; } int dapodom_next(Dapodometer* odom) { int i; /* do not make unsigned */ if(odom->rank == 0) return 0; for(i=odom->rank-1;i>=0;i--) { odom->index[i] += odom->stride[i]; if(odom->index[i] < odom->stop[i]) break; if(i == 0) return 0; /* leave the 0th entry if it overflows*/ odom->index[i] = odom->start[i]; /* reset this position*/ } return 1; } /**************************************************/ size_t dapodom_varmcount(Dapodometer* odom, const ptrdiff_t* steps, const size_t* declsizes) { int i; size_t offset = 0; for(i=0;irank;i++) { size_t tmp; tmp = odom->index[i]; tmp = tmp - odom->start[i]; tmp = tmp / odom->stride[i]; tmp = tmp * steps[i]; offset += tmp; } return offset; } /* Given a dapodometer, compute the total number of elements in its space. */ #if 0 off_t dapodom_space(Dapodometer* odom) { size_t i; off_t count = 1; for(i=0;irank;i++) { count *= odom->size[i]; } return count; } #endif