diff options
-rw-r--r-- | src/H5D.c | 343 | ||||
-rw-r--r-- | src/H5Dprivate.h | 9 | ||||
-rw-r--r-- | src/H5FPclient.c | 12 | ||||
-rw-r--r-- | src/H5FPserver.c | 12 | ||||
-rw-r--r-- | src/H5Fprivate.h | 2 | ||||
-rw-r--r-- | src/H5O.c | 103 | ||||
-rw-r--r-- | src/H5Ofphdf5.c | 54 | ||||
-rw-r--r-- | src/H5Oprivate.h | 4 |
8 files changed, 385 insertions, 154 deletions
@@ -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; diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index 82cfdf3..3526e3c 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -145,6 +145,15 @@ typedef struct H5D_t H5D_t; /* Functions defined in H5D.c */ H5_DLL herr_t H5D_init(void); + +H5_DLL herr_t H5D_update_entry_cache(H5F_t *f, H5G_entry_t *ent, H5G_entry_t *loc, + const char *name, const H5S_t *space, + H5P_genplist_t *new_plist, H5O_layout_t *layout, + H5T_t *type, hbool_t allocate_header, + haddr_t header); +H5_DLL herr_t H5D_update_external_storage_cache(H5F_t *file, H5G_entry_t *ent, + H5O_efl_t *efl, H5O_layout_t *layout); + H5_DLL H5D_t *H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type, const H5S_t *space, hid_t dcpl_id); diff --git a/src/H5FPclient.c b/src/H5FPclient.c index 9ec0fe1..a94b0db 100644 --- a/src/H5FPclient.c +++ b/src/H5FPclient.c @@ -31,18 +31,6 @@ static int interface_initialize_g = 0; #define INTERFACE_INIT NULL -MPI_Datatype SAP_request_t; /* MPI datatype for the SAP_request obj */ -MPI_Datatype SAP_reply_t; /* MPI datatype for the SAP_reply obj */ -MPI_Datatype SAP_sync_t; /* MPI datatype for the SAP_sync obj */ - -/* SAP specific variables */ -MPI_Comm H5FP_SAP_COMM; /* Comm we use: Supplied by user */ -MPI_Comm H5FP_SAP_BARRIER_COMM; /* Comm if you want to do a barrier */ - -unsigned H5FP_sap_rank; /* The rank of the SAP: Supplied by user*/ -unsigned H5FP_my_rank; /* Rank of this process in the COMM */ -int H5FP_comm_size; /* Size of the COMM */ - /* local functions */ static unsigned int H5FP_gen_request_id(void); static herr_t H5FP_update_metadata_cache(hid_t file_id, struct SAP_sync *sap_sync, diff --git a/src/H5FPserver.c b/src/H5FPserver.c index 5fe3df3..2794a2a 100644 --- a/src/H5FPserver.c +++ b/src/H5FPserver.c @@ -41,18 +41,6 @@ static int interface_initialize_g = 0; #define INTERFACE_INIT NULL -MPI_Datatype SAP_request_t; /* MPI datatype for the SAP_request obj */ -MPI_Datatype SAP_reply_t; /* MPI datatype for the SAP_reply obj */ -MPI_Datatype SAP_sync_t; /* MPI datatype for the SAP_sync obj */ - -/* SAP specific variables */ -MPI_Comm H5FP_SAP_COMM; /* Comm we use: Supplied by user */ -MPI_Comm H5FP_SAP_BARRIER_COMM; /* Comm if you want to do a barrier */ - -unsigned H5FP_sap_rank; /* The rank of the SAP: Supplied by user*/ -unsigned H5FP_my_rank; /* Rank of this process in the COMM */ -int H5FP_comm_size; /* Size of the COMM */ - /* Internal SAP structures */ struct sap_obj_lock { diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index b1c591c..ed96763 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -144,7 +144,7 @@ typedef struct H5F_t H5F_t; * Note: the NBYTEDECODE macro is backwards from the memcpy() routine, in * the spirit of the other DECODE macros. */ -#define NBYTEDECODE(s, d, n) do { HDmemcpy(d,s,n); d += n; } while (0) +#define NBYTEDECODE(s, d, n) do { HDmemcpy(d,s,n); s += n; } while (0) /* Address-related macros */ #define H5F_addr_overflow(X,Z) (HADDR_UNDEF==(X) || \ @@ -131,10 +131,10 @@ H5O_init_interface(void) /*------------------------------------------------------------------------- * Function: H5O_create * - * Purpose: Creates a new object header, sets the link count - * to 0, and caches the header. The object header is opened for - * write access and should eventually be closed by calling - * H5O_close(). + * Purpose: Creates a new object header. Allocates space for it and + * then calls an initialization function. The object header + * is opened for write access and should eventually be + * closed by calling H5O_close(). * * Return: Success: Non-negative, the ENT argument contains * information about the object header, @@ -148,33 +148,85 @@ H5O_init_interface(void) * * Modifications: * + * Bill Wendling, 1. November 2002 + * Separated the create function into two different functions. One + * which allocates space and an initialization function which + * does the rest of the work (initializes, caches, and opens the + * object header). + * *------------------------------------------------------------------------- */ herr_t H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/) { - hsize_t size; /*total size of object header */ - H5O_t *oh = NULL; - haddr_t tmp_addr; - herr_t ret_value=SUCCEED; /* Return value */ + haddr_t header; + herr_t ret_value = SUCCEED; /* return value */ FUNC_ENTER_NOAPI(H5O_create, FAIL); /* check args */ assert(f); assert(ent); + HDmemset(ent, 0, sizeof(H5G_entry_t)); size_hint = H5O_ALIGN (MAX (H5O_MIN_SIZE, size_hint)); /* allocate disk space for header and first chunk */ - size = H5O_SIZEOF_HDR(f) + size_hint; + if (HADDR_UNDEF == (header = H5MF_alloc(f, H5FD_MEM_OHDR, + (hsize_t)H5O_SIZEOF_HDR(f) + size_hint))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "file allocation failed for object header header"); + + /* initialize the object header */ + if (H5O_init(f, size_hint, ent, header) != SUCCEED) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to initialize object header"); + +done: + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5O_init + * + * Purpose: Initialize a new object header, sets the link count to 0, + * and caches the header. The object header is opened for + * write access and should eventually be closed by calling + * H5O_close(). + * + * Return: Success: SUCCEED, the ENT argument contains + * information about the object header, + * including its address. + * Failure: FAIL + * + * Programmer: Bill Wendling + * 1, November 2002 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_init(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/, haddr_t header) +{ + H5O_t *oh = NULL; + haddr_t tmp_addr; + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_NOAPI(H5O_init, FAIL); + + /* check args */ + assert(f); + assert(ent); + + size_hint = H5O_ALIGN(MAX(H5O_MIN_SIZE, size_hint)); ent->file = f; - if (HADDR_UNDEF==(ent->header=H5MF_alloc(f, H5FD_MEM_OHDR, size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header header"); - + ent->header = header; + /* allocate the object header and fill in header fields */ - if (NULL==(oh = H5FL_ALLOC(H5O_t,1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + if (NULL == (oh = H5FL_ALLOC(H5O_t, 1))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + oh->dirty = TRUE; oh->version = H5O_VERSION; oh->nlink = 0; @@ -182,20 +234,25 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/) /* create the chunk list and initialize the first chunk */ oh->nchunks = 1; oh->alloc_nchunks = H5O_NCHUNKS; - if (NULL==(oh->chunk=H5FL_ARR_ALLOC(H5O_chunk_t,oh->alloc_nchunks,0))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + + if (NULL == (oh->chunk = H5FL_ARR_ALLOC(H5O_chunk_t, oh->alloc_nchunks, 0))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + tmp_addr = ent->header + (hsize_t)H5O_SIZEOF_HDR(f); oh->chunk[0].dirty = TRUE; oh->chunk[0].addr = tmp_addr; oh->chunk[0].size = size_hint; - if (NULL==(oh->chunk[0].image = H5FL_BLK_ALLOC(chunk_image,size_hint,1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + + if (NULL == (oh->chunk[0].image = H5FL_BLK_ALLOC(chunk_image, size_hint, 1))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); /* create the message list and initialize the first message */ oh->nmesgs = 1; oh->alloc_nmesgs = H5O_NMESGS; - if (NULL==(oh->mesg=H5FL_ARR_ALLOC(H5O_mesg_t,oh->alloc_nmesgs,1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + + if (NULL == (oh->mesg = H5FL_ARR_ALLOC(H5O_mesg_t, oh->alloc_nmesgs, 1))) + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + oh->mesg[0].type = H5O_NULL; oh->mesg[0].dirty = TRUE; oh->mesg[0].native = NULL; @@ -205,13 +262,13 @@ H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/) /* cache it */ if (H5AC_set(f, H5AC_OHDR, ent->header, oh) < 0) { - H5FL_FREE(H5O_t,oh); - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header"); + H5FL_FREE(H5O_t,oh); + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header"); } /* open it */ if (H5O_open(ent) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header"); done: FUNC_LEAVE(ret_value); diff --git a/src/H5Ofphdf5.c b/src/H5Ofphdf5.c index a51d42a..dffc8b0 100644 --- a/src/H5Ofphdf5.c +++ b/src/H5Ofphdf5.c @@ -41,6 +41,7 @@ static void *H5O_fphdf5_decode(H5F_t *f, const uint8_t *p, H5O_shared_t *sh) static herr_t H5O_fphdf5_encode(H5F_t *f, uint8_t *p, const void *_mesg); static size_t H5O_fphdf5_size(H5F_t *f, const void *_mesg); static herr_t H5O_fphdf5_reset(void *_mesg); +static void *H5O_fphdf5_copy(const void *mesg, void *dest); static herr_t H5O_fphdf5_free(void *_mesg); static herr_t H5O_fphdf5_debug(H5F_t *f, const void *_mesg, FILE *stream, int indent, int fwidth); @@ -52,7 +53,7 @@ const H5O_class_t H5O_FPHDF5[1] = {{ sizeof(H5O_fphdf5_t), /* native message size */ H5O_fphdf5_decode, /* decode message */ H5O_fphdf5_encode, /* encode message */ - NULL, /* copy the native value */ + H5O_fphdf5_copy, /* copy the native value */ H5O_fphdf5_size, /* size of symbol table entry */ H5O_fphdf5_reset, /* default reset method */ H5O_fphdf5_free, /* free method */ @@ -97,7 +98,6 @@ H5O_fphdf5_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh) { H5O_fphdf5_t *fmeta = NULL; /* New FPHDF5 metadata structure */ void *ret_value; - unsigned int i; FUNC_ENTER_NOAPI(H5O_fphdf5_decode, NULL); @@ -110,7 +110,10 @@ H5O_fphdf5_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh) fmeta = H5FL_ALLOC(H5O_fphdf5_t, 1); /* decode the OID first */ - NBYTEDECODE(fmeta->oid,p,sizeof(fmeta->oid)); + NBYTEDECODE(p, fmeta->oid, sizeof(fmeta->oid)); + + /* decode the header address next */ + NBYTEDECODE(p, &fmeta->header, sizeof(fmeta->header)); /* decode the dataspace dimensions next */ fmeta->sdim = H5O_SDSPACE[0].decode(f, p, NULL); @@ -133,12 +136,21 @@ H5O_fphdf5_decode(H5F_t *f, const uint8_t *p, H5O_shared_t UNUSED *sh) /* decode the modification time next */ fmeta->mtime = H5O_DTYPE[0].decode(f, p, NULL); - if (!fmeta->dtype) + if (!fmeta->mtime) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); /* jump past the modification time part */ p += H5O_MTIME[0].raw_size(f, fmeta->mtime); + /* decode the dataset layout next */ + fmeta->layout = H5O_LAYOUT[0].decode(f, p, NULL); + + if (!fmeta->layout) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + /* jump past the dataset layout part */ + p += H5O_LAYOUT[0].raw_size(f, fmeta->layout); + /* decode the group the modification took place in */ fmeta->group = H5O_NAME[0].decode(f, p, NULL); @@ -178,6 +190,9 @@ done: if (H5O_MTIME[0].free) H5O_MTIME[0].free(fmeta->mtime); + if (H5O_LAYOUT[0].free) + H5O_LAYOUT[0].free(fmeta->layout); + if (H5O_PLIST[0].free) H5O_PLIST[0].free(fmeta->plist); @@ -209,7 +224,6 @@ H5O_fphdf5_encode(H5F_t *f, uint8_t *p, const void *mesg) { const H5O_fphdf5_t *fmeta = (const H5O_fphdf5_t *)mesg; herr_t ret_value = SUCCEED; - unsigned int i; FUNC_ENTER_NOAPI(H5O_fphdf5_encode, FAIL); @@ -219,7 +233,10 @@ H5O_fphdf5_encode(H5F_t *f, uint8_t *p, const void *mesg) assert(fmeta); /* encode the OID first */ - NBYTEENCODE(p,fmeta->oid,sizeof(fmeta->oid)); + NBYTEENCODE(p, fmeta->oid, sizeof(fmeta->oid)); + + /* encode the header address info next */ + NBYTEENCODE(p, &fmeta->header, sizeof(fmeta->header)); /* encode the dataspace dimensions next */ ret_value = H5O_SDSPACE[0].encode(f, p, fmeta->sdim); @@ -248,6 +265,15 @@ H5O_fphdf5_encode(H5F_t *f, uint8_t *p, const void *mesg) /* jump past the modification time part */ p += H5O_MTIME[0].raw_size(f, fmeta->mtime); + /* encode the dataset layout next */ + ret_value = H5O_LAYOUT[0].encode(f, p, fmeta->layout); + + if (ret_value < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + + /* jump past the dataset layout part */ + p += H5O_LAYOUT[0].raw_size(f, fmeta->layout); + /* encode the group name next */ ret_value = H5O_NAME[0].encode(f, p, fmeta->group); @@ -308,8 +334,10 @@ H5O_fphdf5_copy(const void *mesg, void *dest) HDmemcpy(dst->oid,src->oid,sizeof(src->oid)); H5O_SDSPACE[0].copy(src->sdim, dst->sdim); + dst->header = src->header; H5O_DTYPE[0].copy(src->dtype, dst->dtype); H5O_MTIME[0].copy(src->mtime, dst->mtime); + H5O_LAYOUT[0].copy(src->layout, dst->layout); H5O_NAME[0].copy(src->group, dst->group); H5O_NAME[0].copy(src->dset, dst->dset); @@ -352,8 +380,10 @@ H5O_fphdf5_size(H5F_t *f, const void *mesg) /* add in the metadata sizes */ ret_value = sizeof(fmeta->oid); ret_value += H5O_SDSPACE[0].raw_size(f, fmeta->sdim); + ret_value += sizeof(fmeta->header); ret_value += H5O_DTYPE[0].raw_size(f, fmeta->dtype); ret_value += H5O_MTIME[0].raw_size(f, fmeta->mtime); + ret_value += H5O_LAYOUT[0].raw_size(f, fmeta->layout); ret_value += H5O_NAME[0].raw_size(f, fmeta->group); ret_value += H5O_NAME[0].raw_size(f, fmeta->dset); ret_value += H5O_PLIST[0].raw_size(f, fmeta->plist); @@ -379,7 +409,6 @@ H5O_fphdf5_reset(void *mesg) { H5O_fphdf5_t *fmeta = (H5O_fphdf5_t *)mesg; herr_t ret_value = SUCCEED; - unsigned int i; FUNC_ENTER_NOAPI(H5O_fphdf5_reset, FAIL); @@ -389,12 +418,17 @@ H5O_fphdf5_reset(void *mesg) if (H5O_SDSPACE[0].reset) ret_value = H5O_SDSPACE[0].reset(fmeta->sdim); + fmeta->header = 0; + if (H5O_DTYPE[0].reset) ret_value = H5O_DTYPE[0].reset(fmeta->dtype); if (H5O_MTIME[0].reset) ret_value = H5O_MTIME[0].reset(fmeta->mtime); + if (H5O_LAYOUT[0].reset) + ret_value = H5O_LAYOUT[0].reset(fmeta->layout); + if (H5O_NAME[0].reset) ret_value = H5O_NAME[0].reset(fmeta->group); @@ -437,6 +471,9 @@ H5O_fphdf5_free(void *mesg) if (H5O_MTIME[0].free) ret_value = H5O_MTIME[0].free(fmeta->mtime); + if (H5O_LAYOUT[0].free) + ret_value = H5O_MTIME[0].free(fmeta->layout); + if (H5O_NAME[0].free) ret_value = H5O_NAME[0].free(fmeta->group); @@ -492,8 +529,11 @@ H5O_fphdf5_debug(H5F_t UNUSED *f, const void *mesg, HDfprintf(stream, "\n"); ret_value = H5O_SDSPACE[0].debug(f, fmeta->sdim, stream, indent + 1, fwidth); + HDfprintf(stream, "%*sHeader Address: %" H5_PRINTF_LL_WIDTH "u\n", + indent, "", (unsigned long_long)fmeta->header); ret_value = H5O_DTYPE[0].debug(f, fmeta->dtype, stream, indent + 1, fwidth); ret_value = H5O_MTIME[0].debug(f, fmeta->mtime, stream, indent + 1, fwidth); + ret_value = H5O_LAYOUT[0].debug(f, fmeta->layout, stream, indent + 1, fwidth); ret_value = H5O_NAME[0].debug(f, fmeta->group, stream, indent + 1, fwidth); ret_value = H5O_NAME[0].debug(f, fmeta->dset, stream, indent + 1, fwidth); ret_value = H5O_PLIST[0].debug(f, fmeta->plist, stream, indent + 1, fwidth); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index f1e42ef..00b9e8f 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -322,9 +322,11 @@ struct H5P_genplist_t; typedef struct H5O_fphdf5_t { uint8_t oid[H5R_OBJ_REF_BUF_SIZE]; /* OID of object */ + haddr_t header; /* Header address info */ struct H5S_simple_t *sdim; /* Simple dimensionality structure */ H5T_t *dtype; /* Datatype structure */ time_t *mtime; /* Modification time */ + H5O_layout_t *layout; /* Dataset layout */ H5O_name_t *group; /* Group name */ H5O_name_t *dset; /* Dataset name */ struct H5P_genplist_t *plist; /* Property list of the object */ @@ -336,6 +338,8 @@ typedef struct H5O_fphdf5_t { /* General message operators */ H5_DLL herr_t H5O_create(H5F_t *f, size_t size_hint, H5G_entry_t *ent/*out*/); +H5_DLL herr_t H5O_init(H5F_t *f, size_t size_hint, + H5G_entry_t *ent/*out*/, haddr_t header); H5_DLL herr_t H5O_open(H5G_entry_t *ent); H5_DLL herr_t H5O_close(H5G_entry_t *ent); H5_DLL int H5O_link(H5G_entry_t *ent, int adjust); |