Merged latest trunk changes into my branch.

This commit is contained in:
Russ Rew 2010-10-04 16:53:34 +00:00
commit 4b3ea48bbd
12 changed files with 453 additions and 194 deletions

View File

@ -5,6 +5,9 @@ VERSION COMMENTS
------- --------
4.1.2-beta2 2010-08-08
Refactor of HDF5 file metadata scan for large speedup
in opening files, especially large files.
Complete rewrite of the handling of character datalist
constants. The heuristics are documented in ncgen.1.

View File

@ -17,7 +17,7 @@ AC_REVISION([$Id: configure.ac,v 1.450 2010/05/28 19:42:47 dmh Exp $])
AC_PREREQ([2.59])
# Initialize with name, version, and support email address.
AC_INIT([netCDF], [4.1.2-beta1], [support-netcdf@unidata.ucar.edu])
AC_INIT([netCDF], [4.1.2-beta2], [support-netcdf@unidata.ucar.edu])
# Create the VERSION file, which contains the package version from
# AC_INIT.

View File

@ -40,17 +40,17 @@ if BUILD_V2
LDADD += ${top_builddir}/libdispatch/libnetcdf2.la
endif
NC4_TESTS = tst_h_files tst_h_files2 tst_h_atts tst_h_atts3 tst_h_vars \
tst_h_vars2 tst_h_vars3 tst_h_grps tst_h_compounds tst_h_compounds2 \
tst_h_wrt_cmp tst_h_rd_cmp tst_h_vl tst_h_opaques tst_h_strings \
tst_h_strings1 tst_h_dimscales tst_h_dimscales1 tst_h_dimscales2 \
tst_h_dimscales3 tst_h_enums tst_dims tst_dims2 tst_dims3 tst_files \
tst_files4 tst_vars tst_varms tst_unlim_vars tst_converts \
tst_converts2 tst_grps tst_compounds tst_compounds2 tst_compounds3 \
tst_opaques tst_strings tst_interops tst_interops4 tst_interops5 \
tst_interops6 tst_enums tst_coords tst_coords2 tst_coords3 tst_vars3 \
tst_chunks tst_utf8 tst_fills tst_fillbug tst_xplatform tst_xplatform2 \
tst_h_atts2 tst_endian_fill
NC4_TESTS = tst_h_files tst_h_files2 tst_h_files4 tst_h_atts \
tst_h_atts3 tst_h_vars tst_h_vars2 tst_h_vars3 tst_h_grps \
tst_h_compounds tst_h_compounds2 tst_h_wrt_cmp tst_h_rd_cmp tst_h_vl \
tst_h_opaques tst_h_strings tst_h_strings1 tst_h_dimscales \
tst_h_dimscales1 tst_h_dimscales2 tst_h_dimscales3 tst_h_enums \
tst_dims tst_dims2 tst_dims3 tst_files tst_files4 tst_vars tst_varms \
tst_unlim_vars tst_converts tst_converts2 tst_grps tst_compounds \
tst_compounds2 tst_compounds3 tst_opaques tst_strings tst_interops \
tst_interops4 tst_interops5 tst_interops6 tst_enums tst_coords \
tst_coords2 tst_coords3 tst_vars3 tst_chunks tst_utf8 tst_fills \
tst_fillbug tst_xplatform tst_xplatform2 tst_h_atts2 tst_endian_fill
check_PROGRAMS = $(NC4_TESTS)
if LARGE_FILE_TESTS

View File

