From 01b3ee75cfca4a32f631d882076ffdd3cd03923b Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 5 Nov 2002 12:55:27 -0500 Subject: [svn-r6057] Purpose: New Feature. Support for new FPHDF5 Feature Description: More support for the FPHDF5 feature. This splits the H5D_create function into separate parts which update the metadata cache. It was necessary to split apart the H5O_create function to do a similar thing since it would allocate real space on the hard disk. I'm checking this up now so that I don't get too far away from what the CVS repository has and so that others may look at the code and retch^H^H^H^H^Hmarvel at it. If there are any comments, send them my way. There is one outstanding issue, though. I need to use non-API functions in the FPHDF5 stuff. I'm using some APIs right now and should migrate to using others. At the moment, I'm putting that on the back burner until I'm more along in the implementation. Platforms tested: Arabica (C++) Eirene (Parallel) Modi4 (Parallel) --- src/H5D.c | 343 +++++++++++++++++++++++++++++++++++++++---------------- src/H5Dprivate.h | 9 ++ src/H5FPclient.c | 12 -- src/H5FPserver.c | 12 -- src/H5Fprivate.h | 2 +- src/H5O.c | 103 +++++++++++++---- src/H5Ofphdf5.c | 54 +++++++-- src/H5Oprivate.h | 4 + 8 files changed, 385 insertions(+), 154 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; ient), 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) || \ diff --git a/src/H5O.c b/src/H5O.c index 001e998..7817b55 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -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); -- cgit v0.12