summaryrefslogtreecommitdiffstats
path: root/src/H5D.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5D.c')
-rw-r--r--src/H5D.c343
1 files changed, 244 insertions, 99 deletions
diff --git a/src/H5D.c b/src/H5D.c
index dbdfb49..cb53178 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1461,6 +1461,225 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_update_entry_cache
+ *
+ * Purpose: Create and fill an H5G_entry_t object for insertion into
+ * the group LOC.
+ *
+ * This code was originally found at the end of H5D_create()
+ * but was placed here for general use.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Errors:
+ *
+ * Programmer: Bill Wendling
+ * Thursday, October 31, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_update_entry_cache(H5F_t *file, H5G_entry_t *ent, H5G_entry_t *loc,
+ const char *name, const H5S_t *space,
+ H5P_genplist_t *plist, H5O_layout_t *layout, H5T_t *type,
+ hbool_t allocate_header, haddr_t header)
+{
+ H5O_pline_t dcpl_pline;
+ H5D_alloc_time_t alloc_time;
+ size_t ohdr_size = H5D_MINHDR_SIZE; /* Size of dataset's object header */
+
+ /* fill value variables */
+ H5D_fill_time_t fill_time;
+ H5O_fill_t fill_prop = { NULL, 0, NULL };
+ H5O_fill_new_t fill = { NULL, 0, NULL, H5D_ALLOC_TIME_LATE, H5D_FILL_TIME_ALLOC, TRUE };
+ H5D_fill_value_t fill_status;
+
+ /* return code */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5D_update_entry_cache, FAIL);
+
+ if (layout->type == H5D_COMPACT)
+ ohdr_size += layout->size;
+
+ /* If TRUE, then allocate the space in the file for the header */
+ if (allocate_header) {
+ /* Create (open for write access) an object header */
+ if (H5O_create(file, ohdr_size, ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to create dataset object header");
+ } else {
+ /*
+ * Just initialize the header to the specified address and open
+ * it for us
+ */
+ HDmemset(ent, 0, sizeof(H5G_entry_t));
+
+ if (H5O_init(file, ohdr_size, ent, header) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to initialize dataset object header");
+ }
+
+ /*
+ * Retrieve properties of fill value and others. Copy them into new fill
+ * value struct. Convert the fill value to the dataset type and write
+ * the message
+ */
+ if (H5P_get(plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve space allocation time");
+
+ if (H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time");
+
+ if (H5P_fill_value_defined(plist, &fill_status) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined");
+
+ if (fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED) {
+ if (H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value");
+
+ if (H5O_copy(H5O_FILL, &fill_prop, &fill) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to copy fill value");
+
+ if (fill_prop.buf && fill_prop.size > 0 && H5O_fill_convert(&fill, type) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to convert fill value to dataset type");
+
+ fill.fill_defined = TRUE;
+ } else if (fill_status == H5D_FILL_VALUE_UNDEFINED) {
+ fill.size = -1;
+ fill.type = fill.buf = NULL;
+ fill.fill_defined = FALSE;
+ } else {
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL,
+ "unable to determine if fill value is defined");
+ }
+
+ fill.alloc_time = alloc_time;
+ fill.fill_time = fill_time;
+
+ if (fill.fill_defined == FALSE && fill_time != H5D_FILL_TIME_NEVER)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to create dataset");
+
+ /* Write new fill value message */
+ if (H5O_modify(ent, H5O_FILL_NEW, 0, H5O_FLAG_CONSTANT, &fill) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update fill value header message");
+ H5O_reset(H5O_FILL, &fill_prop);
+
+ if (fill.buf && H5O_copy(H5O_FILL, &fill, &fill_prop) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL,"unable to copy fill value");
+
+ H5O_reset(H5O_FILL_NEW, &fill);
+
+ /* Write old fill value */
+ if (fill_prop.buf && H5O_modify(ent, H5O_FILL, 0, H5O_FLAG_CONSTANT, &fill_prop) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to update fill value header message");
+
+ if (H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fill value");
+
+ /* Update the type and space header messages */
+ if (H5O_modify(ent, H5O_DTYPE, 0, H5O_FLAG_CONSTANT | H5O_FLAG_SHARED, type) < 0 ||
+ H5S_modify(ent, space) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to update type or space header messages");
+
+ /* Update the filters message */
+ if (H5P_get(plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "Can't retrieve pipeline filter");
+
+ if (dcpl_pline.nfilters > 0 &&
+ H5O_modify(ent, H5O_PLINE, 0, H5O_FLAG_CONSTANT, &dcpl_pline) < 0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update filter header message");
+
+ /* Add a modification time message. */
+ if (H5O_touch(ent, TRUE) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to update modification time message");
+
+ /* Give the dataset a name */
+ if (H5G_insert(loc, name, ent) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to name dataset");
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_update_external_storage_cache
+ *
+ * Purpose: Update the external cache if the dataset uses external
+ * files.
+ *
+ * This code was originally found at the end of H5D_create()
+ * but was placed here for general use.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Errors:
+ *
+ * Programmer: Bill Wendling
+ * Thursday, October 31, 2002
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent,
+ H5O_efl_t *efl, H5O_layout_t *layout)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5D_update_external_storage_cache, FAIL);
+
+ /* Update external storage message */
+ if (efl->nused > 0) {
+ size_t heap_size = H5HL_ALIGN(1);
+ int i;
+
+ for (i = 0; i < efl->nused; ++i)
+ heap_size += H5HL_ALIGN(HDstrlen(efl->slot[i].name) + 1);
+
+ if (H5HL_create(file, heap_size, &efl->heap_addr/*out*/) < 0 ||
+ H5HL_insert(file, efl->heap_addr, 1, "") == (size_t)(-1))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to create external file list name heap");
+
+ for (i = 0; i < efl->nused; ++i) {
+ size_t offset = H5HL_insert(file, efl->heap_addr,
+ HDstrlen(efl->slot[i].name) + 1,
+ efl->slot[i].name);
+
+ assert(0 == efl->slot[i].name_offset);
+
+ if (offset == (size_t)(-1))
+ HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, FAIL, "unable to insert URL into name heap");
+
+ efl->slot[i].name_offset = offset;
+ }
+
+ if (H5O_modify(ent, H5O_EFL, 0, H5O_FLAG_CONSTANT, efl) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to update external file list message");
+ }
+
+ /* Update layout message */
+ if (H5D_COMPACT != layout->type && H5O_modify(ent, H5O_LAYOUT, 0, 0, layout) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout");
+
+done:
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_create
*
* Purpose: Creates a new dataset with name NAME in file F and associates
@@ -1505,6 +1724,15 @@ done:
* A new fill value message is added. Two properties, space allocation
* time and fill value writing time, govern space allocation and fill
* value writing.
+ *
+ * Bill Wendling, 1. November 2002
+ * Removed the cache updating mechanism. This was done so that it
+ * can be called separately from the H5D_create function. There were
+ * two of these mechanisms: one to create and insert into the parent
+ * group the H5G_entry_t object and the other to update based upon
+ * whether we're working with an external file or not. Between the
+ * two, there is a conditional call to allocate space which isn't
+ * part of updating the cache.
*
*-------------------------------------------------------------------------
*/
@@ -1526,12 +1754,8 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
hsize_t chunk_size[32]={0};
H5D_alloc_time_t alloc_time;
H5D_fill_time_t fill_time;
- H5O_fill_t fill_prop={NULL,0,NULL};
- H5O_fill_new_t fill={NULL, 0, NULL, H5D_ALLOC_TIME_LATE, H5D_FILL_TIME_ALLOC, TRUE};
- H5D_fill_value_t fill_status;
H5P_genplist_t *plist; /* Property list */
H5P_genplist_t *new_plist; /* New Property list */
- size_t ohdr_size=H5D_MINHDR_SIZE; /* Size of dataset's object header */
FUNC_ENTER_NOAPI(H5D_create, NULL);
@@ -1709,7 +1933,6 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
if ((ndims=H5S_get_simple_extent_dims(space, new_dset->layout.dim, max_dim))<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize dimension size of compact dataset storage");
/* remember to check if size is small enough to fit header message */
- ohdr_size+=new_dset->layout.size;
break;
@@ -1717,108 +1940,30 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet");
} /* end switch */
- /* Create (open for write access) an object header */
- if (H5O_create(f, ohdr_size, &(new_dset->ent)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to create dataset object header");
-
- /* Retrieve properties of fill value and others. Copy them into new fill
- * value struct. Convert the fill value to the dataset type and write
- * the message */
- if(H5P_get(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
- if(H5P_get(new_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve fill time");
- if(H5P_fill_value_defined(new_plist, &fill_status)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't tell if fill value defined");
- if(fill_status== H5D_FILL_VALUE_DEFAULT || fill_status==H5D_FILL_VALUE_USER_DEFINED) {
- if(H5P_get(new_plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve fill value");
- if(NULL==H5O_copy(H5O_FILL, &fill_prop, &fill))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,NULL, "unable to copy fill value");
- if (fill_prop.buf && fill_prop.size>0 && H5O_fill_convert(&fill, new_dset->type) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to convert fill value to dataset type");
- fill.fill_defined = TRUE;
- } else if(fill_status==H5D_FILL_VALUE_UNDEFINED) {
- fill.size = -1;
- fill.type = fill.buf = NULL;
- fill.fill_defined = FALSE;
- } else {
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "unable to determine if fill value is defined");
- } /* end else */
- fill.alloc_time = alloc_time;
- fill.fill_time = fill_time;
-
- if(fill.fill_defined == FALSE && fill_time != H5D_FILL_TIME_NEVER)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,NULL, "unable to create dataset");
-
- /* Write new fill value message */
- if (H5O_modify(&(new_dset->ent), H5O_FILL_NEW, 0, H5O_FLAG_CONSTANT, &fill) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update fill value header message");
- H5O_reset(H5O_FILL, &fill_prop);
- if(fill.buf && (NULL==H5O_copy(H5O_FILL, &fill, &fill_prop)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,NULL,"unable to copy fill value");
- H5O_reset(H5O_FILL_NEW, &fill);
-
- /* Write old fill value */
- if (fill_prop.buf && H5O_modify(&(new_dset->ent), H5O_FILL, 0, H5O_FLAG_CONSTANT, &fill_prop) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update fill value header message");
- if(H5P_set(new_plist, H5D_CRT_FILL_VALUE_NAME, &fill_prop) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, NULL, "can't set fill value");
-
- /* Update the type and space header messages */
- if (H5O_modify(&(new_dset->ent), H5O_DTYPE, 0,
- H5O_FLAG_CONSTANT|H5O_FLAG_SHARED, new_dset->type)<0 ||
- H5S_modify(&(new_dset->ent), space) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update type or space header messages");
-
- /* Update the filters message */
- if(H5P_get(new_plist, H5D_CRT_DATA_PIPELINE_NAME, &dcpl_pline) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "Can't retrieve pipeline filter");
- if (dcpl_pline.nfilters>0 && H5O_modify (&(new_dset->ent), H5O_PLINE, 0, H5O_FLAG_CONSTANT, &dcpl_pline) < 0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to update filter header message");
-
/*
- * Add a modification time message.
+ * Update the entry cache. That is, create and add a new
+ * "H5G_entry_t" object to the group this dataset is being initially
+ * created in.
*/
- if (H5O_touch(&(new_dset->ent), TRUE)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update modification time message");
-
- /* Give the dataset a name */
- if (H5G_insert(loc, name, &(new_dset->ent)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to name dataset");
+ if (H5D_update_entry_cache(f, &new_dset->ent, loc, name, space, new_plist,
+ &new_dset->layout, new_dset->type, TRUE, (haddr_t)0) != SUCCEED)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the metadata cache");
/*
- * Allocate storage if space allocate time is early; otherwise delay allocation until later.
+ * Allocate storage if space allocate time is early; otherwise delay
+ * allocation until later.
*/
- if(alloc_time==H5D_ALLOC_TIME_EARLY)
- if (H5D_alloc_storage(f, new_dset,H5D_ALLOC_CREATE)<0)
+ if (H5P_get(new_plist, H5D_CRT_ALLOC_TIME_NAME, &alloc_time) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve space allocation time");
+
+ if (alloc_time == H5D_ALLOC_TIME_EARLY)
+ if (H5D_alloc_storage(f, new_dset, H5D_ALLOC_CREATE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize storage");
- /* Update external storage message */
- if (efl.nused>0) {
- size_t heap_size = H5HL_ALIGN (1);
-
- for (i=0; i<efl.nused; i++)
- heap_size += H5HL_ALIGN (HDstrlen (efl.slot[i].name)+1);
- if (H5HL_create (f, heap_size, &(efl.heap_addr)/*out*/)<0 ||
- (size_t)(-1)==H5HL_insert(f, efl.heap_addr, 1, ""))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to create external file list name heap");
- for (i=0; i<efl.nused; i++) {
- size_t offset = H5HL_insert(f, efl.heap_addr,
- HDstrlen(efl.slot[i].name)+1, efl.slot[i].name);
- assert(0==efl.slot[i].name_offset);
- if ((size_t)(-1)==offset)
- HGOTO_ERROR(H5E_EFL, H5E_CANTINIT, NULL, "unable to insert URL into name heap");
- efl.slot[i].name_offset = offset;
- } /* end for */
- if (H5O_modify (&(new_dset->ent), H5O_EFL, 0, H5O_FLAG_CONSTANT, &efl)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to update external file list message");
- } /* end if */
+ /* Update the external storage cache if this is an external object */
+ if (H5D_update_external_storage_cache(f, &new_dset->ent, &efl, &new_dset->layout) != SUCCEED)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't update the external metadata cache");
- /* Update layout message */
- if (H5D_COMPACT != new_dset->layout.type && H5O_modify (&(new_dset->ent), H5O_LAYOUT, 0, 0, &(new_dset->layout))<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "unable to update layout");
-
/* Success */
ret_value = new_dset;