You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
3.9 KiB
162 lines
3.9 KiB
2 years ago
|
/*********************************************************************
|
||
|
* 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;i<odom->rank;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;i<odom->rank;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;i<odom->rank;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;i<odom->rank;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;i<odom->rank;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;i<odom->rank;i++) {
|
||
|
count *= odom->size[i];
|
||
|
}
|
||
|
return count;
|
||
|
}
|
||
|
#endif
|