From b8632ce735eeae4d65fa27866155a26d19c7e035 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 11 Jun 2003 22:40:34 -0500 Subject: [svn-r7029] Purpose: New feature/Bug fix Description: Add new fill time value - H5D_FILL_TIME_IFSET which writes the fill value to a dataset if the user has defined one, otherwise not writing the fill value to the dataset. Platforms tested: FreeBSD 4.8 (sleipnir) serial & parallel h5committest --- src/H5.c | 3 +++ src/H5D.c | 72 +++++++++++++++++++++++++++++++++++++--------------- src/H5Distore.c | 76 +++++++++++++++++++++++++++++++++++++++---------------- src/H5Dprivate.h | 2 +- src/H5Dpublic.h | 3 ++- src/H5Fistore.c | 76 +++++++++++++++++++++++++++++++++++++++---------------- src/H5Pdcpl.c | 4 +++ test/extend.c | 3 +-- test/set_extent.c | 2 ++ test/tmisc.c | 4 +++ 10 files changed, 177 insertions(+), 68 deletions(-) diff --git a/src/H5.c b/src/H5.c index 0b92dfd..95dfea9 100644 --- a/src/H5.c +++ b/src/H5.c @@ -1632,6 +1632,9 @@ H5_trace (double *returning, const char *func, const char *type, ...) case H5D_FILL_TIME_NEVER: fprintf (out, "H5D_FILL_TIME_NEVER"); break; + case H5D_FILL_TIME_IFSET: + fprintf (out, "H5D_FILL_TIME_IFSET"); + break; } } break; diff --git a/src/H5D.c b/src/H5D.c index 6ded25d..b4bedff 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -1387,9 +1387,6 @@ H5D_update_entry_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, H5P_genplist_t *p HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time"); dset->fill_time=fill_time; /* Cache this for later */ - if(fill_time==H5D_FILL_TIME_NEVER && H5T_detect_class(type, H5T_VLEN)) - HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Dataset doesn't support VL datatype when fill value is not defined"); - /* Get the fill value information from the property list */ if (H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value"); @@ -1398,6 +1395,17 @@ H5D_update_entry_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, H5P_genplist_t *p if (H5P_is_fill_value_defined(fill_prop, &fill_status) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined"); + /* Special case handling for variable-length types */ + if(H5T_detect_class(type, H5T_VLEN)) { + /* If the default fill value is chosen for variable-length types, always write it */ + if(fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_DEFAULT) + dset->fill_time=fill_time=H5D_FILL_TIME_ALLOC; + + /* Don't allow never writing fill values with variable-length types */ + if(fill_time==H5D_FILL_TIME_NEVER) + HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "Dataset doesn't support VL datatype when fill value is not defined"); + } /* end if */ + if (fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED) { if (H5O_copy(H5O_FILL_ID, fill_prop, &fill) == NULL) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to copy fill value"); @@ -1417,7 +1425,7 @@ H5D_update_entry_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, H5P_genplist_t *p fill.alloc_time = alloc_time; fill.fill_time = fill_time; - if (fill.fill_defined == FALSE && fill_time != H5D_FILL_TIME_NEVER) + if (fill.fill_defined == FALSE && fill_time == H5D_FILL_TIME_ALLOC) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT,FAIL, "unable to create dataset"); /* Write new fill value message */ @@ -2457,8 +2465,8 @@ H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_allo } /* end if */ /* If space allocation is set to 'early' and we are extending - * the dataset, indicate that space was allocated, so the - * B-tree gets expanded. -QAK + * the dataset, indicate that space should be allocated, so the + * B-tree gets expanded. -QAK */ if(dset->alloc_time==H5D_ALLOC_TIME_EARLY && time_alloc==H5D_ALLOC_EXTEND) init_space=1; @@ -2487,22 +2495,46 @@ H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_allo HGOTO_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL, "unsupported storage layout"); } /* end switch */ - /* Check if we actually allocated space before performing other actions */ - if(init_space || addr_set) { - /* If we are filling the dataset on allocation, do that now */ - if(dset->fill_time==H5D_FILL_TIME_ALLOC - && !(dset->alloc_time==H5D_ALLOC_TIME_INCR && time_alloc==H5D_ALLOC_WRITE)) { - if(H5D_init_storage(dset, full_overwrite, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value"); + /* Check if we need to initialize the space */ + if(init_space) { + if (layout->type==H5D_CHUNKED) { + /* If we are doing incremental allocation and the B-tree got + * created during a H5Dwrite call, don't initialize the storage + * now, wait for the actual writes to each block and let the + * low-level chunking routines handle initialize the fill-values. + * Otherwise, pass along the space initialization call and let + * the low-level chunking routines sort out whether to write + * fill values to the chunks they allocate space for. Yes, + * this is icky. -QAK + */ + if(!(dset->alloc_time==H5D_ALLOC_TIME_INCR && time_alloc==H5D_ALLOC_WRITE)) { + if(H5D_init_storage(dset, full_overwrite, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value"); + } /* end if */ } /* end if */ - - /* Also update header message for layout with new address, if we - * set the address. (this is mainly for forward compatibility). - */ - if(time_alloc!=H5D_ALLOC_CREATE && addr_set) - if (H5O_modify (&(dset->ent), H5O_LAYOUT_ID, 0, H5O_FLAG_CONSTANT, update_time, &(dset->layout), dxpl_id) < 0) - HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message"); + else { + H5D_fill_value_t fill_status; /* The fill value status */ + + /* Check the dataset's fill-value status */ + if (H5P_is_fill_value_defined(&(dset->fill), &fill_status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined"); + + /* If we are filling the dataset on allocation or "if set" and + * the fill value _is_ set, do that now */ + if(dset->fill_time==H5D_FILL_TIME_ALLOC || + (dset->fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED)) { + if(H5D_init_storage(dset, full_overwrite, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value"); + } /* end if */ + } /* end else */ } /* end if */ + + /* Also update header message for layout with new address, if we + * set the address. (this is improves forward compatibility). + */ + if(time_alloc!=H5D_ALLOC_CREATE && addr_set) + if (H5O_modify (&(dset->ent), H5O_LAYOUT_ID, 0, H5O_FLAG_CONSTANT, update_time, &(dset->layout), dxpl_id) < 0) + HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message"); } /* end if */ done: diff --git a/src/H5Distore.c b/src/H5Distore.c index baeac20..2f9f3b0 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1348,9 +1348,9 @@ done: */ static void * H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, - const H5O_pline_t *pline, const H5O_fill_t *fill, - const hssize_t offset[], hbool_t relax, - unsigned *idx_hint/*in,out*/) + const H5O_pline_t *pline, const H5O_fill_t *fill, H5D_fill_time_t fill_time, + const hssize_t offset[], hbool_t relax, + unsigned *idx_hint/*in,out*/) { int idx=0; /*hash index number */ hsize_t temp_idx=0; /* temporary index number */ @@ -1458,24 +1458,33 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, } rdcc->nmisses++; } else { + H5D_fill_value_t fill_status; + /* Chunk size on disk isn't [likely] the same size as the final chunk * size in memory, so allocate memory big enough. */ if (NULL==(chunk = H5MM_malloc (chunk_size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk"); - if (fill && fill->buf) { - /* - * The chunk doesn't exist in the file. Replicate the fill - * value throughout the chunk. - */ - assert(0==chunk_size % fill->size); - H5V_array_fill(chunk, fill->buf, fill->size, chunk_size/fill->size); - } else { - /* - * The chunk doesn't exist in the file and no fill value was - * specified. Assume all zeros. - */ - HDmemset (chunk, 0, chunk_size); - } + + if (H5P_is_fill_value_defined(fill, &fill_status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't tell if fill value defined"); + + if(fill_time==H5D_FILL_TIME_ALLOC || + (fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED)) { + if (fill && fill->buf) { + /* + * The chunk doesn't exist in the file. Replicate the fill + * value throughout the chunk. + */ + assert(0==chunk_size % fill->size); + H5V_array_fill(chunk, fill->buf, fill->size, chunk_size/fill->size); + } else { + /* + * The chunk doesn't exist in the file and no fill value was + * specified. Assume all zeros. + */ + HDmemset (chunk, 0, chunk_size); + } /* end else */ + } /* end if */ rdcc->ninits++; } /* end else */ } @@ -1771,18 +1780,21 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a else { uint8_t *chunk; /* Pointer to cached chunk in memory */ H5O_fill_t fill; /* Fill value information */ + H5D_fill_time_t fill_time; /* Fill time information */ unsigned idx_hint=0; /* Cache index hint */ ssize_t naccessed; /* Number of bytes accessed in chunk */ /* Get necessary properties from property list */ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill time"); /* * Lock the chunk, copy from application to chunk, then unlock the * chunk. */ - if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, fill_time, chunk_coords_in_elmts, FALSE, &idx_hint))) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk"); @@ -1902,6 +1914,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a else { uint8_t *chunk; /* Pointer to cached chunk in memory */ H5O_fill_t fill; /* Fill value information */ + H5D_fill_time_t fill_time; /* Fill time information */ unsigned idx_hint=0; /* Cache index hint */ ssize_t naccessed; /* Number of bytes accessed in chunk */ hbool_t relax; /* Whether whole chunk is selected */ @@ -1909,6 +1922,8 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a /* Get necessary properties from property list */ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill time"); /* * Lock the chunk, copy from application to chunk, then unlock the @@ -1919,7 +1934,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a else relax = FALSE; - if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, fill_time, chunk_coords_in_elmts, relax, &idx_hint))) HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); @@ -2131,6 +2146,8 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, H5O_pline_t pline; /* I/O pipeline information */ H5O_fill_t fill; /* Fill value information */ H5D_fill_time_t fill_time; /* When to write fill values */ + H5D_fill_value_t fill_status; /* The fill value status */ + unsigned should_fill=0; /* Whether fill values should be written */ H5F_istore_ud1_t udata; /* B-tree pass-through for creating chunk */ void *chunk=NULL; /* Chunk buffer for writing fill values */ H5P_genplist_t *dx_plist; /* Data xfer property list */ @@ -2239,8 +2256,20 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, chunk_size *= layout->dim[u]; } /* end for */ + /* Check the dataset's fill-value status */ + if (H5P_is_fill_value_defined(&fill, &fill_status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined"); + + /* If we are filling the dataset on allocation or "if set" and + * the fill value _is_ set, _and_ we are not overwriting the new blocks, + * set the "should fill" flag + */ + if(!full_overwrite && (fill_time==H5D_FILL_TIME_ALLOC || + (fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED))) + should_fill=1; + /* Check if fill values should be written to blocks */ - if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) { + if(should_fill) { /* Allocate chunk buffer for processes to use when writing fill values */ H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t); if (NULL==(chunk = H5MM_malloc((size_t)chunk_size))) @@ -2318,7 +2347,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk"); /* Check if fill values should be written to blocks */ - if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) { + if(should_fill) { #ifdef H5_HAVE_PARALLEL /* Check if this file is accessed with an MPI-capable file driver */ if(using_mpi) { @@ -2709,6 +2738,7 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay int found = 0; /*initialize this entry */ H5O_pline_t pline; /* I/O pipeline information */ H5O_fill_t fill; /* Fill value information */ + H5D_fill_time_t fill_time; /* Fill time information */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5F_istore_initialize_by_extent, FAIL); @@ -2723,6 +2753,8 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay /* Get necessary properties from property list */ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill time"); if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline"); @@ -2780,7 +2812,7 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay if(found) { - if(NULL == (chunk = H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, + if(NULL == (chunk = H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, fill_time, chunk_offset, FALSE, &idx_hint))) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index f2bc489..b1615b0 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -59,7 +59,7 @@ /* Definitions for time of fill value writing */ #define H5D_CRT_FILL_TIME_NAME "fill_time" #define H5D_CRT_FILL_TIME_SIZE sizeof(H5D_fill_time_t) -#define H5D_CRT_FILL_TIME_DEF H5D_FILL_TIME_ALLOC +#define H5D_CRT_FILL_TIME_DEF H5D_FILL_TIME_IFSET /* Definitions for external file list */ #define H5D_CRT_EXT_FILE_LIST_NAME "efl" #define H5D_CRT_EXT_FILE_LIST_SIZE sizeof(H5O_efl_t) diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index c0a23cb..5987b79 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -53,7 +53,8 @@ typedef enum H5D_space_status_t { typedef enum H5D_fill_time_t { H5D_FILL_TIME_ERROR =-1, H5D_FILL_TIME_ALLOC =0, - H5D_FILL_TIME_NEVER =1 + H5D_FILL_TIME_NEVER =1, + H5D_FILL_TIME_IFSET =2 } H5D_fill_time_t; /* Values for fill value status */ diff --git a/src/H5Fistore.c b/src/H5Fistore.c index baeac20..2f9f3b0 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -1348,9 +1348,9 @@ done: */ static void * H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, - const H5O_pline_t *pline, const H5O_fill_t *fill, - const hssize_t offset[], hbool_t relax, - unsigned *idx_hint/*in,out*/) + const H5O_pline_t *pline, const H5O_fill_t *fill, H5D_fill_time_t fill_time, + const hssize_t offset[], hbool_t relax, + unsigned *idx_hint/*in,out*/) { int idx=0; /*hash index number */ hsize_t temp_idx=0; /* temporary index number */ @@ -1458,24 +1458,33 @@ H5F_istore_lock(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, } rdcc->nmisses++; } else { + H5D_fill_value_t fill_status; + /* Chunk size on disk isn't [likely] the same size as the final chunk * size in memory, so allocate memory big enough. */ if (NULL==(chunk = H5MM_malloc (chunk_size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk"); - if (fill && fill->buf) { - /* - * The chunk doesn't exist in the file. Replicate the fill - * value throughout the chunk. - */ - assert(0==chunk_size % fill->size); - H5V_array_fill(chunk, fill->buf, fill->size, chunk_size/fill->size); - } else { - /* - * The chunk doesn't exist in the file and no fill value was - * specified. Assume all zeros. - */ - HDmemset (chunk, 0, chunk_size); - } + + if (H5P_is_fill_value_defined(fill, &fill_status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't tell if fill value defined"); + + if(fill_time==H5D_FILL_TIME_ALLOC || + (fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED)) { + if (fill && fill->buf) { + /* + * The chunk doesn't exist in the file. Replicate the fill + * value throughout the chunk. + */ + assert(0==chunk_size % fill->size); + H5V_array_fill(chunk, fill->buf, fill->size, chunk_size/fill->size); + } else { + /* + * The chunk doesn't exist in the file and no fill value was + * specified. Assume all zeros. + */ + HDmemset (chunk, 0, chunk_size); + } /* end else */ + } /* end if */ rdcc->ninits++; } /* end else */ } @@ -1771,18 +1780,21 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a else { uint8_t *chunk; /* Pointer to cached chunk in memory */ H5O_fill_t fill; /* Fill value information */ + H5D_fill_time_t fill_time; /* Fill time information */ unsigned idx_hint=0; /* Cache index hint */ ssize_t naccessed; /* Number of bytes accessed in chunk */ /* Get necessary properties from property list */ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill time"); /* * Lock the chunk, copy from application to chunk, then unlock the * chunk. */ - if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, fill_time, chunk_coords_in_elmts, FALSE, &idx_hint))) HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "unable to read raw data chunk"); @@ -1902,6 +1914,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a else { uint8_t *chunk; /* Pointer to cached chunk in memory */ H5O_fill_t fill; /* Fill value information */ + H5D_fill_time_t fill_time; /* Fill time information */ unsigned idx_hint=0; /* Cache index hint */ ssize_t naccessed; /* Number of bytes accessed in chunk */ hbool_t relax; /* Whether whole chunk is selected */ @@ -1909,6 +1922,8 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a /* Get necessary properties from property list */ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill time"); /* * Lock the chunk, copy from application to chunk, then unlock the @@ -1919,7 +1934,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a else relax = FALSE; - if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, + if (NULL==(chunk=H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, fill_time, chunk_coords_in_elmts, relax, &idx_hint))) HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); @@ -2131,6 +2146,8 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, H5O_pline_t pline; /* I/O pipeline information */ H5O_fill_t fill; /* Fill value information */ H5D_fill_time_t fill_time; /* When to write fill values */ + H5D_fill_value_t fill_status; /* The fill value status */ + unsigned should_fill=0; /* Whether fill values should be written */ H5F_istore_ud1_t udata; /* B-tree pass-through for creating chunk */ void *chunk=NULL; /* Chunk buffer for writing fill values */ H5P_genplist_t *dx_plist; /* Data xfer property list */ @@ -2239,8 +2256,20 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, chunk_size *= layout->dim[u]; } /* end for */ + /* Check the dataset's fill-value status */ + if (H5P_is_fill_value_defined(&fill, &fill_status) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't tell if fill value defined"); + + /* If we are filling the dataset on allocation or "if set" and + * the fill value _is_ set, _and_ we are not overwriting the new blocks, + * set the "should fill" flag + */ + if(!full_overwrite && (fill_time==H5D_FILL_TIME_ALLOC || + (fill_time==H5D_FILL_TIME_IFSET && fill_status==H5D_FILL_VALUE_USER_DEFINED))) + should_fill=1; + /* Check if fill values should be written to blocks */ - if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) { + if(should_fill) { /* Allocate chunk buffer for processes to use when writing fill values */ H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t); if (NULL==(chunk = H5MM_malloc((size_t)chunk_size))) @@ -2318,7 +2347,7 @@ H5F_istore_allocate(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout, HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk"); /* Check if fill values should be written to blocks */ - if(fill_time != H5D_FILL_TIME_NEVER && !full_overwrite) { + if(should_fill) { #ifdef H5_HAVE_PARALLEL /* Check if this file is accessed with an MPI-capable file driver */ if(using_mpi) { @@ -2709,6 +2738,7 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay int found = 0; /*initialize this entry */ H5O_pline_t pline; /* I/O pipeline information */ H5O_fill_t fill; /* Fill value information */ + H5D_fill_time_t fill_time; /* Fill time information */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5F_istore_initialize_by_extent, FAIL); @@ -2723,6 +2753,8 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay /* Get necessary properties from property list */ if(H5P_get(dc_plist, H5D_CRT_FILL_VALUE_NAME, &fill) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill value"); + if(H5P_get(dc_plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get fill time"); if(H5P_get(dc_plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get data pipeline"); @@ -2780,7 +2812,7 @@ H5F_istore_initialize_by_extent(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *lay if(found) { - if(NULL == (chunk = H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, + if(NULL == (chunk = H5F_istore_lock(f, dxpl_id, layout, &pline, &fill, fill_time, chunk_offset, FALSE, &idx_hint))) HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to read raw data chunk"); diff --git a/src/H5Pdcpl.c b/src/H5Pdcpl.c index 2c9a377..7da0afc 100644 --- a/src/H5Pdcpl.c +++ b/src/H5Pdcpl.c @@ -1532,6 +1532,10 @@ H5Pset_fill_time(hid_t plist_id, H5D_fill_time_t fill_time) FUNC_ENTER_API(H5Pset_fill_time, FAIL); H5TRACE2("e","iDf",plist_id,fill_time); + /* Check arguments */ + if(fill_timeH5D_FILL_TIME_IFSET) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid fill time setting"); + /* Get the property list structure */ if(NULL == (plist = H5P_object_verify(plist_id,H5P_DATASET_CREATE))) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID"); diff --git a/test/extend.c b/test/extend.c index 23625fd..07c8dba 100644 --- a/test/extend.c +++ b/test/extend.c @@ -48,7 +48,7 @@ static int buf1[NY][NX], buf2[NX/2][NY/2]; * *------------------------------------------------------------------------- */ -int +static int write_data(const char *msg, hid_t file, const char *name, hid_t cparms, hid_t mem_space) { hid_t dataset, file_space, half_space; @@ -105,7 +105,6 @@ write_data(const char *msg, hid_t file, const char *name, hid_t cparms, hid_t me for (k=0; k