summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJacob Smith <jake.smith@hdfgroup.org>2018-09-11 21:37:14 (GMT)
committerJacob Smith <jake.smith@hdfgroup.org>2018-09-11 21:37:14 (GMT)
commit602dd3ac15c9f5cd47fc78985266ce66a68a8789 (patch)
tree149023d5992abebe5a5a36e45e8132ab478a8c63 /src
parent5647dea421be9dc8429f08632aa72a8a22904292 (diff)
downloadhdf5-602dd3ac15c9f5cd47fc78985266ce66a68a8789.zip
hdf5-602dd3ac15c9f5cd47fc78985266ce66a68a8789.tar.gz
hdf5-602dd3ac15c9f5cd47fc78985266ce66a68a8789.tar.bz2
Stash work on object header reduction code and tests.
CMake stuff is not verified.
Diffstat (limited to 'src')
-rw-r--r--src/H5Dint.c306
-rw-r--r--src/H5Dprivate.h1
-rw-r--r--src/H5F.c94
-rw-r--r--src/H5Fint.c3
-rw-r--r--src/H5Fpkg.h1
-rw-r--r--src/H5Fpublic.h2
-rw-r--r--src/H5Oint.c382
-rw-r--r--src/H5Oprivate.h12
-rw-r--r--src/H5Pdcpl.c126
-rw-r--r--src/H5Ppublic.h2
10 files changed, 835 insertions, 94 deletions
diff --git a/src/H5Dint.c b/src/H5Dint.c
index e8874a2..6d095aa 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -61,7 +61,9 @@ static herr_t H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overw
static herr_t H5D__get_storage_size_real(const H5D_t *dset, hsize_t *storage_size);
static herr_t H5D__append_flush_setup(H5D_t *dset, hid_t dapl_id);
static herr_t H5D__close_cb(H5D_t *dataset);
-
+static herr_t H5D__use_minimized_dset_headers(H5F_t *file, H5D_t *dset, hbool_t *minimize);
+static herr_t H5D__prepare_minimized_oh(H5F_t *file, H5D_t *dset, H5O_loc_t *oloc);
+static size_t H5D__calculate_minimum_header_size(H5F_t *file, H5D_t *dset, H5O_t *ohdr);
/*********************/
/* Package Variables */
/*********************/
@@ -662,6 +664,272 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D__use_minimized_dset_headers
+ *
+ * Purpose: Compartmentalize check for file- or dcpl-set values indicating
+ * to create a "minimized" dataset object header.
+ * Upon success, write resulting value to out pointer `minimize`.
+ *
+ * Return: Success: SUCCEED (0) (non-negative value)
+ * Failure: FAIL (-1) (negative value)
+ *
+ * Programmer: Jacob Smith
+ * 16 August 2018
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__use_minimized_dset_headers( \
+ H5F_t *file, \
+ H5D_t *dset, \
+ hbool_t *minimize)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT;
+
+ HDassert(file);
+ HDassert(dset);
+ HDassert(minimize);
+
+ if (FAIL == H5Pget_dset_no_attrs_hint(dset->shared->dcpl_id, minimize))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL,
+ "can't get minimize value from dcpl")
+
+#if 1 /* TODO: problem getting file id? */
+ /* error kicks in when tring to create dset through external link */
+ if (FALSE == *minimize) {
+#if 1 /* API or direct */
+ /* problems getting/verifying object id */
+ hid_t file_id = -1;
+ file_id = H5F_get_file_id((const H5F_t *)file);
+ if (0 > file_id)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL,
+ "can't get file id")
+
+#if 1 /* which file-id verification */
+ if (NULL == H5I_object(file_id))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL,
+ "file id seems to be invalid")
+#else
+ if (NULL == H5I_object_verify(file_id, H5I_FILE))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL,
+ "file id seems to be invalid")
+#endif /* which file-id verification */
+
+ if (FAIL == H5Fget_dset_no_attrs_hint(file_id, minimize))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, FAIL,
+ "can't get minimize value from file")
+#else
+ /* direct access -- "incomplete type" */
+ HDassert(file->shared);
+ minimize = file->shared->crt_dset_min_ohdr_flag;
+#endif /* API or direct */
+ } /* if to look in file for flag */
+#endif /* TODO */
+
+done:
+ if (FAIL == ret_value)
+ *minimize = FALSE;
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5D__use_minimized_dset_headers */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__calculate_minimium_header_size
+ *
+ * Purpose: Calculate the size required for the minimized object header.
+ *
+ * Return: Success: SUCCEED (0) (non-negative value)
+ * Failure: FAIL (-1) (negative value)
+ *
+ * Programmer: Jacob Smith
+ * 16 August 2018
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5D__calculate_minimum_header_size( \
+ H5F_t *file, \
+ H5D_t *dset, \
+ H5O_t *ohdr)
+{
+ H5T_t *type = NULL;
+ H5O_fill_t *fill_prop = NULL;
+ hbool_t use_at_least_v18 = FALSE;
+ size_t ret_value = 0;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOERR;
+
+ HDassert(file);
+ HDassert(dset);
+ HDassert(ohdr);
+
+ type = dset->shared->type;
+ fill_prop = &(dset->shared->dcpl_cache.fill);
+ use_at_least_v18 = (H5F_LOW_BOUND(file) >= H5F_LIBVER_V18);
+
+ /* Datatype message size */
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_DTYPE_ID,
+ type,
+ 0);
+
+ /* Shared Dataspace message size */
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_SDSPACE_ID,
+ dset->shared->space,
+ 0);
+
+ /* "Layout" message size */
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_LAYOUT_ID,
+ &dset->shared->layout,
+ 0);
+
+ /* Fill Value message size */
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_FILL_NEW_ID,
+ fill_prop,
+ 0);
+
+#if 1 /* DEBUG H5Omessage */
+ /* "Continuation" message size */
+#if 0
+ ret_value += H5O_msg_raw_size(
+ file,
+ H5O_CONT_ID,
+ FALSE,
+ NULL);
+#else
+ {
+ char tmp[1] = "\0";
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_CONT_ID,
+ tmp, /* NULL, */ /* UNUSED? */ /*intercepted by assert before passed through */
+ 0);
+ }
+#endif
+#endif /* DEBUG H5Omessage */
+
+ /* Fill Value (backwards compatability) message size */
+ if (fill_prop->buf && !use_at_least_v18) {
+ H5O_fill_t old_fill_prop; /* Copy for writing "old" fill value */
+
+ /* Shallow copy the fill value property */
+ /* guards against shared component modification */
+ HDmemcpy(&old_fill_prop, fill_prop, sizeof(old_fill_prop));
+
+ H5O_msg_reset_share(H5O_FILL_ID, &old_fill_prop);
+
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_FILL_ID,
+ &old_fill_prop,
+ 0);
+ }
+
+ /* Filter/Pipeline message size */
+ if (H5D_CHUNKED == dset->shared->layout.type) {
+ H5O_pline_t *pline = &dset->shared->dcpl_cache.pline;
+ if (pline->nused > 0) {
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_PLINE_ID,
+ pline,
+ 0);
+ }
+ }
+
+ /* External File Link message size */
+ if (dset->shared->dcpl_cache.efl.nused > 0) {
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_EFL_ID,
+ &dset->shared->dcpl_cache.efl,
+ 0);
+ }
+
+ /* Modification Time message size */
+ if ((H5O_OH_GET_VERSION(ohdr) > 1) && /* TODO: H5O_VERSION_1 in H5Opkg.h */
+ (H5O_HDR_STORE_TIMES & H5O_OH_GET_FLAGS(ohdr)))
+ {
+ time_t mtime = H5O_OH_GET_MTIME(ohdr);
+ ret_value += H5O_msg_size_oh(
+ file,
+ ohdr,
+ H5O_MTIME_NEW_ID,
+ &mtime,
+ 0);
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5D__calculate_minimum_header_size */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D__prepare_minimized_oh
+ *
+ * Purpose: Create an object header (H5O_t) allocated with the smallest
+ * possible size.
+ *
+ * Return: Success: SUCCEED (0) (non-negative value)
+ * Failure: FAIL (-1) (negative value)
+ *
+ * Programmer: Jacob Smith
+ * 16 August 2018
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__prepare_minimized_oh( \
+ H5F_t *file, \
+ H5D_t *dset, \
+ H5O_loc_t *oloc)
+{
+ H5O_t *oh = NULL;
+ size_t ohdr_size = 0;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT;
+
+ HDassert(file);
+ HDassert(dset);
+ HDassert(oloc);
+
+ oh = H5O__create_ohdr(file, dset->shared->dcpl_id);
+ if (NULL == oh)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL,
+ "can't instantiate object header")
+
+ ohdr_size = H5D__calculate_minimum_header_size(file, dset, oh);
+
+ if (FAIL == H5O__apply_ohdr(
+ file,
+ oh,
+ dset->shared->dcpl_id,
+ ohdr_size,
+ (size_t)1,
+ oloc))
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL,
+ "can't apply object header to file")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5D_prepare_minimized_oh */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D__update_oh_info
*
* Purpose: Create and fill object header for dataset
@@ -683,6 +951,7 @@ H5D__update_oh_info(H5F_t *file, H5D_t *dset, hid_t dapl_id)
hbool_t fill_changed = FALSE; /* Flag indicating the fill value was changed */
hbool_t layout_init = FALSE; /* Flag to indicate that chunk information was initialized */
hbool_t use_at_least_v18; /* Flag indicating to use at least v18 format versions */
+ hbool_t minimize_header = FALSE;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_STATIC
@@ -751,19 +1020,42 @@ H5D__update_oh_info(H5F_t *file, H5D_t *dset, hid_t dapl_id)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value info")
} /* end if */
- /* Add the dataset's raw data size to the size of the header, if the raw data will be stored as compact */
- if(layout->type == H5D_COMPACT)
- ohdr_size += layout->storage.u.compact.size;
+ if (FAIL == H5D__use_minimized_dset_headers(file, dset, &minimize_header))
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTGET, FAIL,
+ "can't get minimize settings")
+ if (TRUE == minimize_header) {
+ if (FAIL == H5D__prepare_minimized_oh(file, dset, oloc))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "can't create minimized dataset object header")
+ } else {
+ /* Add the dataset's raw data size to the size of the header, if the
+ * raw data will be stored as compact
+ */
+ if (H5D_COMPACT == layout->type)
+ ohdr_size += layout->storage.u.compact.size;
+
+ /* Create an object header for the dataset */
+ if (0 > H5O_create(
+ file,
+ ohdr_size,
+ (size_t)1,
+ dset->shared->dcpl_id,
+ oloc/*out*/))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to create dataset object header")
+ } /* If use minimum/standard object header space */
- /* Create an object header for the dataset */
- if(H5O_create(file, ohdr_size, (size_t)1, dset->shared->dcpl_id, oloc/*out*/) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header")
HDassert(file == dset->oloc.file);
/* Pin the object header */
if(NULL == (oh = H5O_pin(oloc)))
HGOTO_ERROR(H5E_DATASET, H5E_CANTPIN, FAIL, "unable to pin dataset object header")
+#if 0
+ HDprintf("DATATYPE SIZE: %lu\n",
+ H5O_msg_size_oh(file, oh, H5O_DTYPE_ID, type, 0));
+#endif /* TESTING DEBUG */
+
/* Write the dataspace header message */
if(H5S_append(file, oh, dset->shared->space) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update dataspace header message")
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index cbee0de..e136c80 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -45,6 +45,7 @@
#define H5D_CRT_FILL_VALUE_NAME "fill_value" /* Fill value */
#define H5D_CRT_ALLOC_TIME_STATE_NAME "alloc_time_state" /* Space allocation time state */
#define H5D_CRT_EXT_FILE_LIST_NAME "efl" /* External file list */
+#define H5D_CRT_MIN_DSET_HDR_SIZE_NAME "dset_oh_minimize"/* Minimize object header */
/* ======== Dataset access property names ======== */
#define H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME "rdcc_nslots" /* Size of raw data chunk cache(slots) */
diff --git a/src/H5F.c b/src/H5F.c
index 01fd7db..7e206bb 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1713,3 +1713,97 @@ H5Fincrement_filesize(hid_t file_id, hsize_t increment)
done:
FUNC_LEAVE_API(ret_value)
} /* H5Fincrement_filesize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fget_dset_no_attrs_hint
+ *
+ * Purpose:
+ *
+ * Get the file-level setting to create minimized dataset object headers.
+ * Result is stored at pointer `minimize`.
+ *
+ * Return:
+ *
+ * Success: SUCCEED (0) (non-negative value)
+ * Failure: FAIL (-1) (negative value)
+ *
+ * Programmer:
+ *
+ * Jacob Smith
+ * 15 August 2018
+ *
+ * Changes: None.
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fget_dset_no_attrs_hint(hid_t file_id,
+ hbool_t *minimize)
+{
+ H5F_t *f = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*b", file_id, minimize);
+
+ if (NULL == minimize)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "out pointer 'minimize' cannot be NULL")
+
+ f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE);
+ if (NULL == f)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "can't get file from id")
+
+ HDassert(f->shared);
+
+ *minimize = f->shared->crt_dset_min_ohdr_flag;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Fget_dset_no_attrs_hint */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Fset_dset_no_attrs_hint
+ *
+ * Purpose:
+ *
+ * Set the file-level setting to create minimized dataset object headers.
+ *
+ * Return:
+ *
+ * Success: SUCCEED (0) (non-negative value)
+ * Failure: FAIL (-1) (negative value)
+ *
+ * Programmer:
+ *
+ * Jacob Smith
+ * 15 August 2018
+ *
+ * Changes: None.
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Fset_dset_no_attrs_hint(hid_t file_id,
+ hbool_t minimize)
+{
+ H5F_t *f = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ib", file_id, minimize);
+
+ f = (H5F_t *)H5I_object_verify(file_id, H5I_FILE);
+ if (NULL == f)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "can't get file from id")
+
+ HDassert(f->shared);
+
+ f->shared->crt_dset_min_ohdr_flag = minimize;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Fset_dset_no_attrs_hint */
+
diff --git a/src/H5Fint.c b/src/H5Fint.c
index abc638a..c3fe07a 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -880,6 +880,9 @@ H5F__new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_
/* intialize point of no return */
f->shared->point_of_no_return = FALSE;
+ /* set default value for minimizing dataset object headers */
+ f->shared->crt_dset_min_ohdr_flag = FALSE;
+
/* Copy the file creation and file access property lists into the
* new file handle. We do this early because some values might need
* to change as the file is being opened.
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 2ab41de..edbd460 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -353,6 +353,7 @@ struct H5F_file_t {
/* Object flush info */
H5F_object_flush_t object_flush; /* Information for object flush callback */
+ hbool_t crt_dset_min_ohdr_flag; /* flag to minimize created dataset object header */
};
/*
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index 73c59f5..6274eb0 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -273,6 +273,8 @@ H5_DLL herr_t H5Freset_page_buffering_stats(hid_t file_id);
H5_DLL herr_t H5Fget_page_buffering_stats(hid_t file_id, unsigned accesses[2],
unsigned hits[2], unsigned misses[2], unsigned evictions[2], unsigned bypasses[2]);
H5_DLL herr_t H5Fget_mdc_image_info(hid_t file_id, haddr_t *image_addr, hsize_t *image_size);
+H5_DLL herr_t H5Fget_dset_no_attrs_hint(hid_t file_id, hbool_t *minimize);
+H5_DLL herr_t H5Fset_dset_no_attrs_hint(hid_t file_id, hbool_t minimize);
#ifdef H5_HAVE_PARALLEL
H5_DLL herr_t H5Fset_mpi_atomicity(hid_t file_id, hbool_t flag);
diff --git a/src/H5Oint.c b/src/H5Oint.c
index 2752a25..1d07415 100644
--- a/src/H5Oint.c
+++ b/src/H5Oint.c
@@ -83,7 +83,6 @@ static herr_t H5O__visit_cb(hid_t group, const char *name, const H5L_info_t *lin
void *_udata);
static const H5O_obj_class_t *H5O__obj_class_real(const H5O_t *oh);
-
/*********************/
/* Package Variables */
/*********************/
@@ -277,130 +276,276 @@ done:
* matzke@llnl.gov
* Aug 5 1997
*
+ * Changes: 17 August 2018
+ * Jacob Smith
+ * Refactor out the operations into two separate steps --
+ * preparation and application -- to facilitate overriding the
+ * library-default size allocated for the object header. This
+ * function is retained as a wrapper, to minimize changes to
+ * unaffected calling functions.
+ *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id,
- H5O_loc_t *loc/*out*/)
+H5O_create( \
+ H5F_t *f, \
+ size_t size_hint, \
+ size_t initial_rc, \
+ hid_t ocpl_id, \
+ H5O_loc_t *loc) /*out*/
{
- H5P_genplist_t *oc_plist; /* Object creation property list */
- H5O_t *oh = NULL; /* Object header created */
- haddr_t oh_addr; /* Address of initial object header */
- size_t oh_size; /* Size of initial object header */
- uint8_t oh_flags; /* Object header's initial status flags */
- unsigned insert_flags = H5AC__NO_FLAGS_SET; /* Flags for inserting object header into cache */
- hbool_t store_msg_crt_idx; /* Whether to always store message creation indices for this file */
- herr_t ret_value = SUCCEED; /* return value */
+ H5O_t *oh = NULL;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(FAIL)
- /* check args */
HDassert(f);
HDassert(loc);
HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE));
+ /* create object header in freelist
+ * header version is set internally
+ */
+ oh = H5O__create_ohdr(f, ocpl_id);
+ if (NULL == oh)
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL,
+ "Can't instantiate object header")
+
+ /* apply object header information to file
+ */
+ if (0 > H5O__apply_ohdr(
+ f,
+ oh,
+ ocpl_id,
+ size_hint,
+ initial_rc,
+ loc))
+ {
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL,
+ "Can't apply object header to file")
+ }
+
+done:
+ if (FAIL == ret_value &&
+ NULL != oh &&
+ 0 > H5O__free(oh))
+ {
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL,
+ "can't delete object header")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_create() */
+
+
+/*-----------------------------------------------------------------------------
+ * Function: H5O__create_ohdr
+ *
+ * Purpose: Create the object header, set version and flags.
+ *
+ * Return: Success: Pointer to the newly-crated header object.
+ * Failure: NULL
+ *
+ * Programmer: Jacob Smith
+ * 17 August 2018
+ *
+ *-----------------------------------------------------------------------------
+ */
+H5O_t *
+H5O__create_ohdr( \
+ H5F_t *f, \
+ hid_t ocpl_id)
+{
+ H5P_genplist_t *oc_plist;
+ H5O_t *oh = NULL; /* Object header in Freelist */
+ uint8_t oh_flags; /* Initial status flags */
+ H5O_t *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI(NULL)
+
+ HDassert(f);
+ HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE));
+
/* Check for invalid access request */
- if(0 == (H5F_INTENT(f) & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, FAIL, "no write intent on file")
+ if (0 == (H5F_INTENT(f) & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_OHDR, H5E_BADVALUE, NULL,
+ "no write intent on file")
- /* Make certain we allocate at least a reasonable size for the object header */
- size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint));
+ oh = H5FL_CALLOC(H5O_t);
+ if (NULL == oh)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL,
+ "memory allocation failed")
- /* Get the property list */
- if(NULL == (oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id)))
- HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property list")
+ oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id);
+ if (NULL == oc_plist)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, NULL,
+ "not a property list")
/* Get any object header status flags set by properties */
- if(H5P_get(oc_plist, H5O_CRT_OHDR_FLAGS_NAME, &oh_flags) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object header flags")
+ if (0 > H5P_get(oc_plist, H5O_CRT_OHDR_FLAGS_NAME, &oh_flags))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL,
+ "can't get object header flags")
- /* Allocate the object header and zero out header fields */
- if(NULL == (oh = H5FL_CALLOC(H5O_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if (0 > H5O_set_version(f, oh, oh_flags, H5F_STORE_MSG_CRT_IDX(f)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, NULL,
+ "can't set version of object header")
- /* Initialize file-specific information for object header */
- store_msg_crt_idx = H5F_STORE_MSG_CRT_IDX(f);
+ oh->flags = oh_flags;
- if(H5O_set_version(f, oh, oh_flags, store_msg_crt_idx) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTSET, FAIL, "can't set version of objecdt header")
+ ret_value = oh;
+
+done:
+ if (NULL == ret_value &&
+ NULL != oh &&
+ 0 > H5O__free(oh))
+ {
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL,
+ "can't delete object header")
+ }
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O__create_ohdr */
+
+
+/*-----------------------------------------------------------------------------
+ * Function: H5O__apply_ohdr
+ *
+ * Purpose: Initialize and set the object header in the file.
+ * Record some information at `loc_out`.
+ *
+ * Return: Success: SUCCEED (0) (non-negative value)
+ * Failure: FAI (-1) (negative value)
+ *
+ * Programmer: Jacob Smith
+ * 17 August 2018
+ *
+ *-----------------------------------------------------------------------------
+ */
+herr_t
+H5O__apply_ohdr( \
+ H5F_t *f, \
+ H5O_t *oh, \
+ hid_t ocpl_id, \
+ size_t size_hint, \
+ size_t initial_rc, \
+ H5O_loc_t *loc_out)
+{
+ haddr_t oh_addr;
+ size_t oh_size;
+ H5P_genplist_t *oc_plist = NULL;
+ unsigned insert_flags = H5AC__NO_FLAGS_SET;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ HDassert(f);
+ HDassert(loc_out);
+ HDassert(oh);
+ HDassert(TRUE == H5P_isa_class(ocpl_id, H5P_OBJECT_CREATE));
+
+ /* Allocate at least a reasonable size for the object header */
+ size_hint = H5O_ALIGN_F(f, MAX(H5O_MIN_SIZE, size_hint));
oh->sizeof_size = H5F_SIZEOF_SIZE(f);
oh->sizeof_addr = H5F_SIZEOF_ADDR(f);
- oh->swmr_write = !!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE);
+ oh->swmr_write = !!(H5F_INTENT(f) & H5F_ACC_SWMR_WRITE); /* funky cast */
+
#ifdef H5O_ENABLE_BAD_MESG_COUNT
- /* Check whether the "bad message count" property is set */
- if(H5P_exist_plist(oc_plist, H5O_BAD_MESG_COUNT_NAME) > 0) {
- /* Retrieve bad message count flag */
- if(H5P_get(oc_plist, H5O_BAD_MESG_COUNT_NAME, &oh->store_bad_mesg_count) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "can't get bad message count flag")
+ if (0 < H5P_exist_plist(oc_plist, H5O_BAD_MESG_COUNT_NAME)) {
+ /* Set bad message count flag -- from property list */
+ if (0 > H5P_get(oc_plist,
+ H5O_BAD_MESG_COUNT_NAME,
+ &oh->store_bad_mesg_count))
+ {
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL,
+ "can't get bad message count flag")
+ }
}
#endif /* H5O_ENABLE_BAD_MESG_COUNT */
/* Create object header proxy if doing SWMR writes */
- if(oh->swmr_write) {
- /* Create virtual entry, for use as proxy */
- if(NULL == (oh->proxy = H5AC_proxy_entry_create()))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL, "can't create object header proxy")
- }
- else
+ if (oh->swmr_write) {
+ oh->proxy = H5AC_proxy_entry_create();
+ if (NULL == oh->proxy)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCREATE, FAIL,
+ "can't create object header proxy")
+ } else {
oh->proxy = NULL;
+ }
- /* Set initial status flags */
- oh->flags = oh_flags;
+ oc_plist = (H5P_genplist_t *)H5I_object(ocpl_id);
+ if (NULL == oc_plist)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL,
+ "not a property list")
/* Initialize version-specific fields */
- if(oh->version > H5O_VERSION_1) {
- /* Initialize all time fields with current time, if we are storing them */
- if(oh->flags & H5O_HDR_STORE_TIMES)
+ if (oh->version > H5O_VERSION_1) {
+ /* Initialize all time fields */
+ if (oh->flags & H5O_HDR_STORE_TIMES)
oh->atime = oh->mtime = oh->ctime = oh->btime = H5_now();
else
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
- /* Make certain attribute creation order tracking is enabled if
- * attributes can be shared in this file.
- */
- if(store_msg_crt_idx)
+ if (H5F_STORE_MSG_CRT_IDX(f))
+ /* flag to record message creation indices */
oh->flags |= H5O_HDR_ATTR_CRT_ORDER_TRACKED;
- /* Retrieve attribute storage phase change values from property list */
- if(H5P_get(oc_plist, H5O_CRT_ATTR_MAX_COMPACT_NAME, &oh->max_compact) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get max. # of compact attributes")
- if(H5P_get(oc_plist, H5O_CRT_ATTR_MIN_DENSE_NAME, &oh->min_dense) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get min. # of dense attributes")
+ /* Set attribute storage phase change values -- from property list */
+ if (0 > H5P_get(oc_plist,
+ H5O_CRT_ATTR_MAX_COMPACT_NAME,
+ &oh->max_compact))
+ {
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL,
+ "can't get max. # of compact attributes")
+ }
+ if (0 > H5P_get(oc_plist,
+ H5O_CRT_ATTR_MIN_DENSE_NAME,
+ &oh->min_dense))
+ {
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL,
+ "can't get min. # of dense attributes")
+ }
/* Check for non-default attribute storage phase change values */
- if(oh->max_compact != H5O_CRT_ATTR_MAX_COMPACT_DEF || oh->min_dense != H5O_CRT_ATTR_MIN_DENSE_DEF)
+ if (H5O_CRT_ATTR_MAX_COMPACT_DEF != oh->max_compact || \
+ H5O_CRT_ATTR_MIN_DENSE_DEF != oh->min_dense )
+ {
oh->flags |= H5O_HDR_ATTR_STORE_PHASE_CHANGE;
+ }
/* Determine correct value for chunk #0 size bits */
/* Avoid compiler warning on 32-bit machines */
#if H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T
- if(size_hint > 4294967295UL)
+ if (size_hint > 4294967295UL)
oh->flags |= H5O_HDR_CHUNK0_8;
else
#endif /* H5_SIZEOF_SIZE_T > H5_SIZEOF_INT32_T */
- if(size_hint > 65535)
+ if (size_hint > 65535)
oh->flags |= H5O_HDR_CHUNK0_4;
- else if(size_hint > 255)
+ else if (size_hint > 255)
oh->flags |= H5O_HDR_CHUNK0_2;
- } /* end if */
- else {
+ } else {
/* Reset unused time fields */
oh->atime = oh->mtime = oh->ctime = oh->btime = 0;
- } /* end else */
+ } /* end if/else header version >1 */
/* Compute total size of initial object header */
/* (i.e. object header prefix and first chunk) */
oh_size = (size_t)H5O_SIZEOF_HDR(oh) + size_hint;
/* Allocate disk space for header and first chunk */
- if(HADDR_UNDEF == (oh_addr = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)oh_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
+ oh_addr = H5MF_alloc(f, H5FD_MEM_OHDR, (hsize_t)oh_size);
+ if (HADDR_UNDEF == oh_addr)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "file allocation failed for object header")
/* Create the chunk list */
- oh->nchunks = oh->alloc_nchunks = 1;
- if(NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ oh->nchunks = 1;
+ oh->alloc_nchunks = 1;
+ oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks);
+ if (NULL == oh->chunk)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed")
/* Initialize the first chunk */
oh->chunk[0].addr = oh_addr;
@@ -409,30 +554,37 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id,
/* Allocate enough space for the first chunk */
/* (including space for serializing the object header prefix */
- if(NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, oh_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, oh_size);
+ if(NULL == oh->chunk[0].image)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed")
oh->chunk[0].chunk_proxy = NULL;
/* Put magic # for object header in first chunk */
- if(oh->version > H5O_VERSION_1)
+ if (H5O_VERSION_1 < oh->version)
HDmemcpy(oh->chunk[0].image, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC);
/* Create the message list */
oh->nmesgs = 1;
oh->alloc_nmesgs = H5O_NMESGS;
- if(NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh->alloc_nmesgs)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh->alloc_nmesgs);
+ if (NULL == oh->mesg)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed")
- /* Initialize the initial "null" message, covering the entire first chunk */
+ /* Initialize the initial "null" message; covers the entire first chunk */
oh->mesg[0].type = H5O_MSG_NULL;
oh->mesg[0].dirty = TRUE;
oh->mesg[0].native = NULL;
- oh->mesg[0].raw = oh->chunk[0].image + (H5O_SIZEOF_HDR(oh) - H5O_SIZEOF_CHKSUM_OH(oh)) + H5O_SIZEOF_MSGHDR_OH(oh);
+ oh->mesg[0].raw = oh->chunk[0].image \
+ + H5O_SIZEOF_HDR(oh) \
+ - H5O_SIZEOF_CHKSUM_OH(oh) \
+ + H5O_SIZEOF_MSGHDR_OH(oh);
oh->mesg[0].raw_size = size_hint - (size_t)H5O_SIZEOF_MSGHDR_OH(oh);
oh->mesg[0].chunkno = 0;
/* Check for non-zero initial refcount on the object header */
- if(initial_rc > 0) {
+ if (initial_rc > 0) {
/* Set the initial refcount & pin the header when its inserted */
oh->rc = initial_rc;
insert_flags |= H5AC__PIN_ENTRY_FLAG;
@@ -442,9 +594,11 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id,
H5_BEGIN_TAG(oh_addr);
/* Cache object header */
- if(H5AC_insert_entry(f, H5AC_OHDR, oh_addr, oh, insert_flags) < 0)
- HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, FAIL, "unable to cache object header")
+ if (0 > H5AC_insert_entry(f, H5AC_OHDR, oh_addr, oh, insert_flags))
+ HGOTO_ERROR_TAG(H5E_OHDR, H5E_CANTINSERT, FAIL,
+ "unable to cache object header")
+ /* TODO: is this relevant to the BEGIN/END TAG region? if not, delete */
/* Reset object header pointer, now that it's been inserted into the cache */
oh = NULL;
@@ -452,20 +606,16 @@ H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc, hid_t ocpl_id,
H5_END_TAG
/* Set up object location */
- loc->file = f;
- loc->addr = oh_addr;
+ loc_out->file = f;
+ loc_out->addr = oh_addr;
- /* Open it */
- if(H5O_open(loc) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header")
+ if (0 > H5O_open(loc_out))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL,
+ "unable to open object header")
done:
- if(ret_value < 0 && oh)
- if(H5O__free(oh) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
-
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5O_create() */
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* H5O__apply_ohdr */
/*-------------------------------------------------------------------------
@@ -2686,6 +2836,64 @@ H5O_get_oh_addr(const H5O_t *oh)
/*-------------------------------------------------------------------------
+ * Function: H5O_get_oh_flags
+ *
+ * Programmer: Jacob Smith
+ * 17 August 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+uint8_t
+H5O_get_oh_flags(const H5O_t *oh)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+ HDassert(oh);
+ HDassert(oh->flags);
+ FUNC_LEAVE_NOAPI(oh->flags);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_oh_mtime
+ *
+ * Purpose: Retrieve an object's modification time. Assumes that the
+ * caller has verified that accessing this variable is appropriate
+ * to the header in question.
+ *
+ * Programmer: Jacob Smith
+ * 17 August 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+time_t
+H5O_get_oh_mtime(const H5O_t *oh)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+ HDassert(oh);
+ HDassert(oh->mtime);
+ FUNC_LEAVE_NOAPI(oh->mtime);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_oh_version
+ *
+ * Programmer: Jacob Smith
+ * 17 August 2018
+ *
+ *-------------------------------------------------------------------------
+ */
+uint8_t
+H5O_get_oh_version(const H5O_t *oh)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+ HDassert(oh);
+ HDassert(oh->version);
+ FUNC_LEAVE_NOAPI(oh->version);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_get_rc_and_type
*
* Purpose: Retrieve an object's reference count and type
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 10063d5..f8154c4 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -120,8 +120,14 @@ typedef struct H5O_mesg_t H5O_mesg_t;
/* If the module using this macro is allowed access to the private variables, access them directly */
#ifdef H5O_MODULE
#define H5O_OH_GET_ADDR(O) ((O)->chunk[0].addr)
+#define H5O_OH_GET_VERSION(O) ((O)->version)
+#define H5O_OH_GET_FLAGS(O) ((O)->flags)
+#define H5O_OH_GET_MTIME(O) ((O)->mtime)
#else /* H5O_MODULE */
#define H5O_OH_GET_ADDR(O) (H5O_get_oh_addr(O))
+#define H5O_OH_GET_VERSION(O) (H5O_get_oh_version(O))
+#define H5O_OH_GET_FLAGS(O) (H5O_get_oh_flags(O))
+#define H5O_OH_GET_MTIME(O) (H5O_get_oh_mtime(O))
#endif /* H5O_MODULE */
/* Set the fields in a shared message structure */
@@ -865,6 +871,9 @@ struct H5P_genplist_t;
H5_DLL herr_t H5O_init(void);
H5_DLL herr_t H5O_create(H5F_t *f, size_t size_hint, size_t initial_rc,
hid_t ocpl_id, H5O_loc_t *loc/*out*/);
+H5_DLL H5O_t *H5O__create_ohdr(H5F_t *f, hid_t ocpl_id);
+H5_DLL herr_t H5O__apply_ohdr(H5F_t *f, H5O_t *oh, hid_t ocpl_id,
+ size_t size_hint, size_t initial_rc, H5O_loc_t *loc_out);
H5_DLL herr_t H5O_open(H5O_loc_t *loc);
H5_DLL herr_t H5O_close(H5O_loc_t *loc, hbool_t *file_closed/*out*/);
H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust);
@@ -888,6 +897,9 @@ H5_DLL hid_t H5O_open_name(const H5G_loc_t *loc, const char *name, hbool_t app_r
H5_DLL herr_t H5O_get_nlinks(const H5O_loc_t *loc, hsize_t *nlinks);
H5_DLL void *H5O_obj_create(H5F_t *f, H5O_type_t obj_type, void *crt_info, H5G_loc_t *obj_loc);
H5_DLL haddr_t H5O_get_oh_addr(const H5O_t *oh);
+H5_DLL uint8_t H5O_get_oh_flags(const H5O_t *oh);
+H5_DLL time_t H5O_get_oh_mtime(const H5O_t *oh);
+H5_DLL uint8_t H5O_get_oh_version(const H5O_t *oh);
H5_DLL herr_t H5O_get_rc_and_type(const H5O_loc_t *oloc, unsigned *rc, H5O_type_t *otype);
H5_DLL H5AC_proxy_entry_t *H5O_get_proxy(const H5O_t *oh);
diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c
index cb13ff3..a1799ad 100644
--- a/src/H5Pdcpl.c
+++ b/src/H5Pdcpl.c
@@ -119,6 +119,11 @@
#define H5D_CRT_EXT_FILE_LIST_COPY H5P__dcrt_ext_file_list_copy
#define H5D_CRT_EXT_FILE_LIST_CMP H5P__dcrt_ext_file_list_cmp
#define H5D_CRT_EXT_FILE_LIST_CLOSE H5P__dcrt_ext_file_list_close
+/* Definitions for dataset object header minimization */
+#define H5D_CRT_MIN_DSET_HDR_SIZE_SIZE sizeof(hbool_t)
+#define H5D_CRT_MIN_DSET_HDR_SIZE_DEF FALSE
+#define H5D_CRT_MIN_DSET_HDR_SIZE_ENC H5P__encode_hbool_t
+#define H5D_CRT_MIN_DSET_HDR_SIZE_DEC H5P__decode_hbool_t
/******************/
@@ -211,6 +216,7 @@ static const H5O_layout_t H5D_def_layout_g = H5D_CRT_LAYOUT_DEF; /* Defau
static const H5O_fill_t H5D_def_fill_g = H5D_CRT_FILL_VALUE_DEF; /* Default fill value */
static const unsigned H5D_def_alloc_time_state_g = H5D_CRT_ALLOC_TIME_STATE_DEF; /* Default allocation time state */
static const H5O_efl_t H5D_def_efl_g = H5D_CRT_EXT_FILE_LIST_DEF; /* Default external file list */
+static const H5O_ohdr_min_g = H5D_CRT_MIN_DSET_HDR_SIZE_DEF; /* Default object header minimization */
/* Defaults for each type of layout */
#ifdef H5_HAVE_C99_DESIGNATED_INITIALIZER
@@ -270,6 +276,26 @@ H5P__dcrt_reg_prop(H5P_genclass_t *pclass)
H5D_CRT_EXT_FILE_LIST_DEL, H5D_CRT_EXT_FILE_LIST_COPY, H5D_CRT_EXT_FILE_LIST_CMP, H5D_CRT_EXT_FILE_LIST_CLOSE) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register the object header minimization property */
+ if (0 > H5P_register_real(
+ pclass, /* class */
+ H5D_CRT_MIN_DSET_HDR_SIZE_NAME, /* name */
+ H5D_CRT_MIN_DSET_HDR_SIZE_SIZE, /* size */
+ &H5O_ohdr_min_g, /* default */
+ NULL, /* create */
+ NULL, /* set */
+ NULL, /* get */
+ H5D_CRT_MIN_DSET_HDR_SIZE_ENC, /* encode */
+ H5D_CRT_MIN_DSET_HDR_SIZE_DEC, /* decode */
+ NULL, /* delete */
+ NULL, /* copy */
+ NULL, /* compare */
+ NULL)) /* close */
+ {
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL,
+ "can't insert property into class")
+ }
+
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5P__dcrt_reg_prop() */
@@ -3733,3 +3759,103 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_fill_time() */
+
+/*-----------------------------------------------------------------------------
+ * Function: H5Pget_dset_no_attrs_hint
+ *
+ * Purpose:
+ *
+ * Access the flag for whether or not datasets created by the given dcpl
+ * will be created with a "minimized" object header.
+ *
+ * Return:
+ *
+ * Failure: Negative value (FAIL)
+ * Success: Non-negative value (SUCCEED)
+ *
+ * Programmer: Jacob Smith
+ * 14 August 2018
+ *
+ * Modifications: None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_dset_no_attrs_hint(hid_t dcpl_id,
+ hbool_t *minimize)
+{
+ hbool_t setting = FALSE;
+ H5P_genplist_t *plist = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "i*b", dcpl_id, minimize);
+
+ if (NULL == minimize)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL,
+ "receiving pointer cannot be NULL")
+
+ plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE);
+ if (NULL == plist)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL,
+ "can't find object for ID")
+
+ if (0 > H5P_peek(plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &setting))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL,
+ "can't get dset oh minimize flag value")
+
+ *minimize = setting;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pget_dset_no_attrs_hint */
+
+
+/*-----------------------------------------------------------------------------
+ * Function: H5Pset_dset_no_attrs_hint
+ *
+ * Purpose:
+ *
+ * Set the dcpl to minimize (or explicitly to not minimized) dataset object
+ * headers upon creation.
+ *
+ * Return:
+ *
+ * Failure: Negative value (FAIL)
+ * Success: Non-negative value (SUCCEED)
+ *
+ * Programmer: Jacob Smith
+ * 14 August 2018
+ *
+ * Modifications: None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_dset_no_attrs_hint(hid_t dcpl_id,
+ hbool_t minimize)
+{
+ H5P_genplist_t *plist = NULL;
+ hbool_t prev_set = FALSE;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE2("e", "ib", dcpl_id, minimize);
+
+ plist = H5P_object_verify(dcpl_id, H5P_DATASET_CREATE);
+ if (NULL == plist)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL,
+ "can't find object for ID")
+
+ if (0 > H5P_peek(plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &prev_set))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL,
+ "can't get extant dset oh minimize flag value")
+
+ if (0 > H5P_poke(plist, H5D_CRT_MIN_DSET_HDR_SIZE_NAME, &minimize))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL,
+ "can't get dset oh minimize flag value")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pset_dset_no_attrs_hint */
+
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index c5596e5..c2f9b4c 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -409,6 +409,8 @@ H5_DLL herr_t H5Pget_alloc_time(hid_t plist_id, H5D_alloc_time_t
H5_DLL herr_t H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time);
H5_DLL herr_t H5Pget_fill_time(hid_t plist_id, H5D_fill_time_t
*fill_time/*out*/);
+H5_DLL herr_t H5Pget_dset_no_attrs_hint(hid_t dcpl_id, hbool_t *minimize);
+H5_DLL herr_t H5Pset_dset_no_attrs_hint(hid_t dcpl_id, hbool_t minimize);
/* Dataset access property list (DAPL) routines */
H5_DLL herr_t H5Pset_chunk_cache(hid_t dapl_id, size_t rdcc_nslots,