/* Iterate on blocks for variables, by updating start and count vector * for next vara call. Assumes nc_get_iter called first. Returns * number of variable values to get, 0 if done, negative number if * error, so use like this: size_t to_get; while((to_get = nc_next_iter(&iter, start, count)) > 0) { ... iteration ... } if(to_get < 0) { ... handle error ... } */ size_t nc_next_iter(nciter_t *iter, /* returned opaque iteration state */ size_t *start, /* returned start vector for next vara call */ size_t *count /* returned count vector for next vara call */ ) { int i; if(iter->first) { for(i = 0; i < iter->right_dim; i++) { start[i] = 0; count[i] = 1; } start[iter->right_dim] = 0; count[iter->right_dim] = iter->rows; for(i = iter->right_dim + 1; i < iter->rank; i++) { start[i] = 0; count[i] = iter->dimsizes[i]; } iter->first = 0; } else { iter->more = up_start(iter->rank, iter->dimsizes, iter->right_dim, iter->inc, start); /* iterate on pieces of variable */ if(iter->cur < iter->numrows) { iter->inc = iter->rows; count[iter->right_dim] = iter->rows; iter->cur++; } else { if(iter->leftover > 0) { count[iter->right_dim] = iter->leftover; iter->inc = iter->leftover; iter->cur = 0; } } } iter->to_get = 1; for(i = 0; i < iter->rank; i++) { iter->to_get *= count[i]; } return iter->more == 0 ? 0 : iter->to_get ; }
/* Iterate on blocks for variables, by updating start and count vector * for next vara call. Assumes nc_get_iter called first. Returns * number of variable values to get, 0 if done, negative number if * error, so use like this: size_t to_get; while((to_get = nc_next_iter(&iter, start, count)) > 0) { ... iteration ... } if(to_get < 0) { ... handle error ... } */ size_t nc_next_iter(nciter_t *iter, /* returned opaque iteration state */ size_t *start, /* returned start vector for next vara call */ size_t *count /* returned count vector for next vara call */ ) { int i; /* Note: special case for chunked variables is just an * optimization, the contiguous code below is OK even * for chunked variables, but in general will do more I/O ... */ if(iter->first) { if(!iter->chunked) { /* contiguous storage */ for(i = 0; i < iter->right_dim; i++) { start[i] = 0; count[i] = 1; } start[iter->right_dim] = 0; count[iter->right_dim] = iter->rows; for(i = iter->right_dim + 1; i < iter->rank; i++) { start[i] = 0; count[i] = iter->dimsizes[i]; } } else { /* chunked storage */ #ifdef DOCHUNK for(i = 0; i < iter->rank; i++) { start[i] = 0; count[i] = iter->chunksizes[i]; } #endif } iter->first = 0; } else { if(!iter->chunked) { /* contiguous storage */ iter->more = up_start(iter->rank, iter->dimsizes, iter->right_dim, iter->inc, start); /* iterate on pieces of variable */ if(iter->cur < iter->numrows) { iter->inc = iter->rows; count[iter->right_dim] = iter->rows; iter->cur++; } else { if(iter->leftover > 0) { count[iter->right_dim] = iter->leftover; iter->inc = iter->leftover; iter->cur = 0; } } } else { /* chunked storage */ #ifdef DOCHUNK iter->more = up_start_by_chunks(iter->rank, iter->dimsizes, iter->chunksizes, start); /* adjust count to stay in range of dimsizes */ for(i = 0; i < iter->rank; i++) { int leftover = iter->dimsizes[i] - start[i]; count[i] = iter->chunksizes[i]; if(leftover < count[i]) count[i] = leftover; } #endif } } iter->to_get = 1; for(i = 0; i < iter->rank; i++) { iter->to_get *= count[i]; } return iter->more == 0 ? 0 : iter->to_get ; }