@ -1680,53 +1680,145 @@ read_dataset(NC_GRP_INFO_T *grp, char *obj_name)
return retval;
}
/* Given index, get the HDF5 name of an object. This function will try
* to use creation ordering, but if that fails (which causes a HDF5
* error message to be printed) then it will use default
/* Given index, get the HDF5 name of an object and the class of the
* object (group, type, dataset, etc.). This function will try to use
* creation ordering, but if that fails it will use default
* (i.e. alphabetical) ordering. (This is necessary to read existing
* HDF5 archives without creation ordering). */
static int
get_name_by_idx(NC_HDF5_FILE_INFO_T *h5, hid_t hdf_grpid, int i,
int *obj_class, char *obj_name)
{
H5O_info_t obj_info;
H5_index_t idx_field = H5_INDEX_CRT_ORDER;
ssize_t size;
herr_t res;
/* static int */
/* get_name_by_idx(NC_HDF5_FILE_INFO_T *h5, hid_t hdf_grpid, int i, */
/* int *obj_class, char *obj_name) */
/* { */
/* H5O_info_t obj_info; */
/* H5_index_t idx_field = H5_INDEX_CRT_ORDER; */
/* ssize_t size; */
/* herr_t res; */
/* These HDF5 macros prevent an HDF5 error message when a
* non-creation-ordered HDF5 file is opened. */
H5E_BEGIN_TRY {
res = H5Oget_info_by_idx(hdf_grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC,
i, &obj_info, H5P_DEFAULT);
} H5E_END_TRY;
/* /\* These HDF5 macros prevent an HDF5 error message when a */
/* * non-creation-ordered HDF5 file is opened. *\/ */
/* H5E_BEGIN_TRY { */
/* res = H5Oget_info_by_idx(hdf_grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, */
/* i, &obj_info, H5P_DEFAULT); */
/* } H5E_END_TRY; */
/* Creation ordering not available, so make sure this file is
* opened for read-only access. This is a plain old HDF5 file being
* read by netCDF-4. */
if (res < 0)
/* /\* Creation ordering not available, so make sure this file is */
/* * opened for read-only access. This is a plain old HDF5 file being */
/* * read by netCDF-4. *\/ */
/* if (res < 0) */
/* { */
/* if (H5Oget_info_by_idx(hdf_grpid, ".", H5_INDEX_NAME, H5_ITER_INC, */
/* i, &obj_info, H5P_DEFAULT) < 0) */
/* return NC_EHDFERR; */
/* if (!h5->no_write) */
/* return NC_ECANTWRITE; */
/* h5->ignore_creationorder = 1; */
/* idx_field = H5_INDEX_NAME; */
/* } */
/* *obj_class = obj_info.type; */
/* if ((size = H5Lget_name_by_idx(hdf_grpid, ".", idx_field, H5_ITER_INC, i, */
/* NULL, 0, H5P_DEFAULT)) < 0) */
/* return NC_EHDFERR; */
/* if (size > NC_MAX_NAME) */
/* return NC_EMAXNAME; */
/* if (H5Lget_name_by_idx(hdf_grpid, ".", idx_field, H5_ITER_INC, i, */
/* obj_name, size+1, H5P_DEFAULT) < 0) */
/* return NC_EHDFERR; */
/* LOG((4, "get_name_by_idx: encountered HDF5 object obj_name %s", obj_name)); */
/* return NC_NOERR; */
/* } */
/* This struct is used to pass information back from the callback
* function used with H5Literate. */
struct nc_hdf5_link_info
{
char name[NC_MAX_NAME + 1];
H5I_type_t obj_type;
};
/* This is a callback function for H5Literate().
The parameters of this callback function have the following values or
meanings:
g_id Group that serves as root of the iteration; same value as the
H5Lvisit group_id parameter
name Name of link, relative to g_id, being examined at current step of
the iteration
info H5L_info_t struct containing information regarding that link
op_data User-defined pointer to data required by the application in
processing the link; a pass-through of the op_data pointer provided
with the H5Lvisit function call
*/
static herr_t
visit_link(hid_t g_id, const char *name, const H5L_info_t *info,
void *op_data)
{
/* A positive return value causes the visit iterator to immediately
* return that positive value, indicating short-circuit
* success. The iterator can be restarted at the next group
* member. */
int ret = 1;
hid_t id;
/* Get the name, truncating at NC_MAX_NAME. */
strncpy(((struct nc_hdf5_link_info *)op_data)->name, name,
NC_MAX_NAME);
/* Open this critter. */
if ((id = H5Oopen_by_addr(g_id, info->u.address)) < 0)
return NC_EHDFERR;
/* Is this critter a group, type, data, attribute, or what? */
if ((((struct nc_hdf5_link_info *)op_data)->obj_type = H5Iget_type(id)) < 0)
ret = NC_EHDFERR;
/* Close the critter to release resouces. */
if (H5Oclose(id) < 0)
return NC_EHDFERR;
return ret;
}
/* Iterate over one link in the group at a time, returning
* link_info. The creation_ordering and idx pointers keep track of
* whether creation ordering works and the most recently examined
* link. */
static int
nc4_iterate_link(int *ordering_checked, int *creation_ordering,
hid_t grpid, hsize_t *idx, struct nc_hdf5_link_info *link_info)
{
int res = 0;
if (*creation_ordering)
{
if (H5Oget_info_by_idx(hdf_grpid, ".", H5_INDEX_NAME, H5_ITER_INC,
i, &obj_info, H5P_DEFAULT) < 0)
return NC_EHDFERR;
if (!h5->no_write)
return NC_ECANTWRITE;
h5->ignore_creationorder = 1;
idx_field = H5_INDEX_NAME;
/* These HDF5 macros prevent an HDF5 error message when a
* non-creation-ordered HDF5 file is opened. */
H5E_BEGIN_TRY {
res = H5Literate(grpid, H5_INDEX_CRT_ORDER, H5_ITER_INC,
idx, visit_link, (void *)link_info);
if (res < 0 && *ordering_checked)
return NC_EHDFERR;
} H5E_END_TRY;
}
*obj_class = obj_info.type;
if ((size = H5Lget_name_by_idx(hdf_grpid, ".", idx_field, H5_ITER_INC, i,
NULL, 0, H5P_DEFAULT)) < 0)
return NC_EHDFERR;
if (size > NC_MAX_NAME)
return NC_EMAXNAME;
if (H5Lget_name_by_idx(hdf_grpid, ".", idx_field, H5_ITER_INC, i,
obj_name, size+1, H5P_DEFAULT) < 0)
return NC_EHDFERR;
LOG((4, "get_name_by_idx: encountered HDF5 object obj_name %s", obj_name));
if (!*creation_ordering || res < 0)
{
if (H5Literate(grpid, H5_INDEX_NAME, H5_ITER_INC, idx,
visit_link, link_info) != 1)
return NC_EHDFERR;
/* If it didn't work with creation ordering, but did without,
* then we don't have creation ordering. */
*creation_ordering = 0;
}
*ordering_checked = 1;
return NC_NOERR;
}
@ -1735,10 +1827,12 @@ int
nc4_rec_read_types(NC_GRP_INFO_T *grp)
{
hsize_t num_obj, i;
int obj_class;
char obj_name[NC_MAX_HDF5_NAME + 1];
NC_HDF5_FILE_INFO_T *h5 = grp->file->nc4_info;
NC_GRP_INFO_T *child_grp;
hsize_t idx = 0;
struct nc_hdf5_link_info link_info;
int ordering_checked = 0;
int creation_ordering = 1; /* Assume we have it. */
int retval = NC_NOERR;
assert(grp && grp->name);
@ -1770,23 +1864,28 @@ nc4_rec_read_types(NC_GRP_INFO_T *grp)
/* For each object in the group... */
for (i = 0; i < num_obj; i++)
{
if ((retval = get_name_by_idx(h5, grp->hdf_grpid, i, &obj_class, obj_name)))
if ((retval = nc4_iterate_link(&ordering_checked, &creation_ordering,
grp->hdf_grpid, &idx, &link_info)))
return retval;
/* Without creation ordering, file must be read-only. */
if (!i && !creation_ordering && !h5->no_write)
return NC_ECANTWRITE;
/* Deal with groups and types; ignore the rest. */
if (obj_class == H5O_TYPE_GROUP)
if (link_info.obj_type == H5I_GROUP)
{
LOG((3, "found group %s", obj_name));
LOG((3, "found group %s", link_info.name));
if ((retval = nc4_grp_list_add(&(grp->children), h5->next_nc_grpid++,
grp, grp->file, obj_name, &child_grp)))
grp, grp->file, link_info.name, &child_grp)))
return retval;
if ((retval = nc4_rec_read_types(child_grp)))
return retval;
}
else if (obj_class == H5O_TYPE_NAMED_DATATYPE)
else if (link_info.obj_type == H5I_DATATYPE)
{
LOG((3, "found datatype %s", obj_name));
if ((retval = read_type(grp, obj_name)))
LOG((3, "found datatype %s", link_info.name));
if ((retval = read_type(grp, link_info.name)))
return retval;
}
}
@ -1801,10 +1900,11 @@ int
nc4_rec_read_vars(NC_GRP_INFO_T *grp)
{
hsize_t num_obj, i;
int obj_class;
char obj_name[NC_MAX_HDF5_NAME + 1];
NC_HDF5_FILE_INFO_T *h5 = grp->file->nc4_info;
NC_GRP_INFO_T *child_grp;
struct nc_hdf5_link_info link_info;
hsize_t idx = 0;
int ordering_checked = 0;
int creation_ordering = 1; /* Assume we have it. */
int retval = NC_NOERR;
assert(grp && grp->name && grp->hdf_grpid > 0);
@ -1817,18 +1917,19 @@ nc4_rec_read_vars(NC_GRP_INFO_T *grp)
/* For each object in the group... */
for (i = 0; i < num_obj; i++)
{
if ((retval = get_name_by_idx(h5, grp->hdf_grpid, i, &obj_class, obj_name)))
if ((retval = nc4_iterate_link(&ordering_checked, &creation_ordering,
grp->hdf_grpid, &idx, &link_info)))
return retval;
/* Deal with datasets. */
switch(obj_class)
switch(link_info.obj_type)
{
case H5O_TYPE_GROUP:
LOG((3, "re-encountering group %s", obj_name));
case H5I_GROUP:
LOG((3, "re-encountering group %s", link_info.name));
/* The NC_GROUP_INFO_T for this group already exists. Find it. */
for (child_grp = grp->children; child_grp; child_grp = child_grp->next)
if (!strcmp(child_grp->name, obj_name))
if (!strcmp(child_grp->name, link_info.name))
break;
if (!child_grp)
return NC_EHDFERR;
@ -1837,25 +1938,20 @@ nc4_rec_read_vars(NC_GRP_INFO_T *grp)
if ((retval = nc4_rec_read_vars(child_grp)))
return retval;
break;
case H5O_TYPE_DATASET:
LOG((3, "found dataset %s", obj_name));
case H5I_DATASET:
LOG((3, "found dataset %s", link_info.name));
/* Learn all about this dataset, which may be a dimscale
* (i.e. dimension metadata), or real data. */
if ((retval = read_dataset(grp, obj_name)))
if ((retval = read_dataset(grp, link_info.name)))
return retval;
break;
case H5O_TYPE_NAMED_DATATYPE:
LOG((3, "already handled type %s", obj_name));
break;
case H5G_LINK:
/* Since I don't know what to do with linkes, I'll just
* ignore them. */
LOG((3, "This is a link object. Have a nice day."));
case H5I_DATATYPE:
LOG((3, "already handled type %s", link_info.name));
break;
default:
LOG((0, "Unknown object class %d in nc4_rec_read_vars!",
obj_class));
link_info.obj_type));
}
}
@ -1929,9 +2025,6 @@ nc4_open_file(const char *path, int mode, MPI_Comm comm,
nc4_chunk_cache_size, nc4_chunk_cache_nelems, nc4_chunk_cache_preemption));
#endif /* USE_PARALLEL */
/*if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
BAIL(NC_EHDFERR);*/
/* The NetCDF-3.x prototype contains an mode option NC_SHARE for
multiple processes accessing the dataset concurrently. As there
is no HDF5 equivalent, NC_SHARE is treated as NC_NOWRITE. */
@ -2698,16 +2791,9 @@ NC4_close(int ncid)
nc4_file_list_del(nc);
}
/* Reset the ncid numbers if there are no more files open. */
if(count_NCList() == 0)
{
/* If all files have been closed, close he HDF5 library. This will
* clean up some stuff that HDF5 is leaving open. */
/* if ((retval = H5close()) < 0)
return NC_EHDFERR;*/
/* Reset the ncid numbers. */
nc4_file_list_free();
}
return NC_NOERR;
}

