From f4d5e4e291d3a7a8a7ae5d0895a9abb4927fb4d3 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Thu, 22 Aug 2019 11:30:44 -0600 Subject: [PATCH 1/3] now trying to move ncid --- include/nc.h | 1 + include/nc4internal.h | 1 + include/netcdf.h | 66 +++++++---------- include/netcdf_dispatch.h | 143 +++++++++++++++++++----------------- libdispatch/nclistmgr.c | 29 ++++++++ libsrc4/nc4internal.c | 58 +++++++++------ unit_test/tst_nc4internal.c | 50 ++++++------- 7 files changed, 188 insertions(+), 160 deletions(-) diff --git a/include/nc.h b/include/nc.h index de6e0482dc..c9be6e751d 100644 --- a/include/nc.h +++ b/include/nc.h @@ -72,6 +72,7 @@ extern int add_to_NCList(NC*); extern void del_from_NCList(NC*);/* does not free object */ extern NC* find_in_NCList(int ext_ncid); extern NC* find_in_NCList_by_name(const char*); +extern int move_in_NCList(NC *ncp, int new_id); extern void free_NCList(void);/* reclaim whole list */ extern int count_NCList(void); /* return # of entries in NClist */ extern int iterate_NCList(int i,NC**); /* Walk from 0 ...; ERANGE return => stop */ diff --git a/include/nc4internal.h b/include/nc4internal.h index b4e07c7d34..3132c09eae 100644 --- a/include/nc4internal.h +++ b/include/nc4internal.h @@ -388,6 +388,7 @@ int nc4_file_list_add(int ncid, const char *path, int mode, int nc4_file_list_get(int ncid, char **path, int *mode, void **dispatchdata); int nc4_file_list_del(int ncid); +int nc4_file_change_ncid(int ncid, unsigned short new_ncid_index); int nc4_var_list_add(NC_GRP_INFO_T* grp, const char* name, int ndims, NC_VAR_INFO_T **var); int nc4_var_list_add2(NC_GRP_INFO_T* grp, const char* name, diff --git a/include/netcdf.h b/include/netcdf.h index c8b00395c3..8f3a14dc7e 100644 --- a/include/netcdf.h +++ b/include/netcdf.h @@ -21,7 +21,7 @@ See \ref copyright file for more info. #include #endif -/*! The nc_type type is just an int. */ +/** The nc_type type is just an int. */ typedef int nc_type; #if defined(__cplusplus) @@ -78,7 +78,8 @@ extern "C" { #define NC_FILL_STRING ((char *)"") /**@}*/ -/*! Max or min values for a type. Nothing greater/smaller can be +/** + * Max or min values for a type. Nothing greater/smaller can be * stored in a netCDF file for their associated types. Recall that a C * compiler may define int to be any length it wants, but a NC_INT is * *always* a 4 byte signed int. On a platform with 64 bit ints, @@ -248,25 +249,16 @@ Use this in mode flags for both nc_create() and nc_open(). */ #define NC_GLOBAL -1 /** -Maximum for classic library. - -In the classic netCDF model there are maximum values for the number of -dimensions in the file (\ref NC_MAX_DIMS), the number of global or per -variable attributes (\ref NC_MAX_ATTRS), the number of variables in -the file (\ref NC_MAX_VARS), and the length of a name (\ref -NC_MAX_NAME). - -These maximums are enforced by the interface, to facilitate writing -applications and utilities. However, nothing is statically allocated -to these sizes internally. - -These maximums are not used for netCDF-4/HDF5 files unless they were -created with the ::NC_CLASSIC_MODEL flag. - -As a rule, NC_MAX_VAR_DIMS <= NC_MAX_DIMS. - -NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits - are *not* enforced after version 4.5.0 + * Maximum for classic library. + * + * In the classic netCDF model there are maximum values for the number + * of dimensions in the file (@ref NC_MAX_DIMS), the number of global + * or per variable attributes (@ref NC_MAX_ATTRS), the number of + * variables in the file (@ref NC_MAX_VARS), and the length of a name + * (@ref NC_MAX_NAME). + * + * Only NC_MAX_NAME and NC_MAX_VAR_DIMS are enforced by the library, + * since version 4.5.0. */ /**@{*/ #define NC_MAX_DIMS 1024 /* not enforced after 4.5.0 */ @@ -276,11 +268,12 @@ NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits #define NC_MAX_VAR_DIMS 1024 /**< max per variable dimensions */ /**@}*/ -/** This is the max size of an SD dataset name in HDF4 (from HDF4 documentation).*/ +/** This is the max size of an SD dataset name in HDF4 (from HDF4 + * documentation). */ #define NC_MAX_HDF4_NAME 64 /** In HDF5 files you can set the endianness of variables with - nc_def_var_endian(). This define is used there. */ + nc_def_var_endian(). This define is used to specify endianness. */ /**@{*/ #define NC_ENDIAN_NATIVE 0 #define NC_ENDIAN_LITTLE 1 @@ -288,7 +281,7 @@ NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits /**@}*/ /** In HDF5 files you can set storage for each variable to be either - * contiguous or chunked, with nc_def_var_chunking(). This define is + * contiguous or chunked, with nc_def_var_chunking(). This define is * used there. */ /**@{*/ #define NC_CHUNKED 0 @@ -297,7 +290,7 @@ NOTE: The NC_MAX_DIMS, NC_MAX_ATTRS, and NC_MAX_VARS limits /** In HDF5 files you can set check-summing for each variable. Currently the only checksum available is Fletcher-32, which can be set -with the function nc_def_var_fletcher32. These defines are used +with the function nc_def_var_fletcher32. These defines are used there. */ /**@{*/ #define NC_NOCHECKSUM 0 @@ -322,14 +315,10 @@ there. */ */ #define NC_ISSYSERR(err) ((err) > 0) -#define NC_NOERR 0 /**< No Error */ +#define NC_NOERR 0 /**< No Error. */ #define NC2_ERR (-1) /**< Returned for all errors in the v2 API. */ -/** Not a netcdf id. - -The specified netCDF ID does not refer to an -open netCDF dataset. */ -#define NC_EBADID (-33) +#define NC_EBADID (-33) /**< Not a netcdf id. */ #define NC_ENFILE (-34) /**< Too many netcdfs open */ #define NC_EEXIST (-35) /**< netcdf file exists && NC_NOCLOBBER */ #define NC_EINVAL (-36) /**< Invalid Argument */ @@ -358,9 +347,8 @@ larger than the corresponding dimension length will cause an error. */ /** NC_MAX_DIMS exceeded. Max number of dimensions exceeded in a classic or 64-bit offset file, or an netCDF-4 file with -::NC_CLASSIC_MODEL on. */ -#define NC_EMAXDIMS (-41) /* not enforced after 4.5.0 */ - +::NC_CLASSIC_MODEL on. (Not enforced after 4.5.0.) */ +#define NC_EMAXDIMS (-41) #define NC_ENAMEINUSE (-42) /**< String match to name in use */ #define NC_ENOTATT (-43) /**< Attribute not found */ #define NC_EMAXATTS (-44) /**< NC_MAX_ATTRS exceeded - not enforced after 4.5.0 */ @@ -370,13 +358,9 @@ ::NC_CLASSIC_MODEL on. */ /** NC_MAX_VARS exceeded. Max number of variables exceeded in a classic or 64-bit offset file, or an netCDF-4 file with -::NC_CLASSIC_MODEL on. */ -#define NC_EMAXVARS (-48) /* not enforced after 4.5.0 */ - -/** Variable not found. - -The variable ID is invalid for the specified netCDF dataset. */ -#define NC_ENOTVAR (-49) +::NC_CLASSIC_MODEL on. (Not enforced after 4.5.0.) */ +#define NC_EMAXVARS (-48) +#define NC_ENOTVAR (-49) /**< Variable not found. */ #define NC_EGLOBAL (-50) /**< Action prohibited on NC_GLOBAL varid */ #define NC_ENOTNC (-51) /**< Not a netcdf file */ #define NC_ESTS (-52) /**< In Fortran, string too short */ diff --git a/include/netcdf_dispatch.h b/include/netcdf_dispatch.h index 532748a911..36ef8908f9 100644 --- a/include/netcdf_dispatch.h +++ b/include/netcdf_dispatch.h @@ -135,80 +135,85 @@ struct NC_Dispatch /* Read-only dispatch layers can use these functions to return * NC_EPERM to all attempts to modify a file. */ - -EXTERNL int NC_RO_create(const char *path, int cmode, size_t initialsz, int basepe, - size_t *chunksizehintp, void* parameters, - const NC_Dispatch*, int); -EXTERNL int NC_RO_redef(int ncid); -EXTERNL int NC_RO__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, - size_t r_align); -EXTERNL int NC_RO_sync(int ncid); -EXTERNL int NC_RO_def_var_fill(int, int, int, const void *); -EXTERNL int NC_RO_rename_att(int ncid, int varid, const char *name, - const char *newname); -EXTERNL int NC_RO_del_att(int ncid, int varid, const char*); -EXTERNL int NC_RO_put_att(int ncid, int varid, const char *name, nc_type datatype, - size_t len, const void *value, nc_type); -EXTERNL int NC_RO_def_var(int ncid, const char *name, - nc_type xtype, int ndims, const int *dimidsp, int *varidp); -EXTERNL int NC_RO_rename_var(int ncid, int varid, const char *name); -EXTERNL int NC_RO_put_vara(int ncid, int varid, - const size_t *start, const size_t *count, - const void *value, nc_type); -EXTERNL int NC_RO_def_dim(int ncid, const char *name, size_t len, int *idp); -EXTERNL int NC_RO_rename_dim(int ncid, int dimid, const char *name); -EXTERNL int NC_RO_set_fill(int ncid, int fillmode, int *old_modep); +#if defined(__cplusplus) +extern "C" { +#endif + EXTERNL int NC_RO_create(const char *path, int cmode, size_t initialsz, int basepe, + size_t *chunksizehintp, void* parameters, + const NC_Dispatch*, int); + EXTERNL int NC_RO_redef(int ncid); + EXTERNL int NC_RO__enddef(int ncid, size_t h_minfree, size_t v_align, size_t v_minfree, + size_t r_align); + EXTERNL int NC_RO_sync(int ncid); + EXTERNL int NC_RO_def_var_fill(int, int, int, const void *); + EXTERNL int NC_RO_rename_att(int ncid, int varid, const char *name, + const char *newname); + EXTERNL int NC_RO_del_att(int ncid, int varid, const char*); + EXTERNL int NC_RO_put_att(int ncid, int varid, const char *name, nc_type datatype, + size_t len, const void *value, nc_type); + EXTERNL int NC_RO_def_var(int ncid, const char *name, + nc_type xtype, int ndims, const int *dimidsp, int *varidp); + EXTERNL int NC_RO_rename_var(int ncid, int varid, const char *name); + EXTERNL int NC_RO_put_vara(int ncid, int varid, + const size_t *start, const size_t *count, + const void *value, nc_type); + EXTERNL int NC_RO_def_dim(int ncid, const char *name, size_t len, int *idp); + EXTERNL int NC_RO_rename_dim(int ncid, int dimid, const char *name); + EXTERNL int NC_RO_set_fill(int ncid, int fillmode, int *old_modep); /* These functions are for dispatch layers that don't implement these * legacy functions. They return NC_ENOTNC3. */ -EXTERNL int NC_NOTNC3_put_varm(int ncid, int varid, const size_t * start, - const size_t *edges, const ptrdiff_t *stride, - const ptrdiff_t *imapp, const void *value0, - nc_type memtype); -EXTERNL int NC_NOTNC3_get_varm(int ncid, int varid, const size_t *start, - const size_t *edges, const ptrdiff_t *stride, - const ptrdiff_t *imapp, void *value0, nc_type memtype); + EXTERNL int NC_NOTNC3_put_varm(int ncid, int varid, const size_t * start, + const size_t *edges, const ptrdiff_t *stride, + const ptrdiff_t *imapp, const void *value0, + nc_type memtype); + EXTERNL int NC_NOTNC3_get_varm(int ncid, int varid, const size_t *start, + const size_t *edges, const ptrdiff_t *stride, + const ptrdiff_t *imapp, void *value0, nc_type memtype); /* These functions are for dispatch layers that don't implement the * enhanced model. They return NC_ENOTNC4. */ -EXTERNL int NC_NOTNC4_def_var_filter(int, int, unsigned int, size_t, - const unsigned int*); -EXTERNL int NC_NOTNC4_def_grp(int, const char *, int *); -EXTERNL int NC_NOTNC4_rename_grp(int, const char *); -EXTERNL int NC_NOTNC4_def_compound(int, size_t, const char *, nc_type *); -EXTERNL int NC_NOTNC4_insert_compound(int, nc_type, const char *, size_t, nc_type); -EXTERNL int NC_NOTNC4_insert_array_compound(int, nc_type, const char *, size_t, - nc_type, int, const int *); -EXTERNL int NC_NOTNC4_inq_typeid(int, const char *, nc_type *); -EXTERNL int NC_NOTNC4_inq_compound_field(int, nc_type, int, char *, size_t *, - nc_type *, int *, int *); -EXTERNL int NC_NOTNC4_inq_compound_fieldindex(int, nc_type, const char *, int *); -EXTERNL int NC_NOTNC4_def_vlen(int, const char *, nc_type base_typeid, nc_type *); -EXTERNL int NC_NOTNC4_put_vlen_element(int, int, void *, size_t, const void *); -EXTERNL int NC_NOTNC4_get_vlen_element(int, int, const void *, size_t *, void *); -EXTERNL int NC_NOTNC4_def_enum(int, nc_type, const char *, nc_type *); -EXTERNL int NC_NOTNC4_insert_enum(int, nc_type, const char *, const void *); -EXTERNL int NC_NOTNC4_inq_enum_member(int, nc_type, int, char *, void *); -EXTERNL int NC_NOTNC4_inq_enum_ident(int, nc_type, long long, char *); -EXTERNL int NC_NOTNC4_def_opaque(int, size_t, const char *, nc_type *); -EXTERNL int NC_NOTNC4_def_var_deflate(int, int, int, int, int); -EXTERNL int NC_NOTNC4_def_var_fletcher32(int, int, int); -EXTERNL int NC_NOTNC4_def_var_chunking(int, int, int, const size_t *); -EXTERNL int NC_NOTNC4_def_var_endian(int, int, int); -EXTERNL int NC_NOTNC4_set_var_chunk_cache(int, int, size_t, size_t, float); -EXTERNL int NC_NOTNC4_get_var_chunk_cache(int, int, size_t *, size_t *, float *); -EXTERNL int NC_NOTNC4_var_par_access(int, int, int); -EXTERNL int NC_NOTNC4_inq_ncid(int, const char *, int *); -EXTERNL int NC_NOTNC4_inq_grps(int, int *, int *); -EXTERNL int NC_NOTNC4_inq_grpname(int, char *); -EXTERNL int NC_NOTNC4_inq_grpname_full(int, size_t *, char *); -EXTERNL int NC_NOTNC4_inq_grp_parent(int, int *); -EXTERNL int NC_NOTNC4_inq_grp_full_ncid(int, const char *, int *); -EXTERNL int NC_NOTNC4_inq_varids(int, int *, int *); -EXTERNL int NC_NOTNC4_inq_dimids(int, int *, int *, int); -EXTERNL int NC_NOTNC4_inq_typeids(int, int *, int *); -EXTERNL int NC_NOTNC4_inq_user_type(int, nc_type, char *, size_t *, - nc_type *, size_t *, int *); -EXTERNL int NC_NOTNC4_inq_typeid(int, const char *, nc_type *); + EXTERNL int NC_NOTNC4_def_var_filter(int, int, unsigned int, size_t, + const unsigned int*); + EXTERNL int NC_NOTNC4_def_grp(int, const char *, int *); + EXTERNL int NC_NOTNC4_rename_grp(int, const char *); + EXTERNL int NC_NOTNC4_def_compound(int, size_t, const char *, nc_type *); + EXTERNL int NC_NOTNC4_insert_compound(int, nc_type, const char *, size_t, nc_type); + EXTERNL int NC_NOTNC4_insert_array_compound(int, nc_type, const char *, size_t, + nc_type, int, const int *); + EXTERNL int NC_NOTNC4_inq_typeid(int, const char *, nc_type *); + EXTERNL int NC_NOTNC4_inq_compound_field(int, nc_type, int, char *, size_t *, + nc_type *, int *, int *); + EXTERNL int NC_NOTNC4_inq_compound_fieldindex(int, nc_type, const char *, int *); + EXTERNL int NC_NOTNC4_def_vlen(int, const char *, nc_type base_typeid, nc_type *); + EXTERNL int NC_NOTNC4_put_vlen_element(int, int, void *, size_t, const void *); + EXTERNL int NC_NOTNC4_get_vlen_element(int, int, const void *, size_t *, void *); + EXTERNL int NC_NOTNC4_def_enum(int, nc_type, const char *, nc_type *); + EXTERNL int NC_NOTNC4_insert_enum(int, nc_type, const char *, const void *); + EXTERNL int NC_NOTNC4_inq_enum_member(int, nc_type, int, char *, void *); + EXTERNL int NC_NOTNC4_inq_enum_ident(int, nc_type, long long, char *); + EXTERNL int NC_NOTNC4_def_opaque(int, size_t, const char *, nc_type *); + EXTERNL int NC_NOTNC4_def_var_deflate(int, int, int, int, int); + EXTERNL int NC_NOTNC4_def_var_fletcher32(int, int, int); + EXTERNL int NC_NOTNC4_def_var_chunking(int, int, int, const size_t *); + EXTERNL int NC_NOTNC4_def_var_endian(int, int, int); + EXTERNL int NC_NOTNC4_set_var_chunk_cache(int, int, size_t, size_t, float); + EXTERNL int NC_NOTNC4_get_var_chunk_cache(int, int, size_t *, size_t *, float *); + EXTERNL int NC_NOTNC4_var_par_access(int, int, int); + EXTERNL int NC_NOTNC4_inq_ncid(int, const char *, int *); + EXTERNL int NC_NOTNC4_inq_grps(int, int *, int *); + EXTERNL int NC_NOTNC4_inq_grpname(int, char *); + EXTERNL int NC_NOTNC4_inq_grpname_full(int, size_t *, char *); + EXTERNL int NC_NOTNC4_inq_grp_parent(int, int *); + EXTERNL int NC_NOTNC4_inq_grp_full_ncid(int, const char *, int *); + EXTERNL int NC_NOTNC4_inq_varids(int, int *, int *); + EXTERNL int NC_NOTNC4_inq_dimids(int, int *, int *, int); + EXTERNL int NC_NOTNC4_inq_typeids(int, int *, int *); + EXTERNL int NC_NOTNC4_inq_user_type(int, nc_type, char *, size_t *, + nc_type *, size_t *, int *); + EXTERNL int NC_NOTNC4_inq_typeid(int, const char *, nc_type *); +#if defined(__cplusplus) +} +#endif #endif /* NETCDF_DISPATCH_H */ diff --git a/libdispatch/nclistmgr.c b/libdispatch/nclistmgr.c index e05b7a3a45..5506faca95 100644 --- a/libdispatch/nclistmgr.c +++ b/libdispatch/nclistmgr.c @@ -100,6 +100,35 @@ add_to_NCList(NC* ncp) return NC_NOERR; } +/** + * Move an NC in the nc_filelist. This is required by PIO. + * + * @param ncp Pointer to already-allocated and initialized NC struct. + * @param new_id New index in the nc_filelist for this file. + * + * @return ::NC_NOERR No error. + * @return ::NC_EINVAL Invalid input. + * @author Ed Hartnett + */ +int +move_in_NCList(NC *ncp, int new_id) +{ + /* If no files in list, error. */ + if (!nc_filelist) + return NC_EINVAL; + + /* If new slot is already taken, error. */ + if (nc_filelist[new_id]) + return NC_EINVAL; + + /* Move the file. */ + nc_filelist[ncp->ext_ncid >> ID_SHIFT] = NULL; + nc_filelist[new_id] = ncp; + ncp->ext_ncid = (new_id << ID_SHIFT); + + return NC_NOERR; +} + /** * Delete an NC struct from the list. This happens when the file is * closed. Relies on all memory in the NC being deallocated after this diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index ad4d3a70f7..8977e59f5e 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -125,30 +125,40 @@ nc4_file_list_add(int ncid, const char *path, int mode, void **dispatchdata) return NC_NOERR; } -/* /\** */ -/* * @internal Change the ncid of an open file. This is needed for PIO */ -/* * integration. */ -/* * */ -/* * @param ncid The ncid of the file (aka ext_ncid). */ -/* * @param new_ncid The new ncid to use. */ -/* * */ -/* * @return ::NC_NOERR No error. */ -/* * @return ::NC_EBADID No NC struct with this ext_ncid. */ -/* * @return ::NC_ENOMEM Out of memory. */ -/* * @author Ed Hartnett */ -/* *\/ */ -/* int */ -/* nc4_file_change_ncid(int ncid, int new_ncid) */ -/* { */ -/* NC *nc; */ -/* int ret; */ - -/* /\* Find NC pointer for this file. *\/ */ -/* if ((ret = NC_check_id(ncid, &nc))) */ -/* return ret; */ - -/* return NC_NOERR; */ -/* } */ +/** + * @internal Change the ncid of an open file. This is needed for PIO + * integration. + * + * @param ncid The ncid of the file (aka ext_ncid). + * @param new_ncid The new ncid index to use (i.e. the first two bytes + * of the ncid). + * + * @return ::NC_NOERR No error. + * @return ::NC_EBADID No NC struct with this ext_ncid. + * @return ::NC_ENOMEM Out of memory. + * @author Ed Hartnett + */ +int +nc4_file_change_ncid(int ncid, unsigned short new_ncid_index) +{ + NC *nc; + int new_ext_ncid; + int ret; + + /* Shift the new index into the first two bytes. */ + new_ext_ncid = new_ncid_index << ID_SHIFT; + + /* Find NC pointer for this file. */ + if ((ret = NC_check_id(ncid, &nc))) + return ret; + + /* Is new list spot already occupied? */ + if (move_in_NCList(nc, new_ncid_index)) + return NC_EIO; + + + return NC_NOERR; +} /** * @internal Get info about a file on the list of libsrc4 open diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index 323a47989f..c22c6e3dda 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -265,36 +265,34 @@ main(int argc, char **argv) free_NC(ncp); } SUMMARIZE_ERR; - /* printf("Testing changing ncid..."); */ - /* { */ - /* NC *ncp, *ncp2; */ - /* int mode = 0; */ - /* NCmodel model; */ - /* int ret; */ - - /* /\* Create the NC* instance and insert its dispatcher and model. *\/ */ - /* if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR; */ - - /* /\* Add to list of known open files and define ext_ncid. *\/ */ - /* add_to_NCList(ncp); */ + printf("Testing changing ncid..."); + { + NC *ncp; + NCmodel model; + NC_GRP_INFO_T *grp; + NC_FILE_INFO_T *h5; + int new_ncid; - /* /\* Find it in the list. *\/ */ - /* if (!(ncp2 = find_in_NCList(ncp->ext_ncid))) ERR; */ - /* if (!(ncp2 = find_in_NCList_by_name(FILE_NAME))) ERR; */ - /* if ((ret = iterate_NCList(1, &ncp2))) ERR; */ - /* if (count_NCList() != 1) ERR; */ + /* Create the NC, add it to nc_filelist array, add and init + * NC_FILE_INFO_T. */ + if (new_NC(NC3_dispatch_table, FILE_NAME, 0, &model, &ncp)) ERR; + add_to_NCList(ncp); + if (nc4_file_list_add(ncp->ext_ncid, FILE_NAME, 0, NULL)) ERR; + if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, &h5)) ERR; - /* /\* Change the ncid. *\/ */ - /* if (nc4_file_change_ncid(ncp->ext_ncid, TEST_VAL_42)) ERR; */ + /* Change the ncid. */ + new_ncid = TEST_VAL_42 << ID_SHIFT; + if (nc4_file_change_ncid(ncp->ext_ncid, new_ncid)) ERR; - /* /\* Delete it. *\/ */ - /* del_from_NCList(ncp); /\* Will free empty list. *\/ */ - /* free_NC(ncp); */ + /* Delete it. */ + if (nc4_file_list_del(ncp->ext_ncid)) ERR; + del_from_NCList(ncp); /* Will free empty list. */ + free_NC(ncp); - /* /\* Ensure it is no longer in list. *\/ */ - /* /\* if (find_in_NCList(ncp->ext_ncid)) ERR; *\/ */ + /* Ensure it is no longer in list. */ + /* if (find_in_NCList(ncp->ext_ncid)) ERR; */ - /* } */ - /* SUMMARIZE_ERR; */ + } + SUMMARIZE_ERR; FINAL_RESULTS; } From 57ff363b22463425079ddb59d8e871f6a18fb1c9 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Thu, 22 Aug 2019 12:03:01 -0600 Subject: [PATCH 2/3] now able to move an ncid --- unit_test/tst_nc4internal.c | 9 ++++++--- unit_test/tst_nclist.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/unit_test/tst_nc4internal.c b/unit_test/tst_nc4internal.c index c22c6e3dda..4fbca4849e 100644 --- a/unit_test/tst_nc4internal.c +++ b/unit_test/tst_nc4internal.c @@ -271,7 +271,7 @@ main(int argc, char **argv) NCmodel model; NC_GRP_INFO_T *grp; NC_FILE_INFO_T *h5; - int new_ncid; + int old_ncid; /* Create the NC, add it to nc_filelist array, add and init * NC_FILE_INFO_T. */ @@ -281,8 +281,11 @@ main(int argc, char **argv) if (nc4_find_nc_grp_h5(ncp->ext_ncid, NULL, &grp, &h5)) ERR; /* Change the ncid. */ - new_ncid = TEST_VAL_42 << ID_SHIFT; - if (nc4_file_change_ncid(ncp->ext_ncid, new_ncid)) ERR; + old_ncid = ncp->ext_ncid; + if (nc4_file_change_ncid(ncp->ext_ncid, TEST_VAL_42)) ERR; + + /* Can't find old ncid. */ + if (nc4_find_nc_grp_h5(old_ncid, NULL, NULL, NULL) != NC_EBADID) ERR; /* Delete it. */ if (nc4_file_list_del(ncp->ext_ncid)) ERR; diff --git a/unit_test/tst_nclist.c b/unit_test/tst_nclist.c index 0daae16a9c..cdb56a9c5a 100644 --- a/unit_test/tst_nclist.c +++ b/unit_test/tst_nclist.c @@ -77,6 +77,37 @@ main(int argc, char **argv) if (find_in_NCList(ncid)) ERR; } SUMMARIZE_ERR; + printf("Testing moving in NC list (needed for PIO)..."); + { + int ncid; + NC *ncp, *ncp2; + int mode = 0; + NCmodel model; + int ret; + + /* Create the NC* instance and add it to list. */ + if ((ret = new_NC(NULL, FILE_NAME, mode, &model, &ncp))) ERR; + add_to_NCList(ncp); + + /* Find it in the list. */ + if (!(ncp2 = find_in_NCList(ncp->ext_ncid))) ERR; + + /* Move it. */ + ncid = ncp->ext_ncid; + if (move_in_NCList(ncp, TEST_VAL_42)) ERR; + + /* Now we won't find old ncid in the list. */ + if (find_in_NCList(ncid)) ERR; + + /* Delete it. */ + ncid = ncp->ext_ncid; + del_from_NCList(ncp); /* Will free empty list. */ + free_NC(ncp); + + /* Ensure it is no longer in list. */ + if (find_in_NCList(ncid)) ERR; + } + SUMMARIZE_ERR; #ifdef LARGE_FILE_TESTS /* This test is slow, only run it on large file test builds. */ printf("Testing maxing out NC list..."); From bec465963253309b236948345a84b114c4ada459 Mon Sep 17 00:00:00 2001 From: edwardhartnett Date: Fri, 30 Aug 2019 08:45:07 -0600 Subject: [PATCH 3/3] changes --- libsrc4/nc4internal.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libsrc4/nc4internal.c b/libsrc4/nc4internal.c index 8977e59f5e..f396ef0610 100644 --- a/libsrc4/nc4internal.c +++ b/libsrc4/nc4internal.c @@ -142,20 +142,22 @@ int nc4_file_change_ncid(int ncid, unsigned short new_ncid_index) { NC *nc; - int new_ext_ncid; int ret; - /* Shift the new index into the first two bytes. */ - new_ext_ncid = new_ncid_index << ID_SHIFT; + LOG((2, "%s: ncid %d new_ncid_index %d", __func__, ncid, new_ncid_index)); /* Find NC pointer for this file. */ if ((ret = NC_check_id(ncid, &nc))) return ret; - /* Is new list spot already occupied? */ + /* Move it in the list. It will faile if list spot is already + * occupied. */ + LOG((3, "moving nc->ext_ncid %d nc->ext_ncid >> ID_SHIFT %d", + nc->ext_ncid, nc->ext_ncid >> ID_SHIFT)); if (move_in_NCList(nc, new_ncid_index)) return NC_EIO; - + LOG((3, "moved to new_ncid_index %d new nc->ext_ncid %d", new_ncid_index, + nc->ext_ncid)); return NC_NOERR; }