reduced memory use for dimensions in netcdf-4

This commit is contained in:
Ed Hartnett 2010-07-01 13:36:41 +00:00
parent 1d5bbb7cfa
commit eb9f666352
5 changed files with 33 additions and 9 deletions

View File

@ -140,6 +140,8 @@ NC4_def_dim(int ncid, const char *name, size_t len, int *idp)
grp->dim->dimid = grp->file->nc4_info->next_dimid++;
/* Initialize the metadata for this dimension. */
if (!(grp->dim->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
return NC_ENOMEM;
strcpy(grp->dim->name, norm_name);
grp->dim->len = len;
grp->dim->dirty++;
@ -340,16 +342,23 @@ NC4_rename_dim(int ncid, int dimid, const char *name)
/* Save the old name, we'll need it to rename this object when we
* sync to HDF5 file. But if there already is an old_name saved,
* just stick with what we've got, since the user might be renaming
* the shit out of this thing, without ever syncing with the
* the crap out of this thing, without ever syncing with the
* file. When the sync does take place, we only need the original
* name of the dim, not any of the intermediate ones. If the user
* could just make up his mind, we could all get on to writing some
* data... */
if (!strlen(dim->old_name))
if (!dim->old_name)
{
if (!(dim->old_name = malloc((strlen(dim->name) + 1) * sizeof(char))))
return NC_ENOMEM;
strcpy(dim->old_name, dim->name);
}
/* Give the dimension its new name in metadata. UTF8 normalization
* has been done. */
free(dim->name);
if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char))))
return NC_ENOMEM;
strcpy(dim->name, norm_name);
return NC_NOERR;

View File

@ -421,6 +421,7 @@ read_scale(NC_GRP_INFO_T *grp, hid_t datasetid, char *obj_name,
int natts, a;
hid_t attid = 0;
char att_name[NC_MAX_HDF5_NAME + 1];
int max_len;
int retval;
/* Add a dimension for this scale. */
@ -454,8 +455,10 @@ read_scale(NC_GRP_INFO_T *grp, hid_t datasetid, char *obj_name,
break;
}
strncpy(grp->dim->name, obj_name, NC_MAX_NAME + 1);
max_len = strlen(obj_name) > NC_MAX_NAME ? NC_MAX_NAME : strlen(obj_name);
if (!(grp->dim->name = malloc((max_len + 1) * sizeof(char))))
return NC_ENOMEM;
strncpy(grp->dim->name, obj_name, max_len + 1);
if (SIZEOF_SIZE_T < 8 && scale_size > NC_MAX_UINT)
{
grp->dim->len = NC_MAX_UINT;
@ -2172,7 +2175,11 @@ nc4_open_hdf4_file(const char *path, int mode, NC_FILE_INFO_T *nc)
grp->ndims++;
dim = grp->dim;
dim->dimid = grp->file->nc4_info->next_dimid++;
strncpy(dim->name, dim_name, NC_MAX_NAME + 1);
if (strlen(dim_name) > NC_MAX_HDF4_NAME)
return NC_EMAXNAME;
if (!(dim->name = malloc(NC_MAX_HDF4_NAME + 1)))
return NC_ENOMEM;
strcpy(dim->name, dim_name);
if (dim_len)
dim->len = dim_len;
else

View File

@ -2202,7 +2202,7 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, int write_dimid)
/* If we define, and then rename this dimension before
* creation of the dimscale dataset, then we can throw
* away the old_name of the dimension. */
if (strlen(dim->old_name))
if (dim->old_name && strlen(dim->old_name))
strcpy(dim->old_name, "");
if (H5Pset_attr_creation_order(create_propid, H5P_CRT_ORDER_TRACKED|
@ -2295,7 +2295,7 @@ write_dim(NC_DIM_INFO_T *dim, NC_GRP_INFO_T *grp, int write_dimid)
}
/* Did we rename this dimension? */
if (strlen(dim->old_name))
if (dim->old_name && strlen(dim->old_name))
{
/* Rename the dimension's dataset in the HDF5 file. */
if (H5Gmove2(grp->hdf_grpid, dim->old_name, grp->hdf_grpid, dim->name) < 0)
@ -3838,6 +3838,8 @@ nc4_rec_match_dimscales(NC_GRP_INFO_T *grp)
dim = grp->dim;
dim->dimid = grp->file->nc4_info->next_dimid++;
sprintf(phony_dim_name, "phony_dim_%d", dim->dimid);
if (!(dim->name = malloc((strlen(phony_dim_name) + 1) * sizeof(char))))
return NC_ENOMEM;
strcpy(dim->name, phony_dim_name);
dim->len = h5dimlen[d];
if (h5dimlenmax[d] == H5S_UNLIMITED)

View File

@ -1055,6 +1055,12 @@ nc4_dim_list_del(NC_DIM_INFO_T **list, NC_DIM_INFO_T *dim)
if(dim->next)
dim->next->prev = dim->prev;
/* Free memory allocated for names. */
if (dim->name)
free(dim->name);
if (dim->old_name)
free(dim->old_name);
free(dim);
return NC_NOERR;
}

View File

@ -102,7 +102,7 @@ typedef enum {VAR, DIM, ATT} NC_OBJ_T;
/* This is a struct to handle the dim metadata. */
typedef struct NC_DIM_INFO
{
char name[NC_MAX_NAME + 1];
char *name;
size_t len;
int dimid;
int unlimited;
@ -110,7 +110,7 @@ typedef struct NC_DIM_INFO
struct NC_DIM_INFO *next;
struct NC_DIM_INFO *prev;
hid_t hdf_dimscaleid;
char old_name[NC_MAX_NAME + 1]; /* only used to rename dim */
char *old_name; /* only used to rename dim */
int dirty;
unsigned char coord_var_in_grp;
struct NC_VAR_INFO *coord_var; /* The coord var, if it exists. */