View File

@ -227,7 +227,7 @@ nc4_find_nc4_grp(int ncid, NC_GRP_INFO_T **grp)
/* If we can't find it, the grp id part of ncid is bad. */
if (!(*grp = nc4_rec_find_grp(f->nc4_info->root_grp, (ncid & GRP_ID_MASK))))
return NC_EBADGRPID;
return NC_EBADID;
return NC_NOERR;
}
@ -243,7 +243,7 @@ nc4_find_grp_h5(int ncid, NC_GRP_INFO_T **grp, NC_HDF5_FILE_INFO_T **h5)
assert(f->nc4_info->root_grp);
/* If we can't find it, the grp id part of ncid is bad. */
if (!(*grp = nc4_rec_find_grp(f->nc4_info->root_grp, (ncid & GRP_ID_MASK))))
return NC_EBADGRPID;
return NC_EBADID;
*h5 = (*grp)->file->nc4_info;
assert(*h5);
} else {
@ -264,7 +264,7 @@ nc4_find_nc_grp_h5(int ncid, NC_FILE_INFO_T **nc, NC_GRP_INFO_T **grp,
assert(f->nc4_info->root_grp);
/* If we can't find it, the grp id part of ncid is bad. */
if (!(*grp = nc4_rec_find_grp(f->nc4_info->root_grp, (ncid & GRP_ID_MASK))))
return NC_EBADGRPID;
return NC_EBADID;
*h5 = (*grp)->file->nc4_info;
assert(*h5);

View File

@ -924,12 +924,13 @@ nc_inq_var_chunking_ints(int ncid, int varid, int *contiguousp, int *chunksizesp
NULL, NULL, NULL, NULL);
/* Copy to size_t array. */
for (i = 0; i < var->ndims; i++)
{
chunksizesp[i] = cs[i];
if (cs[i] > NC_MAX_INT)
retval = NC_ERANGE;
}
if (*contiguousp == NC_CHUNKED)
for (i = 0; i < var->ndims; i++)
{
chunksizesp[i] = cs[i];
if (cs[i] > NC_MAX_INT)
retval = NC_ERANGE;
}
if (var->ndims)
free(cs);

View File

@ -223,61 +223,6 @@ main()
ERR;
}
SUMMARIZE_ERR;
printf("*** Creating HDF5 file in the canonical netCDF-4 way...");
{
hid_t fapl_id, fcpl_id, fileid, grpid, fileid2;
hsize_t num_obj;
/* Create file access and create property lists. */
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
/* Set latest_format in access propertly list. This ensures that
* the latest, greatest, HDF5 versions are used in the file. */
if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0) ERR;
/* Set H5P_CRT_ORDER_TRACKED in the creation property list. This
* turns on HDF5 creation ordering in the file. */
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
/* Set close degree. */
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
/* Create the file. */
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;
/* Open the root group. */
if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
/* Close up. */
if (H5Pclose(fapl_id) < 0 ||
H5Pclose(fcpl_id) < 0 ||
H5Gclose(grpid) < 0 ||
H5Fclose(fileid) < 0)
ERR;
/* Reopen the file and check it. */
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, fapl_id)) < 0) ERR;
if (H5Gget_num_objs(fileid, &num_obj) < 0) ERR;
if (num_obj) ERR;
/* Open another copy of the same file. Must use the same file
* access degree or HDF5 will not open the file. */
if ((fileid2 = H5Fopen(FILE_NAME, H5F_ACC_RDWR, fapl_id)) < 0) ERR;
if (H5Fclose(fileid) < 0) ERR;
if (H5Fclose(fileid2) < 0) ERR;
if (H5Pclose(fapl_id) < 0) ERR;
}
SUMMARIZE_ERR;
#ifdef LARGE_FILE_TESTS
#define NDIMS2 2

