netcdf-c/libnczarr/zopen.c
Dennis Heimbigner 93e9d92778 More NCZarr optimizations
* Replace wholevar with more useful wholechunk optimization
* Add optimization to read multiple values at one time
* Replace NCDEFAULT_get/put_vars with native nczarr versions.
* Clarify chunk projection computations
* zdebdispatch.h
* Add more chunking test cases and re-enable run_chunkcases
* If !szip, then suppress deflate interference test
* Make H5Znoop(1) filter produce more information
* cleanup bzlib.c API
2021-01-06 13:35:59 -07:00

191 lines
5.5 KiB
C

/* Copyright 2003-2018, University Corporation for Atmospheric
* Research. See COPYRIGHT file for copying and redistribution
* conditions. */
/**
* @file
* @internal This file contains functions that are used in file
* opens.
*
* @author Dennis Heimbigner, Ed Hartnett
*/
#include "zincludes.h"
#include "ncmodel.h"
#define NUM_TYPES 12 /**< Number of netCDF atomic types. */
#define CD_NELEMS_ZLIB 1 /**< Number of parameters needed for filter. */
/** @internal These flags may not be set for open mode. */
static const int ILLEGAL_OPEN_FLAGS = (NC_MMAP|NC_DISKLESS|NC_64BIT_OFFSET|NC_CDF5);
/* Forward */
/**
* @internal Check for the attribute that indicates that netcdf
* classic model is in use.
*
* @param root_grp pointer to the group info for the root group of the
* @param is_classic store 1 if this is a classic file.
* file.
*
* @return NC_NOERR No error.
* @author Dennis Heimbigner, Ed Hartnett
*/
static int
check_for_classic_model(NC_GRP_INFO_T *root_grp, int *is_classic)
{
int attr_exists = 0;
/* Check inputs. */
assert(root_grp && root_grp->format_grp_info && !root_grp->parent
&& is_classic);
*is_classic = attr_exists ? 1 : 0;
return NC_NOERR;
}
/**
* @internal Open a netcdf-4 file. Things have already been kicked off
* in ncfunc.c in nc_open, but here the netCDF-4 part of opening a
* file is handled.
*
* @param path The file name of the new file.
* @param mode The open mode flag.
* @param fraglist uri fragment list in envv form
* @param nc Pointer to NC file info.
*
* @return ::NC_NOERR No error.
* @return ::NC_ENOMEM Out of memory.
* @return ::NC_EINTERNAL Internal list error.
* @return ::NC_EHDFERR HDF error.
* @return ::NC_EMPI MPI error for parallel.
* @return ::NC_EPARINIT Parallel I/O initialization error.
* @return ::NC_EINMEMMORY Memory file error.
* @author Dennis Heimbigner, Ed Hartnett
*/
static int
ncz_open_file(const char *path, int mode, const char** controls, int ncid)
{
int stat = NC_NOERR;
NC_FILE_INFO_T *h5 = NULL;
int is_classic;
NC* nc = NULL;
LOG((3, "%s: path %s mode %d", __func__, path, mode));
assert(path);
ZTRACE(2,"path=%s,mode=%d,ncid=%d,controls=%s)",path,mode,ncid,(controls?nczprint_envv(controls):"null"));
/* Convert ncid to an NC* structure pointer */
if((stat = NC_check_id(ncid,&nc))) goto exit;
/* Add necessary structs to hold netcdf-4 file data;
will define the NC_FILE_INFO_T for the file
and the NC_GRP_INFO_T for the root group. */
if ((stat = nc4_nc4f_list_add(nc, path, mode)))
goto exit;
h5 = (NC_FILE_INFO_T*)nc->dispatchdata;
assert(h5 && h5->root_grp);
h5->mem.inmemory = ((mode & NC_INMEMORY) == NC_INMEMORY);
h5->mem.diskless = ((mode & NC_DISKLESS) == NC_DISKLESS);
h5->mem.persist = ((mode & NC_PERSIST) == NC_PERSIST);
/* Does the mode specify that this file is read-only? */
if ((mode & NC_WRITE) == 0)
h5->no_write = NC_TRUE;
/* Setup zarr state */
if((stat = ncz_open_dataset(h5,controls)))
goto exit;
/* Now read in all the metadata. Some types
* information may be difficult to resolve here, if, for example, a
* dataset of user-defined type is encountered before the
* definition of that type. */
if((stat = ncz_read_file(h5)))
goto exit;
/* We must read in the attributes of the root group to get
e.g. provenance and classic model attribute */
if((stat = ncz_read_atts(h5,(NC_OBJ*)h5->root_grp))) goto exit;
/* Check for classic model attribute. */
if ((stat = check_for_classic_model(h5->root_grp, &is_classic)))
goto exit;
if (is_classic)
h5->cmode |= NC_CLASSIC_MODEL;
#ifdef LOGGING
/* This will print out the names, types, lens, etc of the vars and
atts in the file, if the logging level is 2 or greater. */
log_metadata_nc(h5);
#endif
exit:
if (stat && h5)
ncz_close_file(h5, 1); /* treat like abort*/
return ZUNTRACE(stat);
}
/**
* @internal Open a netCDF-4 file.
*
* @param path The file name of the new file.
* @param mode The open mode flag.
* @param basepe Ignored by this function.
* @param chunksizehintp Ignored by this function.
* @param parameters pointer to struct holding extra data (e.g. for parallel I/O)
* layer. Ignored if NULL.
* @param dispatch Pointer to the dispatch table for this file.
* @param nc_file Pointer to an instance of NC.
*
* @return ::NC_NOERR No error.
* @return ::NC_EINVAL Invalid inputs.
* @author Dennis Heimbigner, Ed Hartnett
*/
int
NCZ_open(const char *path, int mode, int basepe, size_t *chunksizehintp,
void *parameters, const NC_Dispatch *dispatch, int ncid)
{
int stat = NC_NOERR;
NCURI* uri = NULL;
ZTRACE(0,"path=%s,mode=%d,ncid=%d)",path,mode,ncid);
NC_UNUSED(parameters);
assert(path && dispatch);
LOG((1, "%s: path %s mode %d ",
__func__, path, mode));
/* Check the mode for validity */
if (mode & ILLEGAL_OPEN_FLAGS)
{stat = NC_EINVAL; goto done;}
if((mode & NC_DISKLESS) && (mode & NC_INMEMORY))
{stat = NC_EINVAL; goto done;}
/* If this is our first file, initialize NCZ. */
if (!ncz_initialized) NCZ_initialize();
#ifdef LOGGING
/* If nc logging level has changed, see if we need to turn on
* NCZ's error messages. */
NCZ_set_log_level();
#endif /* LOGGING */
/* Get the controls */
if(ncuriparse(path,&uri)) goto done;
/* Open the file. */
if((stat = ncz_open_file(path, mode, ncurifragmentparams(uri), ncid)))
goto done;
done:
ncurifree(uri);
return ZUNTRACE(stat);
}