Merge branch 'nc4-var-array' of https://github.com/gsjaardema/netcdf-c into gh328

This commit is contained in:
Ward Fisher 2016-11-28 13:10:07 -07:00
commit 05ceb8d471
8 changed files with 240 additions and 177 deletions

View File

@ -146,7 +146,6 @@ typedef struct NC_ATT_INFO
/* This is a struct to handle the var metadata. */
typedef struct NC_VAR_INFO
{
NC_LIST_NODE_T l; /* Use generic doubly-linked list (must be first) */
char *name;
char *hdf5_name; /* used if different from name */
int ndims;
@ -262,6 +261,12 @@ typedef struct NC_TYPE_INFO
} u; /* Union of structs, for each type/class */
} NC_TYPE_INFO_T;
typedef struct NC_VAR_ARRAY_T {
size_t nalloc; /* number allocated >= nelems */
size_t nelems; /* length of the array */
NC_VAR_INFO_T **value;
} NC_VAR_ARRAY_T;
/* This holds information for one group. Groups reproduce with
* parthenogenesis. */
typedef struct NC_GRP_INFO
@ -273,7 +278,7 @@ typedef struct NC_GRP_INFO
struct NC_HDF5_FILE_INFO *nc4_info;
struct NC_GRP_INFO *parent;
struct NC_GRP_INFO *children;
NC_VAR_INFO_T *var;
NC_VAR_ARRAY_T vars;
NC_DIM_INFO_T *dim;
NC_ATT_INFO_T *att;
NC_TYPE_INFO_T *type;
@ -385,8 +390,8 @@ int nc4_type_free(NC_TYPE_INFO_T *type);
/* These list functions add and delete vars, atts. */
int nc4_nc4f_list_add(NC *nc, const char *path, int mode);
int nc4_var_list_add(NC_VAR_INFO_T **list, NC_VAR_INFO_T **var);
int nc4_var_list_del(NC_VAR_INFO_T **list, NC_VAR_INFO_T *var);
int nc4_var_add(NC_VAR_INFO_T **var);
int nc4_var_del(NC_VAR_INFO_T *var);
int nc4_dim_list_add(NC_DIM_INFO_T **list, NC_DIM_INFO_T **dim);
int nc4_dim_list_del(NC_DIM_INFO_T **list, NC_DIM_INFO_T *dim);
int nc4_att_list_add(NC_ATT_INFO_T **list, NC_ATT_INFO_T **att);

View File

