summaryrefslogtreecommitdiffstats
path: root/src/H5Oint.c
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/H5Oint.c
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/H5Oint.c')
-rw-r--r--src/H5Oint.c382
1 files changed, 295 insertions, 87 deletions
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