204
libsrc4/tst_h_files4.c Normal file
View File

@ -0,0 +1,204 @@
/* This is part of the netCDF package.
Copyright 2005 University Corporation for Atmospheric Research/Unidata
See COPYRIGHT file for conditions of use.
Test HDF5 file code. These are not intended to be exhaustive tests,
but they use HDF5 the same way that netCDF-4 does, so if these
tests don't work, than netCDF-4 won't work either.
$Id$
*/
#include <config.h>
#include <nc_tests.h>
#include "netcdf.h"
#include <nc4internal.h>
#include <H5DSpublic.h>
#define FILE_NAME "tst_h_files4.h5"
/* Heavy duty test file...*/
/*#define FILE_NAME "/machine/downloads/T159_1978110112.nc4"*/
herr_t
obj_iter(hid_t o_id, const char *name, const H5O_info_t *object_info,
void *op_data)
{
*(int *)op_data = object_info->type;
return 1;
}
/* This is a callback function for H5Literate().
The parameters of this callback function have the following values or
meanings:
g_id Group that serves as root of the iteration; same value as the
H5Lvisit group_id parameter
name Name of link, relative to g_id, being examined at current step of
the iteration
info H5L_info_t struct containing information regarding that link
op_data User-defined pointer to data required by the application in
processing the link; a pass-through of the op_data pointer provided
with the H5Lvisit function call
*/
herr_t
op_func (hid_t g_id, const char *name, const H5L_info_t *info,
void *op_data)
{
hid_t id;
H5I_type_t obj_type;
strcpy((char *)op_data, name);
if ((id = H5Oopen_by_addr(g_id, info->u.address)) < 0) ERR;
/* Using H5Ovisit is really slow. Use H5Iget_type for a fast
* answer. */
/* if (H5Ovisit(id, H5_INDEX_CRT_ORDER, H5_ITER_INC, obj_iter, */
/* (void *)&obj_class) != 1) ERR; */
if ((obj_type = H5Iget_type(id)) < 0) ERR;
if (H5Oclose(id) < 0) ERR;
/* Turn this on to learn what type of object you've opened. */
/* switch (obj_type) */
/* { */
/* case H5I_GROUP: */
/* printf("group %s\n", name); */
/* break; */
/* case H5I_DATATYPE: */
/* printf("type %s\n", name); */
/* break; */
/* case H5I_DATASET: */
/* printf("data %s\n", name); */
/* break; */
/* default: */
/* printf("unknown class\n"); */
/* } */
return 1;
}
int
main()
{
printf("\n*** Checking HDF5 file functions.\n");
printf("*** Creating HDF5 file in the canonical netCDF-4 way...");
{
hid_t fapl_id, fcpl_id, fileid, grpid, fileid2;
hsize_t num_obj;
/* Create file access and create property lists. */
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
/* Set latest_format in access propertly list. This ensures that
* the latest, greatest, HDF5 versions are used in the file. */
/* if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST,
H5F_LIBVER_LATEST) < 0) ERR;*/
/* Set H5P_CRT_ORDER_TRACKED in the creation property list. This
* turns on HDF5 creation ordering in the file. */
if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
H5P_CRT_ORDER_INDEXED)) < 0) ERR;
/* Set close degree. */
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
/* Create the file. */
if ((fileid = H5Fcreate(FILE_NAME, H5F_ACC_TRUNC, fcpl_id, fapl_id)) < 0) ERR;
/* Open the root group. */
if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
/* Close up. */
if (H5Pclose(fapl_id) < 0 ||
H5Pclose(fcpl_id) < 0 ||
H5Gclose(grpid) < 0 ||
H5Fclose(fileid) < 0)
ERR;
/* Reopen the file and check it. */
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDWR, fapl_id)) < 0) ERR;
if (H5Gget_num_objs(fileid, &num_obj) < 0) ERR;
if (num_obj) ERR;
/* Open another copy of the same file. Must use the same file
* access degree or HDF5 will not open the file. */
if ((fileid2 = H5Fopen(FILE_NAME, H5F_ACC_RDWR, fapl_id)) < 0) ERR;
if (H5Fclose(fileid) < 0) ERR;
if (H5Fclose(fileid2) < 0) ERR;
if (H5Pclose(fapl_id) < 0) ERR;
}
SUMMARIZE_ERR;
printf("*** Opening a HDF5 file with H5Literate...");
{
hid_t fapl_id, fileid, grpid;
hsize_t idx = 0;
char obj_name[NC_MAX_NAME + 1];
hsize_t num_obj;
int i;
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
if (H5Pset_cache(fapl_id, 0, CHUNK_CACHE_NELEMS, CHUNK_CACHE_SIZE,
CHUNK_CACHE_PREEMPTION) < 0) ERR;
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, fapl_id)) < 0) ERR;
if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
for (i = 0; i < num_obj; i++)
{
if (H5Literate(grpid, H5_INDEX_CRT_ORDER, H5_ITER_INC, &idx, op_func,
(void *)obj_name) != 1) ERR;
printf("encountered object %s\n", obj_name);
}
if (H5Gclose(grpid) < 0) ERR;
if (H5Fclose(fileid) < 0) ERR;
if (H5Pclose(fapl_id) < 0) ERR;
}
SUMMARIZE_ERR;
printf("*** Opening a HDF5 file in the canonical netCDF-4 way...");
{
hid_t fapl_id, fileid, grpid;
H5_index_t idx_field = H5_INDEX_CRT_ORDER;
H5O_info_t obj_info;
hsize_t num_obj;
ssize_t size;
char obj_name[NC_MAX_NAME + 1];
int i;
if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
if (H5Pset_fclose_degree(fapl_id, H5F_CLOSE_STRONG)) ERR;
if (H5Pset_cache(fapl_id, 0, CHUNK_CACHE_NELEMS, CHUNK_CACHE_SIZE,
CHUNK_CACHE_PREEMPTION) < 0) ERR;
if ((fileid = H5Fopen(FILE_NAME, H5F_ACC_RDONLY, fapl_id)) < 0) ERR;
if ((grpid = H5Gopen2(fileid, "/", H5P_DEFAULT)) < 0) ERR;
/* How many objects in this group? */
if (H5Gget_num_objs(grpid, &num_obj) < 0) ERR;
for (i = 0; i < num_obj; i++)
{
if (H5Oget_info_by_idx(grpid, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC,
i, &obj_info, H5P_DEFAULT)) ERR;
if ((size = H5Lget_name_by_idx(grpid, ".", idx_field, H5_ITER_INC, i,
NULL, 0, H5P_DEFAULT)) < 0) ERR;
if (H5Lget_name_by_idx(grpid, ".", idx_field, H5_ITER_INC, i,
obj_name, size+1, H5P_DEFAULT) < 0) ERR;
}
if (H5Gclose(grpid) < 0) ERR;
if (H5Fclose(fileid) < 0) ERR;
if (H5Pclose(fapl_id) < 0) ERR;
}
SUMMARIZE_ERR;
FINAL_RESULTS;
}