@ -42,7 +42,6 @@ nc4_get_att(int ncid, NC *nc, int varid, const char *name,
char norm_name[NC_MAX_NAME + 1];
int i;
int retval = NC_NOERR;
const char** sp;
if (attnum) {
my_attnum = *attnum;
@ -261,14 +260,12 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
attlist = &grp->att;
else
{
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
{
attlist = &var->att;
break;
}
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
attlist = &var->att;
assert(var->varid == varid);
}
for (att = *attlist; att; att = att->l.next)
@ -364,7 +361,6 @@ nc4_put_att(int ncid, NC *nc, int varid, const char *name,
* attribute). */
if (!strcmp(att->name, _FillValue) && varid != NC_GLOBAL)
{
NC_ATT_INFO_T *varatt;
int size;
/* Fill value must be same type and have exactly one value */
@ -666,14 +662,12 @@ NC4_rename_att(int ncid, int varid, const char *name,
}
else
{
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
{
list = var->att;
break;
}
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
list = var->att;
}
for (att = list; att; att = att->l.next)
if (!strncmp(att->name, norm_newname, NC_MAX_NAME))
@ -777,16 +771,12 @@ NC4_del_att(int ncid, int varid, const char *name)
}
else
{
for(var = grp->var; var; var = var->l.next)
{
if (var->varid == varid)
{
attlist = &var->att;
break;
}
}
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
attlist = &var->att;
assert(var->varid == varid);
if (var->created)
locid = var->hdf_datasetid;
}

View File

@ -16,6 +16,9 @@ COPYRIGHT file for copying and redistribution conditions.
#include "nc4internal.h"
#include "nc4dispatch.h"
extern int nc4_vararray_add(NC_GRP_INFO_T *grp,
NC_VAR_INFO_T *var);
/* must be after nc4internal.h */
#include <H5DSpublic.h>
#include <H5Fpublic.h>
@ -506,7 +509,6 @@ NC4_create(const char* path, int cmode, size_t initialsz, int basepe,
MPI_Comm comm = MPI_COMM_WORLD;
MPI_Info info = MPI_INFO_NULL;
int res;
NC* nc;
assert(nc_file && path);
@ -1534,7 +1536,7 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
LOG((4, "%s: obj_name %s", __func__, obj_name));
/* Add a variable to the end of the group's var list. */
if ((retval = nc4_var_list_add(&grp->var, &var)))
if ((retval = nc4_var_add(&var)))
BAIL(retval);
/* Fill in what we already know. */
@ -1810,6 +1812,8 @@ read_var(NC_GRP_INFO_T *grp, hid_t datasetid, const char *obj_name,
} /* endif not HDF5 att */
} /* next attribute */
nc4_vararray_add(grp, var);
/* Is this a deflated variable with a chunksize greater than the
* current cache size? */
if ((retval = nc4_adjust_var_cache(grp, var)))
@ -1820,7 +1824,7 @@ exit:
{
if (incr_id_rc && H5Idec_ref(datasetid) < 0)
BAIL2(NC_EHDFERR);
if (var && nc4_var_list_del(&grp->var, var))
if (var && nc4_var_del(var))
BAIL2(NC_EHDFERR);
}
if (access_pid && H5Pclose(access_pid) < 0)
@ -2590,14 +2594,16 @@ nc4_open_hdf4_file(const char *path, int mode, NC *nc)
size_t var_type_size;
int a;
/* Add a variable to the end of the group's var list. */
if ((retval = nc4_var_list_add(&grp->var, &var)))
/* Add a variable. */
if ((retval = nc4_var_add(&var)))
return retval;
var->varid = grp->nvars++;
var->created = NC_TRUE;
var->written_to = NC_TRUE;
nc4_vararray_add(grp, var);
/* Open this dataset in HDF4 file. */
if ((var->sdsid = SDselect(h5->sdid, v)) == FAIL)
return NC_EVARMETA;
@ -3205,7 +3211,6 @@ NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
NC_GRP_INFO_T *grp;
NC_DIM_INFO_T *dim;
NC_ATT_INFO_T *att;
NC_VAR_INFO_T *var;
int retval;
LOG((2, "%s: ncid 0x%x", __func__, ncid));
@ -3225,9 +3230,13 @@ NC4_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
}
if (nvarsp)
{
int i;
*nvarsp = 0;
for (var = grp->var; var; var= var->l.next)
(*nvarsp)++;
for (i=0; i < grp->vars.nelems; i++)
{
if (grp->vars.value[i])
(*nvarsp)++;
}
}
if (nattsp)
{

View File

@ -392,6 +392,7 @@ NC4_inq_varids(int ncid, int *nvars, int *varids)
NC_VAR_INFO_T *var;
int v, num_vars = 0;
int retval;
int i;
LOG((2, "nc_inq_varids: ncid 0x%x", ncid));
@ -413,14 +414,13 @@ NC4_inq_varids(int ncid, int *nvars, int *varids)
{
/* This is a netCDF-4 group. Round up them doggies and count
* 'em. The list is in correct (i.e. creation) order. */
if (grp->var)
for (i=0; i < grp->vars.nelems; i++)
{
for (var = grp->var; var; var = var->l.next)
{
if (varids)
varids[num_vars] = var->varid;
num_vars++;
}
var = grp->vars.value[i];
if (!var) continue;
if (varids)
varids[num_vars] = var->varid;
num_vars++;
}
}

View File

@ -69,7 +69,7 @@ rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
{
NC_VAR_INFO_T *var;
NC_GRP_INFO_T *child_grp;
int d;
int d, i;
int retval;
assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0);
@ -81,7 +81,10 @@ rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
return retval;
/* Find any vars that use this dimension id. */
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
for (d = 0; d < var->ndims; d++)
if (var->dimids[d] == dimid && !var->dimscale)
{
@ -94,7 +97,7 @@ rec_reattach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
var->dimscale_attached[d] = NC_TRUE;
}
}
}
return NC_NOERR;
}
@ -109,7 +112,7 @@ rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
{
NC_VAR_INFO_T *var;
NC_GRP_INFO_T *child_grp;
int d;
int d, i;
int retval;
assert(grp && grp->name && dimid >= 0 && dimscaleid >= 0);
@ -121,7 +124,10 @@ rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
return retval;
/* Find any vars that use this dimension id. */
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
for (d = 0; d < var->ndims; d++)
if (var->dimids[d] == dimid && !var->dimscale)
{
@ -135,7 +141,7 @@ rec_detach_scales(NC_GRP_INFO_T *grp, int dimid, hid_t dimscaleid)
var->dimscale_attached[d] = NC_FALSE;
}
}
}
return NC_NOERR;
}
@ -146,11 +152,11 @@ nc4_open_var_grp2(NC_GRP_INFO_T *grp, int varid, hid_t *dataset)
NC_VAR_INFO_T *var;
/* Find the requested varid. */
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
break;
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
/* Open this dataset if necessary. */
if (!var->hdf_datasetid)
@ -867,7 +873,7 @@ int
nc4_get_vara(NC *nc, int ncid, int varid, const size_t *startp,
const size_t *countp, nc_type mem_nc_type, int is_long, void *data)
{
NC_GRP_INFO_T *grp, *g;
NC_GRP_INFO_T *grp;
NC_HDF5_FILE_INFO_T *h5;
NC_VAR_INFO_T *var;
NC_DIM_INFO_T *dim;
@ -1520,13 +1526,11 @@ write_netcdf4_dimid(hid_t datasetid, int dimid)
static int
var_create_dataset(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var, nc_bool_t write_dimid)
{
NC_GRP_INFO_T *g;
hid_t plistid = 0, access_plistid = 0, typeid = 0, spaceid = 0;
hsize_t chunksize[H5S_MAX_RANK], dimsize[H5S_MAX_RANK], maxdimsize[H5S_MAX_RANK];
int d;
void *fillp = NULL;
NC_DIM_INFO_T *dim = NULL;
int dims_found = 0;
char *name_to_use;
int retval = NC_NOERR;
@ -2054,13 +2058,14 @@ attach_dimscales(NC_GRP_INFO_T *grp)
{
NC_VAR_INFO_T *var;
NC_DIM_INFO_T *dim1;
NC_GRP_INFO_T *g;
int d;
int d, i;
int retval = NC_NOERR;
/* Attach dimension scales. */
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
/* Scales themselves do not attach. But I really wish they
* would. */
if (var->dimscale)
@ -2355,6 +2360,7 @@ static int
write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
{
int retval;
int i;
/* If there's no dimscale dataset for this dim, create one,
* and mark that it should be hidden from netCDF as a
@ -2433,20 +2439,23 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, nc_bool_t write_dimid)
/* Did we extend an unlimited dimension? */
if (dim->extended)
{
NC_VAR_INFO_T *v1;
NC_VAR_INFO_T *v1 = NULL;
assert(dim->unlimited);
/* If this is a dimension without a variable, then update
* the secret length information at the end of the NAME
* attribute. */
for (v1 = grp->var; v1; v1 = v1->l.next)
if (!strcmp(v1->name, dim->name))
for (i=0; i < grp->vars.nelems; i++)
{
if (grp->vars.value[i] && !strcmp(grp->vars.value[i]->name, dim->name))
{
v1 = grp->vars.value[i];
break;
}
}
if (v1)
{
hsize_t *new_size = NULL;
NC_DIM_INFO_T *dim1;
int d1;
/* Extend the dimension scale dataset to reflect the new
@ -2493,10 +2502,13 @@ nc4_rec_detect_need_to_preserve_dimids(NC_GRP_INFO_T *grp, nc_bool_t *bad_coord_
NC_GRP_INFO_T *child_grp;
int last_dimid = -1;
int retval;
int i;
/* Iterate over variables in this group */
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
/* Only matters for dimension scale variables, with non-scalar dimensionality */
if (var->dimscale && var->ndims)
{
@ -2549,10 +2561,11 @@ nc4_rec_detect_need_to_preserve_dimids(NC_GRP_INFO_T *grp, nc_bool_t *bad_coord_
int
nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
{
NC_DIM_INFO_T *dim;
NC_VAR_INFO_T *var;
NC_GRP_INFO_T *child_grp;
NC_DIM_INFO_T *dim = NULL;
NC_VAR_INFO_T *var = NULL;
NC_GRP_INFO_T *child_grp = NULL;
int coord_varid = -1;
int var_index = 0;
int retval;
assert(grp && grp->name && grp->hdf_grpid);
@ -2564,7 +2577,8 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
/* Set the pointers to the beginning of the list of dims & vars in this
* group. */
dim = grp->dim;
var = grp->var;
if (var_index < grp->vars.nelems)
var = grp->vars.value[var_index];
/* Because of HDF5 ordering the dims and vars have to be stored in
* this way to ensure that the dims and coordinate vars come out in
@ -2591,12 +2605,16 @@ nc4_rec_write_metadata(NC_GRP_INFO_T *grp, nc_bool_t bad_coord_order)
/* Write each var. When we get to the coord var we are waiting
* for (if any), then we break after writing it. */
for (wrote_coord = NC_FALSE; var && !wrote_coord; var = var->l.next)
for (wrote_coord = NC_FALSE; var && !wrote_coord; )
{
if ((retval = write_var(var, grp, bad_coord_order)))
return retval;
if (found_coord && var->varid == coord_varid)
wrote_coord = NC_TRUE;
if (++var_index < grp->vars.nelems)
var = grp->vars.value[var_index];
else
var = NULL;
}
} /* end while */
@ -3630,7 +3648,8 @@ nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
NC_VAR_INFO_T *var;
NC_DIM_INFO_T *dim;
int retval = NC_NOERR;
int i;
assert(grp && grp->name);
LOG((4, "%s: grp->name %s", __func__, grp->name));
@ -3641,8 +3660,10 @@ nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
/* Check all the vars in this group. If they have dimscale info,
* try and find a dimension for them. */
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
/* Check all vars and see if dim[i] != NULL if dimids[i] valid. */
int ndims = var->ndims;
int d;
@ -3976,7 +3997,6 @@ reportopenobjectsT(int log, hid_t fid, int ntypes, unsigned int* otypes)
idlist = (hid_t*)malloc(sizeof(hid_t)*maxobjs);
for(t=0;t<ntypes;t++) {
unsigned int ot = otypes[t];
if(ot < 0) break;
ocount = H5Fget_obj_ids(fid,ot,maxobjs,idlist);
for(i=0;i<ocount;i++) {
hid_t o = idlist[i];
@ -4063,11 +4083,8 @@ done:
static int
NC4_get_strict_att(NC_HDF5_FILE_INFO_T* h5)
{
int ncstat = NC_NOERR;
size_t size;
hid_t grp = -1;
hid_t attid = -1;
herr_t herr = 0;
/* Get root group */
grp = h5->root_grp->hdf_grpid; /* get root group */

View File

@ -25,7 +25,6 @@ NC4_fileinfo_init(void)
{
int stat = NC_NOERR;
unsigned major,minor,release;
int super;
/* Build nc properties */
memset((void*)&globalpropinfo,0,sizeof(globalpropinfo));
@ -145,10 +144,7 @@ int
NC4_put_propattr(NC_HDF5_FILE_INFO_T* h5)
{
int ncstat = NC_NOERR;
H5T_class_t t_class;
size_t size;
hid_t grp = -1;
hid_t exists = -1;
hid_t attid = -1;
hid_t aspace = -1;
hid_t atype = -1;

View File

@ -121,11 +121,11 @@ find_var_dim_max_length(NC_GRP_INFO_T *grp, int varid, int dimid, size_t *maxlen
*maxlen = 0;
/* Find this var. */
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
break;
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
/* If the var hasn't been created yet, its size is 0. */
if (!var->created)
@ -331,11 +331,9 @@ nc4_find_g_var_nc(NC *nc, int ncid, int varid,
return NC_ENOTVAR;
/* Find the var info. */
for ((*var) = (*grp)->var; (*var); (*var) = (*var)->l.next)
if ((*var)->varid == varid)
break;
if (!(*var))
if (varid < 0 || varid >= (*grp)->vars.nelems)
return NC_ENOTVAR;
(*var) = (*grp)->vars.value[varid];
return NC_NOERR;
}
@ -375,13 +373,19 @@ nc4_find_dim(NC_GRP_INFO_T *grp, int dimid, NC_DIM_INFO_T **dim,
int
nc4_find_var(NC_GRP_INFO_T *grp, const char *name, NC_VAR_INFO_T **var)
{
int i;
assert(grp && var && name);
/* Find the var info. */
for ((*var) = grp->var; (*var); (*var) = (*var)->l.next)
if (0 == strcmp(name, (*var)->name))
break;
*var = NULL;
for (i=0; i < grp->vars.nelems; i++)
{
if (0 == strcmp(name, grp->vars.value[i]->name))
{
*var = grp->vars.value[i];
break;
}
}
return NC_NOERR;
}
@ -498,6 +502,7 @@ nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len)
NC_GRP_INFO_T *g;
NC_VAR_INFO_T *var;
int retval;
int i;
assert(grp && len);
LOG((3, "nc4_find_dim_len: grp->name %s dimid %d", grp->name, dimid));
@ -510,9 +515,11 @@ nc4_find_dim_len(NC_GRP_INFO_T *grp, int dimid, size_t **len)
/* For all variables in this group, find the ones that use this
* dimension, and remember the max length. */
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
size_t mylen;
var = grp->vars.value[i];
if (!var) continue;
/* Find max length of dim in this variable... */
if ((retval = find_var_dim_max_length(grp, var->varid, dimid, &mylen)))
@ -541,16 +548,12 @@ nc4_find_grp_att(NC_GRP_INFO_T *grp, int varid, const char *name, int attnum,
attlist = grp->att;
else
{
for(var = grp->var; var; var = var->l.next)
{
if (var->varid == varid)
{
attlist = var->att;
break;
}
}
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
attlist = var->att;
assert(var->varid == varid);
}
/* Now find the attribute by name or number. If a name is provided,
@ -592,16 +595,12 @@ nc4_find_nc_att(int ncid, int varid, const char *name, int attnum,
attlist = grp->att;
else
{
for(var = grp->var; var; var = var->l.next)
{
if (var->varid == varid)
{
attlist = var->att;
break;
}
}
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
attlist = var->att;
assert(var->varid == varid);
}
/* Now find the attribute by name or number. If a name is provided, ignore the attnum. */
@ -667,10 +666,9 @@ obj_list_del(NC_LIST_NODE_T **list, NC_LIST_NODE_T *obj)
((NC_LIST_NODE_T *)obj->next)->prev = obj->prev;
}
/* Add to the end of a var list. Return a pointer to the newly
* added var. */
/* Return a pointer to the new var. */
int
nc4_var_list_add(NC_VAR_INFO_T **list, NC_VAR_INFO_T **var)
nc4_var_add(NC_VAR_INFO_T **var)
{
NC_VAR_INFO_T *new_var;
@ -683,9 +681,6 @@ nc4_var_list_add(NC_VAR_INFO_T **list, NC_VAR_INFO_T **var)
new_var->chunk_cache_nelems = nc4_chunk_cache_nelems;
new_var->chunk_cache_preemption = nc4_chunk_cache_preemption;
/* Add object to list */
obj_list_add((NC_LIST_NODE_T **)list, (NC_LIST_NODE_T *)new_var);
/* Set the var pointer, if one was given */
if (var)
*var = new_var;
@ -777,6 +772,7 @@ nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name)
NC_GRP_INFO_T *g;
NC_VAR_INFO_T *var;
uint32_t hash;
int i;
/* Any types of this name? */
for (type = grp->type; type; type = type->l.next)
@ -790,10 +786,13 @@ nc4_check_dup_name(NC_GRP_INFO_T *grp, char *name)
/* Any variables of this name? */
hash = hash_fast(name, strlen(name));
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
if (var->hash == hash && !strcmp(var->name, name))
return NC_ENAMEINUSE;
}
return NC_NOERR;
}
@ -1002,9 +1001,9 @@ nc4_type_free(NC_TYPE_INFO_T *type)
return NC_NOERR;
}
/* Delete a var from a var list, and free the memory. */
/* Delete a var, and free the memory. */
int
nc4_var_list_del(NC_VAR_INFO_T **list, NC_VAR_INFO_T *var)
nc4_var_del(NC_VAR_INFO_T *var)
{
NC_ATT_INFO_T *a, *att;
int ret;
@ -1012,9 +1011,6 @@ nc4_var_list_del(NC_VAR_INFO_T **list, NC_VAR_INFO_T *var)
if(var == NULL)
return NC_NOERR;
/* Remove the var from the linked list. */
obj_list_del((NC_LIST_NODE_T **)list, (NC_LIST_NODE_T *)var);
/* First delete all the attributes attached to this var. */
att = var->att;
while (att)
@ -1126,11 +1122,12 @@ int
nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
{
NC_GRP_INFO_T *g, *c;
NC_VAR_INFO_T *v, *var;
NC_VAR_INFO_T *var;
NC_ATT_INFO_T *a, *att;
NC_DIM_INFO_T *d, *dim;
NC_TYPE_INFO_T *type, *t;
int retval;
int i;
assert(grp);
LOG((3, "%s: grp->name %s", __func__, grp->name));
@ -1159,18 +1156,29 @@ nc4_rec_grp_del(NC_GRP_INFO_T **list, NC_GRP_INFO_T *grp)
}
/* Delete all vars. */
var = grp->var;
while (var)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
LOG((4, "%s: deleting var %s", __func__, var->name));
/* Close HDF5 dataset associated with this var, unless it's a
* scale. */
if (var->hdf_datasetid && H5Dclose(var->hdf_datasetid) < 0)
return NC_EHDFERR;
v = var->l.next;
if ((retval = nc4_var_list_del(&grp->var, var)))
if ((retval = nc4_var_del(var)))
return retval;
var = v;
grp->vars.value[i] = NULL;
}
/* Vars are all freed above. When eliminate linked-list,
then need to iterate value and free vars from it.
*/
if (grp->vars.nalloc != 0) {
assert(grp->vars.value != NULL);
free(grp->vars.value);
grp->vars.value = NULL;
grp->vars.nalloc = 0;
}
/* Delete all dims. */
@ -1459,7 +1467,7 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
char tabs[MAX_NESTS] = "";
char *dims_string = NULL;
char temp_string[10];
int t, retval, d;
int t, retval, d, i;
/* Come up with a number of tabs relative to the group. */
for (t = 0; t < tab_count && t < MAX_NESTS; t++)
@ -1476,8 +1484,10 @@ rec_print_metadata(NC_GRP_INFO_T *grp, int tab_count)
LOG((2, "%s DIMENSION - dimid: %d name: %s len: %d unlimited: %d",
tabs, dim->dimid, dim->name, dim->len, dim->unlimited));
for(var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
if(var->ndims > 0)
{
dims_string = (char*)malloc(sizeof(char)*(var->ndims*4));

View File

@ -94,11 +94,11 @@ NC4_set_var_chunk_cache(int ncid, int varid, size_t size, size_t nelems,
assert(nc && grp && h5);
/* Find the var. */
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
break;
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
/* Set the values. */
var->chunk_cache_size = size;
@ -157,11 +157,11 @@ NC4_get_var_chunk_cache(int ncid, int varid, size_t *sizep,
assert(nc && grp && h5);
/* Find the var. */
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
break;
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
/* Give the user what they want. */
if (sizep)
@ -340,6 +340,37 @@ nc4_find_default_chunksizes2(NC_GRP_INFO_T *grp, NC_VAR_INFO_T *var)
return NC_NOERR;
}
#define NC_ARRAY_GROWBY 4
int nc4_vararray_add(NC_GRP_INFO_T *grp,
NC_VAR_INFO_T *var)
{
NC_VAR_INFO_T **vp = NULL;
if (grp->vars.nalloc == 0) {
assert(grp->vars.nelems == 0);
vp = (NC_VAR_INFO_T **) malloc(NC_ARRAY_GROWBY * sizeof(NC_VAR_INFO_T *));
if(vp == NULL)
return NC_ENOMEM;
grp->vars.value = vp;
grp->vars.nalloc = NC_ARRAY_GROWBY;
}
else if(grp->vars.nelems +1 > grp->vars.nalloc) {
vp = (NC_VAR_INFO_T **) realloc(grp->vars.value,
(grp->vars.nalloc + NC_ARRAY_GROWBY) * sizeof(NC_VAR_INFO_T *));
if(vp == NULL)
return NC_ENOMEM;
grp->vars.value = vp;
grp->vars.nalloc += NC_ARRAY_GROWBY;
}
if(var != NULL) {
assert(var->varid == grp->vars.nelems);
grp->vars.value[grp->vars.nelems] = var;
grp->vars.nelems++;
}
return NC_NOERR;
}
/* This is called when a new netCDF-4 variable is defined. Break it
* down! */
static int
@ -413,8 +444,8 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
}
#endif
/* Add the var to the end of the list. */
if ((retval = nc4_var_list_add(&grp->var, &var)))
/* Add a new var. */
if ((retval = nc4_var_add(&var)))
BAIL(retval);
/* Now fill in the values in the var info structure. */
@ -426,6 +457,8 @@ nc_def_var_nc4(int ncid, const char *name, nc_type xtype,
var->ndims = ndims;
var->is_new_var = NC_TRUE;
nc4_vararray_add(grp, var);
/* If this is a user-defined type, there is a type_info struct with
* all the type information. For atomic types, fake up a type_info
* struct. */
@ -671,13 +704,11 @@ NC4_inq_var_all(int ncid, int varid, char *name, nc_type *xtypep,
}
/* Find the var. */
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
break;
/* Oh no! Maybe we couldn't find it (*sob*)! */
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
/* Copy the data to the user's data buffers. */
if (name)
@ -821,13 +852,11 @@ nc_def_var_extra(int ncid, int varid, int *shuffle, int *deflate,
assert(nc && grp && h5);
/* Find the var. */
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
break;
/* Oh no! Maybe we couldn't find it (*sob*)! */
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
/* Can't turn on contiguous and deflate/fletcher32/szip. */
if (contiguous)
@ -1129,6 +1158,7 @@ NC4_inq_varid(int ncid, const char *name, int *varidp)
char norm_name[NC_MAX_NAME + 1];
int retval;
uint32_t nn_hash;
int i;
if (!name)
return NC_EINVAL;
@ -1148,13 +1178,16 @@ NC4_inq_varid(int ncid, const char *name, int *varidp)
nn_hash = hash_fast(norm_name, strlen(norm_name));
/* Find var of this name. */
for (var = grp->var; var; var = var->l.next)
if (nn_hash == var->hash && !(strcmp(var->name, norm_name)))
for (i=0; i < grp->vars.nelems; i++)
{
*varidp = var->varid;
return NC_NOERR;
var = grp->vars.value[i];
if (!var) continue;
if (nn_hash == var->hash && !(strcmp(var->name, norm_name)))
{
*varidp = var->varid;
return NC_NOERR;
}
}
return NC_ENOTVAR;
}
@ -1171,6 +1204,7 @@ NC4_rename_var(int ncid, int varid, const char *name)
NC_VAR_INFO_T *var, *tmp_var;
uint32_t nn_hash;
int retval = NC_NOERR;
int i;
LOG((2, "%s: ncid 0x%x varid %d name %s",
__func__, ncid, varid, name));
@ -1197,8 +1231,10 @@ NC4_rename_var(int ncid, int varid, const char *name)
/* Check if name is in use, and retain a pointer to the correct variable */
nn_hash = hash_fast(name, strlen(name));
tmp_var = NULL;
for (var = grp->var; var; var = var->l.next)
for (i=0; i < grp->vars.nelems; i++)
{
var = grp->vars.value[i];
if (!var) continue;
if (nn_hash == var->hash && !strncmp(var->name, name, NC_MAX_NAME))
return NC_ENAMEINUSE;
if (var->varid == varid)
@ -1293,11 +1329,11 @@ NC4_var_par_access(int ncid, int varid, int par_access)
return NC_ENOPAR;
/* Find the var, and set its preference. */
for (var = grp->var; var; var = var->l.next)
if (var->varid == varid)
break;
if (!var)
return NC_ENOTVAR;
if (varid < 0 || varid >= grp->vars.nelems)
return NC_ENOTVAR;
var = grp->vars.value[varid];
if (!var) return NC_ENOTVAR;
assert(var->varid == varid);
if (par_access)
var->parallel_access = NC_COLLECTIVE;