View File

@ -200,6 +200,7 @@ main()
dims[0] = DIM1_LEN;
if ((propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
if (H5Pset_layout(propid, H5D_CHUNKED)) ERR;
if (H5Pset_chunk(propid, 1, dims)) ERR;
if (H5Pset_deflate(propid, DEFLATE_LEVEL)) ERR;
if ((spaceid = H5Screate_simple(1, dims, dims)) < 0) ERR;
if ((datasetid = H5Dcreate(grpid, VAR_BOOL_NAME, H5T_NATIVE_HBOOL,
@ -258,6 +259,7 @@ main()
dims[0] = DIM1_LEN;
if ((propid = H5Pcreate(H5P_DATASET_CREATE)) < 0) ERR;
if (H5Pset_layout(propid, H5D_CHUNKED)) ERR;
if (H5Pset_chunk(propid, 1, dims)) ERR;
if (H5Pset_shuffle(propid)) ERR;
if (H5Pset_deflate(propid, DEFLATE_LEVEL)) ERR;
if (H5Pset_fletcher32(propid)) ERR;

View File

@ -80,21 +80,21 @@ program f90tst_vars_vlen
! if (retval .ne. nf_noerr) call handle_err(retval)
! if (num_types .ne. max_types) stop 2
! ! Use nf_inq_user_type to confirm this is an vlen type, with base
! ! size 4, base type NF_INT.
! ! Use nf_inq_user_type to confirm this is an vlen type, with vlen
! ! size 16, base type NF_INT.
! retval = nf_inq_user_type(ncid, typeids(1), type_name, type_size, &
! base_type, nfields, class)
! if (retval .ne. nf_noerr) call handle_err(retval)
! if (type_name(1:len(vlen_type_name)) .ne. vlen_type_name .or. &
! type_size .ne. 4 .or. base_type .ne. nf_int .or. &
! nfields .ne. 0 .or. class .ne. nf_vlen) stop 2
! type_size .ne. 16 .or. base_type .ne. nf_int .or. &
! nfields .ne. 0 .or. class .ne. nf_vlen) stop 3
! ! Use nf_inq_vlen and make sure we get the same answers as we did
! ! with nf_inq_user_type.
! retval = nf_inq_vlen(ncid, typeids(1), type_name, base_size, base_type)
! if (retval .ne. nf_noerr) call handle_err(retval)
! if (type_name(1:len(vlen_type_name)) .ne. vlen_type_name .or. &
! base_type .ne. nf_int .or. base_size .ne. 4) stop 2
! base_type .ne. nf_int .or. base_size .ne. 16) stop 4
! ! Read the vlen attribute.
! retval = nf_get_att(ncid, NF_GLOBAL, 'att1', vlen_in)
@ -104,29 +104,29 @@ program f90tst_vars_vlen
! retval = nf_get_vlen_element(ncid, vlen_typeid, vlen_in, &
! vlen_len_in, data1_in)
! if (retval .ne. nf_noerr) call handle_err(retval)
! if (vlen_len_in .ne. vlen_len) stop 2
! if (vlen_len_in .ne. vlen_len) stop 5
! ! Check the data
! do x = 1, vlen_len
! if (data1(x) .ne. data1_in(x)) stop 2
! if (data1(x) .ne. data1_in(x)) stop 6
! end do
! ! Close the file.
! retval = nf_close(ncid)
! if (retval .ne. nf_noerr) call handle_err(retval)
print *,'*** SUCCESS!'
contains
! This subroutine handles errors by printing an error message and
! exiting with a non-zero status.
subroutine handle_err(errcode)
use netcdf
implicit none
integer, intent(in) :: errcode
! print *,'*** SUCCESS!'
! contains
! ! This subroutine handles errors by printing an error message and
! ! exiting with a non-zero status.
! subroutine handle_err(errcode)
! use netcdf
! implicit none
! integer, intent(in) :: errcode
if(errcode /= nf90_noerr) then
print *, 'Error: ', trim(nf90_strerror(errcode))
stop 2
endif
end subroutine handle_err
! if(errcode /= nf90_noerr) then
! print *, 'Error: ', trim(nf90_strerror(errcode))
! stop 1
! endif
! end subroutine handle_err
end program f90tst_vars_vlen

View File

@ -115,6 +115,7 @@ array_decls:
array_decl:
'[' SCAN_WORD ']' {$$=dap_arraydecl(parsestate,null,$2);}
| '[' name '=' SCAN_WORD ']' {$$=dap_arraydecl(parsestate,$2,$4);}
| '[' '=' SCAN_WORD ']' {$$=dap_arraydecl(parsestate,null,$3);}
| error
{daperror(parsestate,"Illegal dimension declaration"); YYABORT;}
;

View File

@ -22,11 +22,12 @@
/* Note: TMPPATH must end in '/' */
#ifdef __CYGWIN__
/*#define TMPPATH "c:/temp/"*/
#define TMPPATH1 "c:/temp/"
#define TMPPATH2 "./"
#else
/*#define TMPPATH "/tmp/"*/
#define TMPPATH1 "/tmp/"
#define TMPPATH2 "./"
#endif
#define TMPPATH "./"
/* Define default rc files */
#define DODSRC ".dodsrc"
@ -36,6 +37,7 @@ static int ocextractdds(OCstate*,OCtree*);
static char* constraintescape(const char* url);
#ifdef OC_DISK_STORAGE
static OCerror createtempfile(OCstate*,OCtree*);
static int createtempfile1(char*,char*);
#endif
static void ocsetcurlproperties(OCstate*);
@ -455,12 +457,36 @@ ocextractdds(OCstate* state, OCtree* tree)
static OCerror
createtempfile(OCstate* state, OCtree* tree)
{
int fd,c,slen = strlen(TMPPATH) + strlen("datadds") + strlen("XXXXXX");
char* name = (char*)ocmalloc(slen+1);
char* p;
int fd,slen;
char* name;
slen = strlen(TMPPATH1);
if(slen < strlen(TMPPATH2)) slen = strlen(TMPPATH2);
slen += strlen("datadds") + strlen("XXXXXX");
name = (char*)ocmalloc(slen+1);
MEMCHECK(name,OC_ENOMEM);
strcpy(name,TMPPATH);
strcpy(name,"datadds");
fd = createtempfile1(name, TMPPATH1);
if(fd < 0)
fd = createtempfile1(name, TMPPATH2);
if(fd < 0) {
oc_log(LOGERR,"oc_open: attempt to open tmp file %s failed",name);
return errno;
}
oc_log(LOGNOTE,"oc_open: using tmp file: %s",name);
tree->data.filename = name; /* remember our tmp file name */
tree->data.file = fdopen(fd,"w+");
if(tree->data.file == NULL) return OC_EOPEN;
/* unlink the temp file so it will automatically be reclaimed */
if(ocdebug == 0) unlink(tree->data.filename);
return OC_NOERR;
}
int
createtempfile1(char* name, char* tmppath)
{
char* p;
int c,fd;
strcpy(name,tmppath);
strcat(name,"datadds");
strcat(name,"XXXXXX");
p = name + strlen("datadds");
/* \', and '/' to '_' and '.' to '-'*/
@ -471,16 +497,7 @@ createtempfile(OCstate* state, OCtree* tree)
/* Note Potential problem: old versions of this function
leave the file in mode 0666 instead of 0600 */
fd = mkstemp(name);
if(fd < 0) {
oc_log(LOGERR,"oc_open: attempt to open tmp file %s failed",name);
return errno;
}
tree->data.filename = name; /* remember our tmp file name */
tree->data.file = fdopen(fd,"w+");
if(tree->data.file == NULL) return OC_EOPEN;
/* unlink the temp file so it will automatically be reclaimed */
if(ocdebug == 0) unlink(tree->data.filename);
return OC_NOERR;
return fd;
}
#endif /*OC_DISK_STORAGE*/