summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2016-05-01 10:24:56 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2016-05-01 10:24:56 (GMT)
commita6ce3d4e45faab4691a6181a8ce6197157aea21a (patch)
tree35fa8c0766f7408609d5d55731c52d8ca84288a9 /src
parentac72823bc2a538be8365854a2d3c6f42cf1d5b62 (diff)
downloadhdf5-a6ce3d4e45faab4691a6181a8ce6197157aea21a.zip
hdf5-a6ce3d4e45faab4691a6181a8ce6197157aea21a.tar.gz
hdf5-a6ce3d4e45faab4691a6181a8ce6197157aea21a.tar.bz2
[svn-r29850] Description:
Bring H5DOappend(), H5P[s|g]et_object_flush_cb, and H5P[s|g]et_append_flush from revise_chunks branch to trunk. Brings along updated metadata cache entry tagging, and the internal object flush routine. Tested on: MacOSX/64 10.11.4 (amazon) w/serial, parallel & production (h5committest forthcoming)
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/H5AC.c132
-rw-r--r--src/H5ACprivate.h11
-rw-r--r--src/H5C.c297
-rw-r--r--src/H5Cprivate.h35
-rw-r--r--src/H5D.c38
-rw-r--r--src/H5Dint.c111
-rw-r--r--src/H5Dpkg.h1
-rw-r--r--src/H5Dprivate.h9
-rw-r--r--src/H5Dpublic.h4
-rw-r--r--src/H5Fint.c40
-rw-r--r--src/H5Fio.c45
-rw-r--r--src/H5Fpkg.h3
-rw-r--r--src/H5Fprivate.h13
-rw-r--r--src/H5Fpublic.h3
-rw-r--r--src/H5Oflush.c132
-rw-r--r--src/H5Oprivate.h3
-rw-r--r--src/H5Pdapl.c131
-rw-r--r--src/H5Pdxpl.c7
-rw-r--r--src/H5Pfapl.c95
-rw-r--r--src/H5Ppublic.h6
-rw-r--r--src/Makefile.am2
22 files changed, 946 insertions, 173 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 4e425b1..c9fb8c7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -433,6 +433,7 @@ set (H5O_SRCS
${HDF5_SRC_DIR}/H5Odtype.c
${HDF5_SRC_DIR}/H5Oefl.c
${HDF5_SRC_DIR}/H5Ofill.c
+ ${HDF5_SRC_DIR}/H5Oflush.c
${HDF5_SRC_DIR}/H5Ofsinfo.c
${HDF5_SRC_DIR}/H5Oginfo.c
${HDF5_SRC_DIR}/H5Olayout.c
diff --git a/src/H5AC.c b/src/H5AC.c
index 6a71f29..c0c6604 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -67,6 +67,9 @@ static herr_t H5AC__check_if_write_permitted(const H5F_t *f,
hbool_t *write_permitted_ptr);
static herr_t H5AC__ext_config_2_int_config(H5AC_cache_config_t *ext_conf_ptr,
H5C_auto_size_ctl_t *int_conf_ptr);
+#if H5AC_DO_TAGGING_SANITY_CHECKS
+static herr_t H5AC__verify_tag(hid_t dxpl_id, const H5AC_class_t * type);
+#endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
/*********************/
@@ -824,6 +827,11 @@ H5AC_insert_entry(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t add
flags);
#endif /* H5AC__TRACE_FILE_ENABLED */
+#if H5AC_DO_TAGGING_SANITY_CHECKS
+ if(!H5C_get_ignore_tags(f->shared->cache) && (H5AC__verify_tag(dxpl_id, type) < 0))
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Bad tag value")
+#endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
+
/* Insert entry into metadata cache */
if(H5C_insert_entry(f, dxpl_id, type, addr, thing, flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTINS, FAIL, "H5C_insert_entry() failed")
@@ -1135,8 +1143,8 @@ H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
size_t trace_entry_size = 0;
FILE * trace_file_ptr = NULL;
#endif /* H5AC__TRACE_FILE_ENABLED */
- void * thing = NULL; /* Pointer to native data structure for entry */
- void * ret_value = NULL; /* Return value */
+ void * thing = NULL; /* Pointer to native data structure for entry */
+ void * ret_value; /* Return value */
FUNC_ENTER_NOAPI(NULL)
@@ -1174,6 +1182,11 @@ H5AC_protect(H5F_t *f, hid_t dxpl_id, const H5AC_class_t *type, haddr_t addr,
(int)(type->id), flags);
#endif /* H5AC__TRACE_FILE_ENABLED */
+#if H5AC_DO_TAGGING_SANITY_CHECKS
+ if(!H5C_get_ignore_tags(f->shared->cache) && (H5AC__verify_tag(dxpl_id, type) < 0))
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, NULL, "Bad tag value")
+#endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
+
if(NULL == (thing = H5C_protect(f, dxpl_id, type, addr, udata, flags)))
HGOTO_ERROR(H5E_CACHE, H5E_CANTPROTECT, NULL, "H5C_protect() failed.")
@@ -1776,7 +1789,7 @@ H5AC_set_cache_auto_resize_config(H5AC_t *cache_ptr, H5AC_cache_config_t *config
/* Validate external configuration */
if(H5AC_validate_config(config_ptr) != SUCCEED)
- HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Bad cache configuration");
+ HGOTO_ERROR(H5E_CACHE, H5E_BADVALUE, FAIL, "Bad cache configuration")
if(config_ptr->open_trace_file) {
FILE * file_ptr;
@@ -2342,6 +2355,7 @@ done:
herr_t
H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag)
{
+ H5C_tag_t tag; /* Tag structure */
H5P_genplist_t *dxpl; /* Dataset transfer property list */
herr_t ret_value = SUCCEED; /* Return value */
@@ -2352,12 +2366,32 @@ H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag)
HGOTO_ERROR(H5E_CACHE, H5E_BADTYPE, FAIL, "not a property list")
/* Get the current tag value and return that (if prev_tag is NOT null) */
- if(prev_tag)
- if((H5P_get(dxpl, "H5AC_metadata_tag", prev_tag)) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "unable to query dxpl")
+ if(prev_tag) {
+ if((H5P_get(dxpl, "H5C_tag", &tag)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query dxpl")
+ *prev_tag = tag.value;
+ } /* end if */
- /* Set the provided tag value in the dxpl_id. */
- if(H5P_set(dxpl, "H5AC_metadata_tag", &metadata_tag) < 0)
+ /* Add metadata_tag to tag structure */
+ tag.value = metadata_tag;
+
+ /* Determine globality of tag */
+ switch(metadata_tag) {
+ case H5AC__SUPERBLOCK_TAG:
+ case H5AC__SOHM_TAG:
+ case H5AC__GLOBALHEAP_TAG:
+ tag.globality = H5C_GLOBALITY_MAJOR;
+ break;
+ case H5AC__FREESPACE_TAG:
+ tag.globality = H5C_GLOBALITY_MINOR;
+ break;
+ default:
+ tag.globality = H5C_GLOBALITY_NONE;
+ break;
+ } /* end switch */
+
+ /* Set the provided tag in the dxpl_id. */
+ if(H5P_set(dxpl, "H5C_tag", &tag) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTSET, FAIL, "can't set property in dxpl")
done:
@@ -2388,13 +2422,91 @@ H5AC_retag_copied_metadata(const H5F_t *f, haddr_t metadata_tag)
HDassert(f);
HDassert(f->shared);
- /* Call cache-level function to retag entries */
- H5C_retag_copied_metadata(f->shared->cache, metadata_tag);
+ /* Call cache-level function to re-tag entries with the COPIED tag */
+ H5C_retag_entries(f->shared->cache, H5AC__COPIED_TAG, metadata_tag);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5AC_retag_copied_metadata */
+/*------------------------------------------------------------------------------
+ * Function: H5AC_flush_tagged_metadata()
+ *
+ * Purpose: Wrapper for cache level function which flushes all metadata
+ * that contains the specific tag.
+ *
+ * Return: SUCCEED on success, FAIL otherwise.
+ *
+ * Programmer: Mike McGreevy
+ * May 19, 2010
+ *
+ *------------------------------------------------------------------------------
+ */
+herr_t
+H5AC_flush_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id)
+{
+ /* Variable Declarations */
+ herr_t ret_value = SUCCEED;
+
+ /* Function Enter Macro */
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Assertions */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Call cache level function to flush metadata entries with specified tag */
+ if(H5C_flush_tagged_entries(f, dxpl_id, metadata_tag) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Cannot flush metadata")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5AC_flush_tagged_metadata */
+
+
+#if H5AC_DO_TAGGING_SANITY_CHECKS
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5AC__verify_tag
+ *
+ * Purpose: Performs sanity checking on an entry type and tag value
+ * stored in a supplied dxpl_id.
+ *
+ * Return: SUCCEED or FAIL.
+ *
+ * Programmer: Mike McGreevy
+ * October 20, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5AC__verify_tag(hid_t dxpl_id, const H5AC_class_t *type)
+{
+ H5P_genplist_t *dxpl; /* DXPL for operation */
+ H5C_tag_t tag; /* Entry tag to validate */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Get the dataset transfer property list */
+ if(NULL == (dxpl = (H5P_genplist_t *)H5I_object_verify(dxpl_id, H5I_GENPROP_LST)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* Get the tag from the DXPL */
+ if((H5P_get(dxpl, "H5C_tag", &tag)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value")
+
+ /* Verify legal tag value */
+ if(H5C_verify_tag(type->id, tag.value, tag.globality) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, FAIL, "tag verification failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5AC__verify_tag */
+#endif /* H5AC_DO_TAGGING_SANITY_CHECKS */
+
+
/*-------------------------------------------------------------------------
* Function: H5AC_get_entry_ring
*
diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h
index 711d441..5b871ff 100644
--- a/src/H5ACprivate.h
+++ b/src/H5ACprivate.h
@@ -121,6 +121,12 @@ typedef enum {
#define H5AC__DEFAULT_MAX_CACHE_SIZE H5C__DEFAULT_MAX_CACHE_SIZE
#define H5AC__DEFAULT_MIN_CLEAN_SIZE H5C__DEFAULT_MIN_CLEAN_SIZE
+/* Check if we are sanity checking tagging */
+#if H5C_DO_TAGGING_SANITY_CHECKS
+#define H5AC_DO_TAGGING_SANITY_CHECKS 1
+#else
+#define H5AC_DO_TAGGING_SANITY_CHECKS 0
+#endif
/*
* Class methods pertaining to caching. Each type of cached object will
@@ -181,10 +187,6 @@ typedef H5C_cache_entry_t H5AC_info_t;
/* Typedef for metadata cache (defined in H5Cpkg.h) */
typedef H5C_t H5AC_t;
-#define H5AC_METADATA_TAG_NAME "H5AC_metadata_tag"
-#define H5AC_METADATA_TAG_SIZE sizeof(haddr_t)
-#define H5AC_METADATA_TAG_DEF H5AC__INVALID_TAG
-
#define H5AC_RING_NAME "H5AC_ring_type"
/* Dataset transfer property lists for metadata calls */
@@ -356,6 +358,7 @@ H5_DLL herr_t H5AC_open_trace_file(H5AC_t *cache_ptr, const char *trace_file_nam
/* Tag & Ring routines */
H5_DLL herr_t H5AC_tag(hid_t dxpl_id, haddr_t metadata_tag, haddr_t *prev_tag);
+H5_DLL herr_t H5AC_flush_tagged_metadata(H5F_t * f, haddr_t metadata_tag, hid_t dxpl_id);
H5_DLL herr_t H5AC_retag_copied_metadata(const H5F_t *f, haddr_t metadata_tag);
H5_DLL herr_t H5AC_ignore_tags(const H5F_t *f);
H5_DLL herr_t H5AC_get_entry_ring(const H5F_t *f, haddr_t addr, H5AC_ring_t *ring);
diff --git a/src/H5C.c b/src/H5C.c
index 8df9679..0082a98 100644
--- a/src/H5C.c
+++ b/src/H5C.c
@@ -166,28 +166,18 @@ static herr_t H5C_make_space_in_cache(H5F_t * f,
size_t space_needed,
hbool_t write_permitted);
-static herr_t H5C_tag_entry(H5C_t * cache_ptr,
+static herr_t H5C__tag_entry(H5C_t * cache_ptr,
H5C_cache_entry_t * entry_ptr,
hid_t dxpl_id);
-static herr_t H5C_flush_tagged_entries(H5F_t * f,
- hid_t dxpl_id,
- H5C_t * cache_ptr,
- haddr_t tag);
+static herr_t H5C__mark_tagged_entries(H5C_t * cache_ptr, haddr_t tag);
-static herr_t H5C_mark_tagged_entries(H5C_t * cache_ptr,
- haddr_t tag);
-
-static herr_t H5C_flush_marked_entries(H5F_t * f,
+static herr_t H5C__flush_marked_entries(H5F_t * f,
hid_t dxpl_id);
static herr_t H5C__generate_image(const H5F_t *f, H5C_t * cache_ptr, H5C_cache_entry_t *entry_ptr,
hid_t dxpl_id, int64_t *entry_size_change_ptr);
-#if H5C_DO_TAGGING_SANITY_CHECKS
-static herr_t H5C_verify_tag(int id, haddr_t tag);
-#endif
-
#if H5C_DO_SLIST_SANITY_CHECKS
static hbool_t H5C_entry_in_skip_list(H5C_t * cache_ptr,
H5C_cache_entry_t *target_ptr);
@@ -1848,7 +1838,7 @@ H5C_insert_entry(H5F_t * f,
entry_ptr->image_up_to_date = FALSE;
/* Apply tag to newly inserted entry */
- if(H5C_tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0)
+ if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "Cannot tag metadata entry")
entry_ptr->is_protected = FALSE;
@@ -2777,7 +2767,7 @@ H5C_protect(H5F_t * f,
#if H5C_DO_TAGGING_SANITY_CHECKS
{
- haddr_t tag = HADDR_UNDEF;
+ H5C_tag_t tag; /* Tag structure */
/* The entry is already in the cache, but make sure that the tag value
being passed in via dxpl is still legal. This will ensure that had
@@ -2786,14 +2776,14 @@ H5C_protect(H5F_t * f,
from disk. */
/* Get the tag from the DXPL */
- if((H5P_get(dxpl, "H5AC_metadata_tag", &tag)) < 0)
+ if((H5P_get(dxpl, "H5C_tag", &tag)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "unable to query property value");
/* Verify tag value */
if(cache_ptr->ignore_tags != TRUE) {
/* Verify legal tag value */
- if((H5C_verify_tag(entry_ptr->type->id, tag)) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "tag verification failed");
+ if(H5C_verify_tag(entry_ptr->type->id, tag.value, tag.globality) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTGET, NULL, "tag verification failed")
} /* end if */
}
#endif
@@ -2822,7 +2812,7 @@ H5C_protect(H5F_t * f,
#endif /* H5_HAVE_PARALLEL */
/* Apply tag to newly protected entry */
- if(H5C_tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0)
+ if(H5C__tag_entry(cache_ptr, entry_ptr, dxpl_id) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, NULL, "Cannot tag metadata entry")
/* If the entry is very large, and we are configured to allow it,
@@ -7462,7 +7452,8 @@ H5C_flush_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring, unsigned flags)
HDassert(entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
HDassert(entry_ptr->in_slist);
HDassert(entry_ptr->is_dirty);
- HDassert(entry_ptr->ring >= ring);
+ if(!flush_marked_entries || entry_ptr->flush_marker)
+ HDassert(entry_ptr->ring >= ring);
/* increment node pointer now, before we delete its target
* from the slist.
@@ -7476,7 +7467,8 @@ H5C_flush_ring(H5F_t *f, hid_t dxpl_id, H5C_ring_t ring, unsigned flags)
HDassert(next_entry_ptr->magic == H5C__H5C_CACHE_ENTRY_T_MAGIC);
HDassert(next_entry_ptr->is_dirty);
HDassert(next_entry_ptr->in_slist);
- HDassert(next_entry_ptr->ring >= ring);
+ if(!flush_marked_entries || next_entry_ptr->flush_marker)
+ HDassert(next_entry_ptr->ring >= ring);
HDassert(entry_ptr != next_entry_ptr);
} /* end if */
else
@@ -8481,8 +8473,8 @@ H5C_load_entry(H5F_t * f,
entry->addr = addr;
entry->size = len;
HDassert(entry->size < H5C_MAX_ENTRY_SIZE);
- entry->compressed = compressed;
- entry->compressed_size = compressed_size;
+ entry->compressed = compressed;
+ entry->compressed_size = compressed_size;
entry->image_ptr = image;
entry->image_up_to_date = TRUE;
entry->type = type;
@@ -9565,7 +9557,34 @@ H5C_ignore_tags(H5C_t * cache_ptr)
/*-------------------------------------------------------------------------
*
- * Function: H5C_tag_entry
+ * Function: H5C_get_ignore_tags
+ *
+ * Purpose: Retrieve the 'ignore_tags' field for the cache
+ *
+ * Return: 'ignore_tags' value (can't fail)
+ *
+ * Programmer: Quincey Koziol
+ * April 30, 2016
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5C_get_ignore_tags(const H5C_t *cache_ptr)
+{
+ FUNC_ENTER_NOAPI_NOERR
+
+ /* Sanity checks */
+ HDassert(cache_ptr);
+ HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
+
+ /* Return ignore tag value */
+ FUNC_LEAVE_NOAPI(cache_ptr->ignore_tags)
+} /* H5C_get_ignore_tags */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5C__tag_entry
*
* Purpose: Tags an entry with the provided tag (contained in the dxpl_id).
* If sanity checking is enabled, this function will perform
@@ -9582,13 +9601,13 @@ H5C_ignore_tags(H5C_t * cache_ptr)
*-------------------------------------------------------------------------
*/
static herr_t
-H5C_tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr, hid_t dxpl_id)
+H5C__tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr, hid_t dxpl_id)
{
H5P_genplist_t *dxpl; /* dataset transfer property list */
- haddr_t tag; /* Tag address */
+ H5C_tag_t tag; /* Tag structure */
herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(FAIL)
+ FUNC_ENTER_STATIC
/* Assertions */
HDassert(cache_ptr != NULL);
@@ -9600,13 +9619,13 @@ H5C_tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr, hid_t dxpl_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
/* Get the tag from the DXPL */
- if((H5P_get(dxpl, "H5AC_metadata_tag", &tag)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value")
+ if((H5P_get(dxpl, "H5C_tag", &tag)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to query property value")
if(cache_ptr->ignore_tags != TRUE) {
#if H5C_DO_TAGGING_SANITY_CHECKS
/* Perform some sanity checks to ensure that a correct tag is being applied */
- if(H5C_verify_tag(entry_ptr->type->id, tag) < 0)
+ if(H5C_verify_tag(entry_ptr->type->id, tag.value, tag.globality) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "tag verification failed")
#endif
} else {
@@ -9617,70 +9636,30 @@ H5C_tag_entry(H5C_t * cache_ptr, H5C_cache_entry_t * entry_ptr, hid_t dxpl_id)
arbitrarily set it to something for the sake of passing the tests.
If the tag value is set, then we'll just let it get assigned without
additional checking for correctness. */
- if(!tag)
- tag = H5AC__IGNORE_TAG;
+ if(!tag.value) {
+ tag.value = H5AC__IGNORE_TAG;
+ tag.globality = H5C_GLOBALITY_NONE;
+ } /* end if */
} /* end if */
/* Apply the tag to the entry */
- entry_ptr->tag = tag;
+ entry_ptr->tag = tag.value;
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C_tag_entry */
-
-
-/*-------------------------------------------------------------------------
- *
- * Function: H5C_flush_tagged_entries
- *
- * WARNING: Not yet tested or used anywhere. (written awhile ago,
- * will keep it around in anticipation of being used in
- * subsequent changes to support flushing individual objects).
- *
- * Purpose: Flushes all entries with the specified tag to disk.
- *
- * Return: FAIL if error is detected, SUCCEED otherwise.
- *
- * Programmer: Mike McGreevy
- * August 19, 2010
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5C_flush_tagged_entries(H5F_t * f, hid_t dxpl_id, H5C_t * cache_ptr, haddr_t tag)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(FAIL)
-
- /* Assertions */
- HDassert(0); /* This function is not yet used. We shouldn't be in here yet. */
- HDassert(cache_ptr != NULL);
- HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
-
- /* Mark all entries with specified tag */
- if(H5C_mark_tagged_entries(cache_ptr, tag) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries")
-
- /* Flush all marked entries */
- if(H5C_flush_marked_entries(f, dxpl_id) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush marked entries")
+ /* Apply the tag globality to the entry */
+ entry_ptr->globality = tag.globality;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C_flush_tagged_entries */
+} /* H5C__tag_entry */
+
/*-------------------------------------------------------------------------
*
- * Function: H5C_mark_tagged_entries
+ * Function: H5C__mark_tagged_entries
*
- * WARNING: Not yet tested or used anywhere. (written awhile ago,
- * will keep it around in anticipation of being used in
- * subsequent changes to support flushing individual objects).
- *
- * Purpose: Set the flush marker on entries in the cache that have
- * the specified tag.
+ * Purpose: Set the flush marker on dirty entries in the cache that have
+ * the specified tag, as well as all globally tagged entries.
*
* Return: FAIL if error is detected, SUCCEED otherwise.
*
@@ -9690,41 +9669,42 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5C_mark_tagged_entries(H5C_t * cache_ptr, haddr_t tag)
+H5C__mark_tagged_entries(H5C_t * cache_ptr, haddr_t tag)
{
- H5C_cache_entry_t *next_entry_ptr; /* entry pointer */
- unsigned u; /* Local index variable */
+ unsigned u; /* Local index variable */
- FUNC_ENTER_NOAPI_NOINIT_NOERR
+ FUNC_ENTER_STATIC
- /* Assertions */
- HDassert(0); /* This function is not yet used. We shouldn't be in here yet. */
- HDassert(cache_ptr != NULL);
+ /* Sanity check */
+ HDassert(cache_ptr);
HDassert(cache_ptr->magic == H5C__H5C_T_MAGIC);
- /* Iterate through entries, marking those with specified tag. */
+ /* Iterate through hash table entries, marking those with specified tag, as
+ * well as any major global entries which should always be flushed
+ * when flushing based on tag value */
for(u = 0; u < H5C__HASH_TABLE_LEN; u++) {
-
- next_entry_ptr = cache_ptr->index[u];
- while(next_entry_ptr != NULL) {
- if(next_entry_ptr->tag == tag)
- next_entry_ptr->flush_marker = TRUE;
-
- next_entry_ptr = next_entry_ptr->ht_next;
- } /* end while */
- } /* for */
+ H5C_cache_entry_t *entry_ptr; /* Entry pointer */
+
+ entry_ptr = cache_ptr->index[u];
+ while(entry_ptr != NULL) {
+ if((entry_ptr->tag == tag) || (entry_ptr->globality == H5C_GLOBALITY_MAJOR)) {
+ /* We only want to set the flush marker on entries that
+ * actually need flushed (i.e., dirty ones) */
+ if(entry_ptr->is_dirty)
+ entry_ptr->flush_marker = TRUE;
+ } /* end if */
+
+ entry_ptr = entry_ptr->ht_next;
+ } /* end while */
+ } /* end for */
FUNC_LEAVE_NOAPI(SUCCEED)
-} /* H5C_mark_tagged_entries */
+} /* H5C__mark_tagged_entries */
/*-------------------------------------------------------------------------
*
- * Function: H5C_flush_marked_entries
- *
- * WARNING: Not yet tested or used anywhere. (written awhile ago,
- * will keep it around in anticipation of being used in
- * subsequent changes to support flushing individual objects).
+ * Function: H5C__flush_marked_entries
*
* Purpose: Flushes all marked entries in the cache.
*
@@ -9736,14 +9716,13 @@ H5C_mark_tagged_entries(H5C_t * cache_ptr, haddr_t tag)
*-------------------------------------------------------------------------
*/
static herr_t
-H5C_flush_marked_entries(H5F_t * f, hid_t dxpl_id)
+H5C__flush_marked_entries(H5F_t * f, hid_t dxpl_id)
{
herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT
+ FUNC_ENTER_STATIC
/* Assertions */
- HDassert(0); /* This function is not yet used. We shouldn't be in here yet. */
HDassert(f != NULL);
/* Flush all marked entries */
@@ -9752,7 +9731,7 @@ H5C_flush_marked_entries(H5F_t * f, hid_t dxpl_id)
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* H5C_flush_marked_entries */
+} /* H5C__flush_marked_entries */
#if H5C_DO_TAGGING_SANITY_CHECKS
@@ -9769,8 +9748,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5C_verify_tag(int id, haddr_t tag)
+herr_t
+H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality)
{
herr_t ret_value = SUCCEED;
@@ -9784,7 +9763,6 @@ H5C_verify_tag(int id, haddr_t tag)
else if(tag == H5AC__INVALID_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "no metadata tag provided")
else {
-
/* Perform some sanity checks on tag value. Certain entry
* types require certain tag values, so check that these
* constraints are met. */
@@ -9793,37 +9771,45 @@ H5C_verify_tag(int id, haddr_t tag)
if((id == H5AC_SUPERBLOCK_ID) || (id == H5AC_DRVRINFO_ID)) {
if(tag != H5AC__SUPERBLOCK_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "superblock not tagged with H5AC__SUPERBLOCK_TAG")
- }
+ if(globality != H5C_GLOBALITY_MAJOR)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "superblock/driver-info globality not marked with H5C_GLOBALITY_MAJOR")
+ } /* end if */
else {
if(tag == H5AC__SUPERBLOCK_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "H5AC__SUPERBLOCK_TAG applied to non-superblock entry")
- }
+ } /* end else */
/* Free Space Manager */
if((id == H5AC_FSPACE_HDR_ID) || (id == H5AC_FSPACE_SINFO_ID)) {
if(tag != H5AC__FREESPACE_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "freespace entry not tagged with H5AC__FREESPACE_TAG")
- }
+ if(globality != H5C_GLOBALITY_MINOR)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "freespace entry globality not marked with H5C_GLOBALITY_MINOR")
+ } /* end if */
else {
if(tag == H5AC__FREESPACE_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "H5AC__FREESPACE_TAG applied to non-freespace entry")
- }
+ } /* end else */
/* SOHM */
if((id == H5AC_SOHM_TABLE_ID) || (id == H5AC_SOHM_LIST_ID)) {
if(tag != H5AC__SOHM_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "sohm entry not tagged with H5AC__SOHM_TAG")
- }
+ if(globality != H5C_GLOBALITY_MAJOR)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "sohm entry globality not marked with H5C_GLOBALITY_MAJOR")
+ } /* end if */
/* Global Heap */
if(id == H5AC_GHEAP_ID) {
if(tag != H5AC__GLOBALHEAP_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "global heap not tagged with H5AC__GLOBALHEAP_TAG")
- }
+ if(globality != H5C_GLOBALITY_MAJOR)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "global heap entry globality not marked with H5C_GLOBALITY_MAJOR")
+ } /* end if */
else {
if(tag == H5AC__GLOBALHEAP_TAG)
HGOTO_ERROR(H5E_CACHE, H5E_CANTTAG, FAIL, "H5AC__GLOBALHEAP_TAG applied to non-globalheap entry")
- }
+ } /* end else */
} /* end else */
done:
@@ -9834,11 +9820,53 @@ done:
/*-------------------------------------------------------------------------
*
- * Function: H5C_retag_copied_metadata
+ * Function: H5C_flush_tagged_entries
+ *
+ * Purpose: Flushes all entries with the specified tag to disk.
+ *
+ * Return: FAIL if error is detected, SUCCEED otherwise.
+ *
+ * Programmer: Mike McGreevy
+ * August 19, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5C_flush_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag)
+{
+ /* Variable Declarations */
+ H5C_t *cache_ptr = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Assertions */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Get cache pointer */
+ cache_ptr = f->shared->cache;
+
+ /* Mark all entries with specified tag */
+ if(H5C__mark_tagged_entries(cache_ptr, tag) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't mark tagged entries")
+
+ /* Flush all marked entries */
+ if(H5C__flush_marked_entries(f, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "Can't flush marked entries")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5C_flush_tagged_entries */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5C_retag_entries
*
* Purpose: Searches through cache index for all entries with the
- * H5AC__COPIED_TAG, indicating that it was created as a
- * result of an object copy, and applies the provided tag.
+ * value specified by src_tag and changes it to the value
+ * specified by dest_tag.
*
* Return: SUCCEED or FAIL.
*
@@ -9848,30 +9876,29 @@ done:
*-------------------------------------------------------------------------
*/
void
-H5C_retag_copied_metadata(H5C_t * cache_ptr, haddr_t metadata_tag)
+H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag)
{
unsigned u; /* Local index variable */
FUNC_ENTER_NOAPI_NOINIT_NOERR
+ /* Sanity check */
HDassert(cache_ptr);
- /* Iterate through entries, retagging those with the H5AC__COPIED_TAG tag */
+ /* Iterate through entries, retagging those with the src_tag tag */
for(u = 0; u < H5C__HASH_TABLE_LEN; u++) {
- H5C_cache_entry_t *next_entry_ptr; /* entry pointer */
-
- next_entry_ptr = cache_ptr->index[u];
- while(next_entry_ptr != NULL) {
- if(cache_ptr->index[u] != NULL)
- if((cache_ptr->index[u])->tag == H5AC__COPIED_TAG)
- (cache_ptr->index[u])->tag = metadata_tag;
-
- next_entry_ptr = next_entry_ptr->ht_next;
- } /* end while */
+ H5C_cache_entry_t *entry_ptr; /* entry pointer */
+
+ entry_ptr = cache_ptr->index[u];
+ while(entry_ptr) {
+ if(entry_ptr->tag == src_tag)
+ entry_ptr->tag = dest_tag;
+ entry_ptr = entry_ptr->ht_next;
+ } /* end while */
} /* end for */
FUNC_LEAVE_NOAPI_VOID
-} /* H5C_retag_copied_metadata */
+} /* H5C_retag_entries */
/*-------------------------------------------------------------------------
diff --git a/src/H5Cprivate.h b/src/H5Cprivate.h
index a062214..d43c845 100644
--- a/src/H5Cprivate.h
+++ b/src/H5Cprivate.h
@@ -205,12 +205,17 @@
#define H5C__FLUSH_MARKED_ENTRIES_FLAG 0x0080
#define H5C__FLUSH_IGNORE_PROTECTED_FLAG 0x0100
#define H5C__READ_ONLY_FLAG 0x0200
-#define H5C__FREE_FILE_SPACE_FLAG 0x0800
-#define H5C__TAKE_OWNERSHIP_FLAG 0x1000
-#define H5C__FLUSH_LAST_FLAG 0x2000
-#define H5C__FLUSH_COLLECTIVELY_FLAG 0x4000
+#define H5C__FREE_FILE_SPACE_FLAG 0x0400
+#define H5C__TAKE_OWNERSHIP_FLAG 0x0800
+#define H5C__FLUSH_LAST_FLAG 0x1000
+#define H5C__FLUSH_COLLECTIVELY_FLAG 0x2000
#define H5C__DEL_FROM_SLIST_ON_DESTROY_FLAG 0x8000
+/* Definitions for cache "tag" property */
+#define H5C_TAG_NAME "H5C_tag"
+#define H5C_TAG_SIZE sizeof(H5C_tag_t)
+#define H5C_TAG_DEF {(haddr_t)0, H5C_GLOBALITY_NONE}
+
/* Debugging/sanity checking/statistics settings */
#ifndef NDEBUG
#define H5C_DO_SANITY_CHECKS 1
@@ -268,8 +273,20 @@
/* Typedef for the main structure for the cache (defined in H5Cpkg.h) */
typedef struct H5C_t H5C_t;
+/* Define enum for cache entry tag 'globality' value */
+typedef enum {
+ H5C_GLOBALITY_NONE=0, /* Non-global tag */
+ H5C_GLOBALITY_MINOR, /* global, not flushed during single object flush */
+ H5C_GLOBALITY_MAJOR /* global, needs flushed during single obect flush */
+} H5C_tag_globality_t;
+
+/* Cache entry tag structure */
+typedef struct H5C_tag_t {
+ haddr_t value;
+ H5C_tag_globality_t globality;
+} H5C_tag_t;
-/***************************************************************************
+/*
*
* Struct H5C_class_t
*
@@ -1596,6 +1613,7 @@ typedef struct H5C_cache_entry_t {
hbool_t image_up_to_date;
const H5C_class_t * type;
haddr_t tag;
+ H5C_tag_globality_t globality;
hbool_t is_dirty;
hbool_t dirtied;
hbool_t is_protected;
@@ -1951,6 +1969,10 @@ H5_DLL herr_t H5C_dest(H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5C_expunge_entry(H5F_t *f, hid_t dxpl_id,
const H5C_class_t *type, haddr_t addr, unsigned flags);
H5_DLL herr_t H5C_flush_cache(H5F_t *f, hid_t dxpl_id, unsigned flags);
+H5_DLL herr_t H5C_flush_tagged_entries(H5F_t * f, hid_t dxpl_id, haddr_t tag);
+#if H5C_DO_TAGGING_SANITY_CHECKS
+herr_t H5C_verify_tag(int id, haddr_t tag, H5C_tag_globality_t globality);
+#endif
H5_DLL herr_t H5C_flush_to_min_clean(H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5C_get_cache_auto_resize_config(const H5C_t *cache_ptr,
H5C_auto_size_ctl_t *config_ptr);
@@ -1992,7 +2014,8 @@ H5_DLL herr_t H5C_unprotect(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *thing,
H5_DLL herr_t H5C_validate_resize_config(H5C_auto_size_ctl_t *config_ptr,
unsigned int tests);
H5_DLL herr_t H5C_ignore_tags(H5C_t *cache_ptr);
-H5_DLL void H5C_retag_copied_metadata(H5C_t *cache_ptr, haddr_t metadata_tag);
+H5_DLL hbool_t H5C_get_ignore_tags(const H5C_t *cache_ptr);
+H5_DLL void H5C_retag_entries(H5C_t * cache_ptr, haddr_t src_tag, haddr_t dest_tag);
H5_DLL herr_t H5C_get_entry_ring(const H5F_t *f, haddr_t addr, H5C_ring_t *ring);
#ifdef H5_HAVE_PARALLEL
diff --git a/src/H5D.c b/src/H5D.c
index 5ef2e37..beb7cfe 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -917,3 +917,41 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Dset_extent() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Dflush
+ *
+ * Purpose: Flushes all buffers associated with a dataset.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Mike McGreevy
+ * May 19, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Dflush(hid_t dset_id)
+{
+ H5D_t *dset; /* Dataset for this operation */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE1("e", "i", dset_id);
+
+ /* Check args */
+ if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
+
+ /* Flush any dataset information still cached in memory */
+ if(H5D__flush_real(dset, H5AC_ind_read_dxpl_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to flush cached dataset info")
+
+ /* Flush object's metadata to file */
+ if(H5O_flush_common(&dset->oloc, dset_id, H5AC_ind_read_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFLUSH, FAIL, "unable to flush dataset and object flush callback")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Dflush */
+
diff --git a/src/H5Dint.c b/src/H5Dint.c
index 0355656..a5d214e 100644
--- a/src/H5Dint.c
+++ b/src/H5Dint.c
@@ -68,7 +68,7 @@ static herr_t H5D_build_extfile_prefix(const H5D_t *dset, hid_t dapl_id,
static herr_t H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id);
static herr_t H5D__init_storage(const H5D_io_info_t *io_info, hbool_t full_overwrite,
hsize_t old_dim[]);
-
+static herr_t H5D__append_flush_setup(H5D_t *dset, hid_t dapl_id);
/*********************/
/* Package Variables */
@@ -1247,6 +1247,10 @@ H5D__create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id,
/* Indicate that the layout information was initialized */
layout_init = TRUE;
+ /* Set up append flush parameters for the dataset */
+ if(H5D__append_flush_setup(new_dset, dapl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to set up flush append property")
+
/* Set the external file prefix */
if(H5D_build_extfile_prefix(new_dset, dapl_id, &new_dset->shared->extfile_prefix) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize external file prefix")
@@ -1491,6 +1495,85 @@ done:
} /* end H5D_open() */
+/*
+ *-------------------------------------------------------------------------
+ * Function: H5D__flush_append_setup
+ *
+ * Purpose: Set the append flush parameters for a dataset
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi
+ * Wednesday, January 8, 2014
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5D__append_flush_setup(H5D_t *dset, hid_t dapl_id)
+{
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Check args */
+ HDassert(dset);
+ HDassert(dset->shared);
+
+ /* Set default append flush values */
+ HDmemset(&dset->shared->append_flush, 0, sizeof(dset->shared->append_flush));
+
+ /* If the dataset is chunked and there is a non-default DAPL */
+ if(dapl_id != H5P_DATASET_ACCESS_DEFAULT && dset->shared->layout.type == H5D_CHUNKED) {
+ H5P_genplist_t *dapl; /* data access property list object pointer */
+
+ /* Get dataset access property list */
+ if(NULL == (dapl = (H5P_genplist_t *)H5I_object(dapl_id)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for dapl ID");
+
+ /* Check if append flush property exists */
+ if(H5P_exist_plist(dapl, H5D_ACS_APPEND_FLUSH_NAME) > 0) {
+ H5D_append_flush_t info;
+
+ /* Get append flush property */
+ if(H5P_get(dapl, H5D_ACS_APPEND_FLUSH_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get append flush info")
+ if(info.ndims > 0) {
+ hsize_t curr_dims[H5S_MAX_RANK]; /* current dimension sizes */
+ hsize_t max_dims[H5S_MAX_RANK]; /* current dimension sizes */
+ int rank; /* dataspace # of dimensions */
+ unsigned u; /* local index variable */
+
+ /* Get dataset rank */
+ if((rank = H5S_get_simple_extent_dims(dset->shared->space, curr_dims, max_dims)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get dataset dimensions")
+ if(info.ndims != (unsigned)rank)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "boundary dimension rank does not match dataset rank")
+
+ /* Validate boundary sizes */
+ for(u = 0; u < info.ndims; u++)
+ if(info.boundary[u] != 0) /* when a non-zero boundary is set */
+ /* the dimension is extendible? */
+ if(max_dims[u] != H5S_UNLIMITED && max_dims[u] == curr_dims[u])
+ break;
+
+ /* At least one boundary dimension is not extendible */
+ if(u != info.ndims)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADVALUE, FAIL, "boundary dimension is not valid")
+
+ /* Copy append flush settings */
+ dset->shared->append_flush.ndims = info.ndims;
+ dset->shared->append_flush.func = info.func;
+ dset->shared->append_flush.udata = info.udata;
+ HDmemcpy(dset->shared->append_flush.boundary, info.boundary, sizeof(info.boundary));
+ } /* end if */
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5D__append_flush_setup() */
+
+
/*-------------------------------------------------------------------------
* Function: H5D__open_oid
*
@@ -1555,6 +1638,10 @@ H5D__open_oid(H5D_t *dataset, hid_t dapl_id, hid_t dxpl_id)
/* Indicate that the layout information was initialized */
layout_init = TRUE;
+ /* Set up flush append property */
+ if(H5D__append_flush_setup(dataset, dapl_id))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to set up flush append property")
+
/* Point at dataset's copy, to cache it for later */
fill_prop = &dataset->shared->dcpl_cache.fill;
@@ -3083,28 +3170,28 @@ H5D_get_access_plist(H5D_t *dset)
FUNC_ENTER_NOAPI_NOINIT
/* Make a copy of the default dataset access property list */
- if (NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_DATASET_ACCESS_ID_g)))
+ if(NULL == (old_plist = (H5P_genplist_t *)H5I_object(H5P_LST_DATASET_ACCESS_ID_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
- if ((new_dapl_id = H5P_copy_plist(old_plist, TRUE)) < 0)
+ if((new_dapl_id = H5P_copy_plist(old_plist, TRUE)) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "can't copy dataset access property list")
- if (NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_dapl_id)))
+ if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_dapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
- /* If the dataset is chunked then copy the rdcc parameters */
- if (dset->shared->layout.type == H5D_CHUNKED) {
- if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(dset->shared->cache.chunk.nslots)) < 0)
+ /* If the dataset is chunked then copy the rdcc & append flush parameters */
+ if(dset->shared->layout.type == H5D_CHUNKED) {
+ if(H5P_set(new_plist, H5D_ACS_DATA_CACHE_NUM_SLOTS_NAME, &(dset->shared->cache.chunk.nslots)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache number of slots")
- if (H5P_set(new_plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(dset->shared->cache.chunk.nbytes_max)) < 0)
+ if(H5P_set(new_plist, H5D_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(dset->shared->cache.chunk.nbytes_max)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache byte size")
- if (H5P_set(new_plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &(dset->shared->cache.chunk.w0)) < 0)
+ if(H5P_set(new_plist, H5D_ACS_PREEMPT_READ_CHUNKS_NAME, &(dset->shared->cache.chunk.w0)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set preempt read chunks")
+ if(H5P_set(new_plist, H5D_ACS_APPEND_FLUSH_NAME, &dset->shared->append_flush) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set append flush property")
} /* end if */
- /* Set the VDS view option */
+ /* Set the VDS view & printf gap options */
if(H5P_set(new_plist, H5D_ACS_VDS_VIEW_NAME, &(dset->shared->layout.storage.u.virt.view)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set VDS view")
-
- /* Set the VDS printf gap option */
if(H5P_set(new_plist, H5D_ACS_VDS_PRINTF_GAP_NAME, &(dset->shared->layout.storage.u.virt.printf_gap)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set VDS printf gap")
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index f582367..c0b8b28 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -465,6 +465,7 @@ typedef struct H5D_shared_t {
H5D_rdcc_t chunk; /* Information about chunked data */
} cache;
+ H5D_append_flush_t append_flush; /* Append flush property information */
char *extfile_prefix; /* expanded external file prefix */
} H5D_shared_t;
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index ab60a50..d1468dd 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -54,6 +54,7 @@
#define H5D_ACS_PREEMPT_READ_CHUNKS_NAME "rdcc_w0" /* Preemption read chunks first */
#define H5D_ACS_VDS_VIEW_NAME "vds_view" /* VDS view option */
#define H5D_ACS_VDS_PRINTF_GAP_NAME "vds_printf_gap" /* VDS printf gap size */
+#define H5D_ACS_APPEND_FLUSH_NAME "append_flush" /* Append flush actions */
#define H5D_ACS_EFILE_PREFIX_NAME "external file prefix" /* External file prefix */
/* ======== Data transfer properties ======== */
@@ -151,6 +152,14 @@ typedef struct H5D_copy_file_ud_t {
H5T_t *src_dtype; /* Copy of datatype for dataset */
} H5D_copy_file_ud_t;
+/* Structure for dataset append flush property (H5Pset_append_flush) */
+typedef struct H5D_append_flush_t {
+ unsigned ndims; /* The # of dimensions for "boundary" */
+ hsize_t boundary[H5S_MAX_RANK]; /* The dimension sizes for determining boundary */
+ H5D_append_cb_t func; /* The callback function */
+ void *udata; /* User data */
+} H5D_append_flush_t;
+
/*****************************/
/* Library Private Variables */
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index 0b6540c..e1555b9 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -109,6 +109,9 @@ typedef enum H5D_vds_view_t {
H5D_VDS_LAST_AVAILABLE = 1
} H5D_vds_view_t;
+/* Callback for H5Pset_append_flush() in a dataset access property list */
+typedef herr_t (*H5D_append_cb_t)(hid_t dataset_id, hsize_t *cur_dims, void *op_data);
+
/********************/
/* Public Variables */
/********************/
@@ -157,6 +160,7 @@ H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_
H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
hid_t buf_type, hid_t space);
H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t size[]);
+H5_DLL herr_t H5Dflush(hid_t dset_id);
H5_DLL herr_t H5Dscatter(H5D_scatter_func_t op, void *op_data, hid_t type_id,
hid_t dst_space_id, void *dst_buf);
H5_DLL herr_t H5Dgather(hid_t src_space_id, const void *src_buf, hid_t type_id,
diff --git a/src/H5Fint.c b/src/H5Fint.c
index f4e6550..9ca472d 100644
--- a/src/H5Fint.c
+++ b/src/H5Fint.c
@@ -171,6 +171,9 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
latest_format = TRUE;
if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &latest_format) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag")
+ if(H5P_set(new_plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set object flush callback")
+
if(f->shared->efc)
efc_size = H5F_efc_max_nfiles(f->shared->efc);
if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0)
@@ -679,6 +682,10 @@ H5F_new(H5F_file_t *shared, unsigned flags, hid_t fcpl_id, hid_t fapl_id, H5FD_t
*/
f->shared->use_tmp_space = !H5F_HAS_FEATURE(f, H5FD_FEAT_HAS_MPI);
+ /* Get object flush callback information */
+ if(H5P_get(plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &(f->shared->object_flush)) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTGET, NULL, "can't get object flush cb info")
+
/*
* Create a metadata cache with the specified number of elements.
* The cache might be created with a different number of elements and
@@ -2070,6 +2077,39 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5F_object_flush_cb
+ *
+ * Purpose: To invoke the callback function for object flush that is set
+ * in the file's access property list.
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Vailin Choi; October 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_object_flush_cb(H5F_t *f, hid_t obj_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared);
+
+ /* Invoke object flush callback if there is one */
+ if(f->shared->object_flush.func && f->shared->object_flush.func(obj_id, f->shared->object_flush.udata) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "object flush callback returns error")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5F_object_flush_cb() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F__set_base_addr
*
* Purpose: Quick and dirty routine to set the file's 'base_addr' value
diff --git a/src/H5Fio.c b/src/H5Fio.c
index d001bc0..1fb3459 100644
--- a/src/H5Fio.c
+++ b/src/H5Fio.c
@@ -199,3 +199,48 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_block_write() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_flush_tagged_metadata
+ *
+ * Purpose: Flushes metadata with specified tag in the metadata cache
+ * to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Mike McGreevy
+ * September 9, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_flush_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id)
+{
+ H5F_io_info_t fio_info; /* I/O info for operation */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Use tag to search for and flush associated metadata */
+ if(H5AC_flush_tagged_metadata(f, tag, dxpl_id)<0)
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata")
+
+ /* Set up I/O info for operation */
+ fio_info.f = f;
+
+ if(NULL == (fio_info.dxpl = (H5P_genplist_t *)H5I_object(dxpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
+
+
+ /* Flush and reset the accumulator */
+ if(H5F__accum_reset(&fio_info, TRUE) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTRESET, FAIL, "can't reset accumulator")
+
+ /* Flush file buffers to disk. */
+ if(H5FD_flush(f->shared->lf, dxpl_id, FALSE) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "low level flush failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5F_flush_tagged_metadata */
+
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 06f0207..e2874d1 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -293,6 +293,9 @@ struct H5F_file_t {
/* Metadata accumulator information */
H5F_meta_accum_t accum; /* Metadata accumulator info */
+
+ /* Object flush info */
+ H5F_object_flush_t object_flush; /* Information for object flush callback */
};
/*
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 05c70d1..93965e0 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -459,6 +459,7 @@
#define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */
#define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */
#define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */
+#define H5F_ACS_OBJECT_FLUSH_CB_NAME "object_flush_cb" /* Object flush callback */
#define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */
#define H5F_ACS_FILE_IMAGE_INFO_NAME "file_image_info" /* struct containing initial file image and callback info */
#define H5F_ACS_CORE_WRITE_TRACKING_FLAG_NAME "core_write_tracking_flag" /* Whether or not core VFD backing store write tracking is enabled */
@@ -591,6 +592,12 @@ typedef struct H5F_file_t H5F_file_t;
/* Block aggregation structure */
typedef struct H5F_blk_aggr_t H5F_blk_aggr_t;
+/* Structure for object flush callback property (H5Pset_object_flush_cb)*/
+typedef struct H5F_object_flush_t {
+ H5F_flush_cb_t func; /* The callback function */
+ void *udata; /* User data */
+} H5F_object_flush_t;
+
/* I/O Info for an operation */
typedef struct H5F_io_info_t {
const H5F_t *f; /* File object */
@@ -688,6 +695,12 @@ H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr,
H5_DLL herr_t H5F_block_write(const H5F_t *f, H5FD_mem_t type, haddr_t addr,
size_t size, hid_t dxpl_id, const void *buf);
+/* Functions that flush or evict */
+H5_DLL herr_t H5F_flush_tagged_metadata(H5F_t * f, haddr_t tag, hid_t dxpl_id);
+
+/* Routine to invoke callback function upon object flush */
+H5_DLL herr_t H5F_object_flush_cb(H5F_t *f, hid_t obj_id);
+
/* Address-related functions */
H5_DLL void H5F_addr_encode(const H5F_t *f, uint8_t **pp, haddr_t addr);
H5_DLL void H5F_addr_encode_len(size_t addr_len, uint8_t **pp, haddr_t addr);
diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h
index eba9b12..6fa18e1 100644
--- a/src/H5Fpublic.h
+++ b/src/H5Fpublic.h
@@ -175,6 +175,9 @@ typedef enum H5F_file_space_type_t {
H5F_FILE_SPACE_NTYPES /* must be last */
} H5F_file_space_type_t;
+/* Callback for H5Pset_object_flush_cb() in a file access property list */
+typedef herr_t (*H5F_flush_cb_t)(hid_t object_id, void *udata);
+
#ifdef __cplusplus
extern "C" {
diff --git a/src/H5Oflush.c b/src/H5Oflush.c
new file mode 100644
index 0000000..0bec096
--- /dev/null
+++ b/src/H5Oflush.c
@@ -0,0 +1,132 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Oflush.c
+ * Aug 19, 2010
+ * Mike McGreevy <mamcgree@hdfgroup.org>
+ *
+ * Purpose: Object flush/refresh routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#include "H5Omodule.h" /* This source code file is part of the H5O module */
+
+/***********/
+/* Headers */
+/***********/
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Errors */
+#include "H5Fprivate.h" /* Files */
+#include "H5Gprivate.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Opkg.h" /* Objects */
+
+/********************/
+/* Local Prototypes */
+/********************/
+static herr_t H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag);
+
+/*************/
+/* Functions */
+/*************/
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_flush_common
+ *
+ * Purpose: Flushes the object's metadata
+ * Invokes the user-defined callback if there is one.
+ *
+ * Return: Non-negative on success, negative on failure
+ *
+ * Programmer: Vailin Choi; Dec 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id, hid_t dxpl_id)
+{
+ haddr_t tag = 0;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Retrieve tag for object */
+ if(H5O_oh_tag(oloc, dxpl_id, &tag) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object metadata")
+
+ /* Flush metadata based on tag value of the object */
+ if(H5F_flush_tagged_metadata(oloc->file, tag, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTFLUSH, FAIL, "unable to flush tagged metadata")
+
+ /* Check to invoke callback */
+ if(H5F_object_flush_cb(oloc->file, obj_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to do object flush callback")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_flush_common() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_oh_tag
+ *
+ * Purpose: Get object header's address--tag value for the object
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mike McGreevy
+ * May 19, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_oh_tag(const H5O_loc_t *oloc, hid_t dxpl_id, haddr_t *tag)
+{
+ H5O_t *oh = NULL; /* Object header */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(oloc);
+
+ /* Get object header for object */
+ if(NULL == (oh = H5O_protect(oloc, dxpl_id, H5AC__READ_ONLY_FLAG)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPROTECT, FAIL, "unable to protect object's object header")
+
+ /* Get object header's address (i.e. the tag value for this object) */
+ if(HADDR_UNDEF == (*tag = H5O_OH_GET_ADDR(oh)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to get address of object header")
+
+done:
+ /* Unprotect object header on failure */
+ if(oh && H5O_unprotect(oloc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTUNPROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_oh_tag() */
+
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 17ab665..9ad8662 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -902,6 +902,9 @@ H5_DLL int H5O_msg_get_chunkno(const H5O_loc_t *loc, unsigned type_id, hid_t dxp
H5_DLL herr_t H5O_msg_lock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
H5_DLL herr_t H5O_msg_unlock(const H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
+/* Object metadata flush/refresh routines */
+H5_DLL herr_t H5O_flush_common(H5O_loc_t *oloc, hid_t obj_id, hid_t dxpl_id);
+
/* Object copying routines */
H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */,
hid_t dxpl_id, H5O_copy_t *cpy_info, hbool_t inc_depth,
diff --git a/src/H5Pdapl.c b/src/H5Pdapl.c
index 6407d4c..aa58dc4 100644
--- a/src/H5Pdapl.c
+++ b/src/H5Pdapl.c
@@ -73,6 +73,9 @@
#define H5D_ACS_VDS_PRINTF_GAP_DEF (hsize_t)0
#define H5D_ACS_VDS_PRINTF_GAP_ENC H5P__encode_hsize_t
#define H5D_ACS_VDS_PRINTF_GAP_DEC H5P__decode_hsize_t
+/* Definition for append flush */
+#define H5D_ACS_APPEND_FLUSH_SIZE sizeof(H5D_append_flush_t)
+#define H5D_ACS_APPEND_FLUSH_DEF {0,{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},NULL,NULL}
/* Definitions for external file prefix */
#define H5D_ACS_EFILE_PREFIX_SIZE sizeof(char *)
#define H5D_ACS_EFILE_PREFIX_DEF NULL /*default is no prefix */
@@ -157,9 +160,9 @@ const H5P_libclass_t H5P_CLS_DACC[1] = {{
/*******************/
/* Property value defaults */
+static const H5D_append_flush_t H5D_def_append_flush_g = H5D_ACS_APPEND_FLUSH_DEF; /* Default setting for append flush */
static const char *H5D_def_efile_prefix_g = H5D_ACS_EFILE_PREFIX_DEF; /* Default external file prefix string */
-
/*-------------------------------------------------------------------------
* Function: H5P__dacc_reg_prop
@@ -212,6 +215,12 @@ H5P__dacc_reg_prop(H5P_genclass_t *pclass)
NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register info for append flush */
+ /* (Note: this property should not have an encode/decode callback -QAK) */
+ if(H5P_register_real(pclass, H5D_ACS_APPEND_FLUSH_NAME, H5D_ACS_APPEND_FLUSH_SIZE, &H5D_def_append_flush_g,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
/* Register property for external file prefix */
if(H5P_register_real(pclass, H5D_ACS_EFILE_PREFIX_NAME, H5D_ACS_EFILE_PREFIX_SIZE, &H5D_def_efile_prefix_g,
NULL, H5D_ACS_EFILE_PREFIX_SET, H5D_ACS_EFILE_PREFIX_GET, H5D_ACS_EFILE_PREFIX_ENC, H5D_ACS_EFILE_PREFIX_DEC,
@@ -1076,6 +1085,125 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Pset_append_flush
+ *
+ * Purpose: Sets the boundary, callback function, and user data in the
+ * property list.
+ * "ndims": number of array elements for boundary
+ * "boundary": used to determine whether the current dimension hits
+ * a boundary; if so, invoke the callback function and
+ * flush the dataset.
+ * "func": the callback function to invoke when the boundary is hit
+ * "udata": the user data to pass as parameter with the callback function
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Dec 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_append_flush(hid_t plist_id, unsigned ndims, const hsize_t *boundary, H5D_append_cb_t func, void *udata)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5D_append_flush_t info; /* Property for append flush parameters */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "iIu*hx*x", plist_id, ndims, boundary, func, udata);
+
+ /* Check arguments */
+ if(0 == ndims)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality cannot be zero")
+ if(ndims > H5S_MAX_RANK)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality is too large")
+ if(!boundary)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no boundary dimensions specified")
+
+ /* Check if the callback function is NULL and the user data is non-NULL.
+ * This is almost certainly an error as the user data will not be used. */
+ if(!func && udata)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Set up values */
+ info.ndims = ndims;
+ info.func = func;
+ info.udata = udata;
+
+ HDmemset(info.boundary, 0, sizeof(info.boundary));
+ /* boundary can be 0 to indicate no boundary is set */
+ for(u = 0; u < ndims; u++) {
+ if(boundary[u] != (boundary[u] & 0xffffffff)) /* negative value (including H5S_UNLIMITED) */
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "all boundary dimensions must be less than 2^32")
+ info.boundary[u] = boundary[u]; /* Store user's boundary dimensions */
+ } /* end for */
+
+ /* Set values */
+ if(H5P_set(plist, H5D_ACS_APPEND_FLUSH_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set append flush")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pset_append_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_append_flush()
+ *
+ * Purpose: Retrieves the boundary, callback function and user data set in
+ * property list.
+ * Note that the # of boundary sizes to retrieve will not exceed
+ * the parameter "ndims" and the ndims set previously via
+ * H5Pset_append_flush().
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Dec 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_append_flush(hid_t plist_id, unsigned ndims, hsize_t boundary[], H5D_append_cb_t *func, void **udata)
+{
+ H5P_genplist_t *plist; /* property list pointer */
+ H5D_append_flush_t info;
+ unsigned u; /* local index variable */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE5("e", "iIu*h*x**x", plist_id, ndims, boundary, func, udata);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_DATASET_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Retrieve info for append flush */
+ if(H5P_get(plist, H5D_ACS_APPEND_FLUSH_NAME, &info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object flush callback")
+
+ /* Assign return values */
+ if(boundary) {
+ HDmemset(boundary, 0, ndims * sizeof(hsize_t));
+ if(info.ndims > 0)
+ for(u = 0; u < info.ndims && u < ndims; u++)
+ boundary[u] = info.boundary[u];
+ } /* end if */
+ if(func)
+ *func = info.func;
+ if(udata)
+ *udata = info.udata;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pget_append_flush() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5Pset_efile_prefix
*
* Purpose: Set a prefix to be used for any external files.
@@ -1165,3 +1293,4 @@ H5Pget_efile_prefix(hid_t plist_id, char *prefix, size_t size)
done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_efile_prefix() */
+
diff --git a/src/H5Pdxpl.c b/src/H5Pdxpl.c
index 9353094..e685c65 100644
--- a/src/H5Pdxpl.c
+++ b/src/H5Pdxpl.c
@@ -273,7 +273,7 @@ static const void *H5D_def_vlen_alloc_info_g = H5D_XFER_VLEN_ALLOC_INFO_DEF; /
static const H5MM_free_t H5D_def_vlen_free_g = H5D_XFER_VLEN_FREE_DEF; /* Default value for vlen free function */
static const void *H5D_def_vlen_free_info_g = H5D_XFER_VLEN_FREE_INFO_DEF; /* Default value for vlen free information */
static const size_t H5D_def_hyp_vec_size_g = H5D_XFER_HYPER_VECTOR_SIZE_DEF; /* Default value for vector size */
-static const haddr_t H5D_def_metadata_tag_g = H5AC_METADATA_TAG_DEF; /* Default value for metadata tag */
+static const H5C_tag_t H5D_def_tag_g = H5C_TAG_DEF; /* Default value for cache entry tag */
static const H5FD_mpio_xfer_t H5D_def_io_xfer_mode_g = H5D_XFER_IO_XFER_MODE_DEF; /* Default value for I/O transfer mode */
static const H5FD_mpio_chunk_opt_t H5D_def_mpio_chunk_opt_mode_g = H5D_XFER_MPIO_CHUNK_OPT_HARD_DEF;
static const H5FD_mpio_collective_opt_t H5D_def_mpio_collective_opt_mode_g = H5D_XFER_MPIO_COLLECTIVE_OPT_DEF;
@@ -325,9 +325,8 @@ H5P__dxfr_reg_prop(H5P_genclass_t *pclass)
NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
- /* Register the metadata tag property */
- /* (Note: this property should not have an encode/decode callback -QAK) */
- if(H5P_register_real(pclass, H5AC_METADATA_TAG_NAME, H5AC_METADATA_TAG_SIZE, &H5D_def_metadata_tag_g,
+ /* Register the cache tag property */
+ if(H5P_register_real(pclass, H5C_TAG_NAME, H5C_TAG_SIZE, &H5D_def_tag_g,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c
index 1fbc3b8..a315f92 100644
--- a/src/H5Pfapl.c
+++ b/src/H5Pfapl.c
@@ -178,6 +178,9 @@
#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEF 524288
#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_ENC H5P__encode_size_t
#define H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEC H5P__decode_size_t
+/* Definition for object flush callback */
+#define H5F_ACS_OBJECT_FLUSH_CB_SIZE sizeof(H5F_object_flush_t)
+#define H5F_ACS_OBJECT_FLUSH_CB_DEF {NULL, NULL}
#ifdef H5_HAVE_PARALLEL
/* Definition of collective metadata read mode flag */
#define H5F_ACS_COLL_MD_READ_FLAG_SIZE sizeof(H5P_coll_md_read_flag_t)
@@ -292,6 +295,7 @@ static const unsigned H5F_def_efc_size_g = H5F_ACS_EFC_SIZE_DEF;
static const H5FD_file_image_info_t H5F_def_file_image_info_g = H5F_ACS_FILE_IMAGE_INFO_DEF; /* Default file image info and callbacks */
static const hbool_t H5F_def_core_write_tracking_flag_g = H5F_ACS_CORE_WRITE_TRACKING_FLAG_DEF; /* Default setting for core VFD write tracking */
static const size_t H5F_def_core_write_tracking_page_size_g = H5F_ACS_CORE_WRITE_TRACKING_PAGE_SIZE_DEF; /* Default core VFD write tracking page size */
+static const H5F_object_flush_t H5F_def_object_flush_cb_g = H5F_ACS_OBJECT_FLUSH_CB_DEF; /* Default setting for object flush callback */
#ifdef H5_HAVE_PARALLEL
static const H5P_coll_md_read_flag_t H5F_def_coll_md_read_flag_g = H5F_ACS_COLL_MD_READ_FLAG_DEF; /* Default setting for the collective metedata read flag */
static const hbool_t H5F_def_coll_md_write_flag_g = H5F_ACS_COLL_MD_WRITE_FLAG_DEF; /* Default setting for the collective metedata write flag */
@@ -452,6 +456,12 @@ H5P__facc_reg_prop(H5P_genclass_t *pclass)
NULL, NULL, NULL, NULL) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+ /* Register object flush callback */
+ /* (Note: this property should not have an encode/decode callback -QAK) */
+ if(H5P_register_real(pclass, H5F_ACS_OBJECT_FLUSH_CB_NAME, H5F_ACS_OBJECT_FLUSH_CB_SIZE, &H5F_def_object_flush_cb_g,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
+
#ifdef H5_HAVE_PARALLEL
/* Register the metadata collective read flag */
if(H5P_register_real(pclass, H5_COLL_MD_READ_FLAG_NAME, H5F_ACS_COLL_MD_READ_FLAG_SIZE, &H5F_def_coll_md_read_flag_g,
@@ -3510,6 +3520,91 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_core_write_tracking() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_obj_flush_cb
+ *
+ * Purpose: Sets the callback function to invoke and the user data when an
+ * object flush occurs in the file.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Dec 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5F_object_flush_t flush_info;
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "ix*x", plist_id, func, udata);
+
+ /* Check if the callback function is NULL and the user data is non-NULL.
+ * This is almost certainly an error as the user data will not be used. */
+ if(!func && udata)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Update property list */
+ flush_info.func = func;
+ flush_info.udata = udata;
+
+ /* Set values */
+ if(H5P_set(plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &flush_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set object flush callback")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pset_obj_flush_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_obj_flush_cb
+ *
+ * Purpose: Retrieves the callback function and user data set in the
+ * property list for an object flush.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Vailin Choi; Dec 2013
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5F_object_flush_t flush_info;
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(FAIL)
+ H5TRACE3("e", "i*x**x", plist_id, func, udata);
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Retrieve the callback function and user data */
+ if(H5P_get(plist, H5F_ACS_OBJECT_FLUSH_CB_NAME, &flush_info) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object flush callback")
+
+ /* Assign return value */
+ if(func)
+ *func = flush_info.func;
+ if(udata)
+ *udata = flush_info.udata;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* H5Pget_obj_flush_cb() */
+
#ifdef H5_HAVE_PARALLEL
/*-------------------------------------------------------------------------
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 67727ce..0318c8f 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -351,6 +351,8 @@ H5_DLL herr_t H5Pget_file_image_callbacks(hid_t fapl_id,
H5FD_file_image_callbacks_t *callbacks_ptr);
H5_DLL herr_t H5Pset_core_write_tracking(hid_t fapl_id, hbool_t is_enabled, size_t page_size);
H5_DLL herr_t H5Pget_core_write_tracking(hid_t fapl_id, hbool_t *is_enabled, size_t *page_size);
+H5_DLL herr_t H5Pset_object_flush_cb(hid_t plist_id, H5F_flush_cb_t func, void *udata);
+H5_DLL herr_t H5Pget_object_flush_cb(hid_t plist_id, H5F_flush_cb_t *func, void **udata);
#ifdef H5_HAVE_PARALLEL
H5_DLL herr_t H5Pset_all_coll_metadata_ops(hid_t plist_id, hbool_t is_collective);
H5_DLL herr_t H5Pget_all_coll_metadata_ops(hid_t plist_id, hbool_t *is_collective);
@@ -408,6 +410,10 @@ H5_DLL herr_t H5Pset_virtual_view(hid_t plist_id, H5D_vds_view_t view);
H5_DLL herr_t H5Pget_virtual_view(hid_t plist_id, H5D_vds_view_t *view);
H5_DLL herr_t H5Pset_virtual_printf_gap(hid_t plist_id, hsize_t gap_size);
H5_DLL herr_t H5Pget_virtual_printf_gap(hid_t plist_id, hsize_t *gap_size);
+H5_DLL herr_t H5Pset_append_flush(hid_t plist_id, unsigned ndims,
+ const hsize_t boundary[], H5D_append_cb_t func, void *udata);
+H5_DLL herr_t H5Pget_append_flush(hid_t plist_id, unsigned dims,
+ hsize_t boundary[], H5D_append_cb_t *func, void **udata);
H5_DLL herr_t H5Pset_efile_prefix(hid_t dapl_id, const char* prefix);
H5_DLL ssize_t H5Pget_efile_prefix(hid_t dapl_id, char* prefix /*out*/, size_t size);
diff --git a/src/Makefile.am b/src/Makefile.am
index 5d72fc5..81fec77 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -81,7 +81,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \
H5O.c H5Oainfo.c H5Oalloc.c H5Oattr.c \
H5Oattribute.c H5Obogus.c H5Obtreek.c H5Ocache.c H5Ochunk.c \
H5Ocont.c H5Ocopy.c H5Odbg.c H5Odrvinfo.c H5Odtype.c H5Oefl.c \
- H5Ofill.c H5Ofsinfo.c H5Oginfo.c \
+ H5Ofill.c H5Oflush.c H5Ofsinfo.c H5Oginfo.c \
H5Olayout.c \
H5Olinfo.c H5Olink.c H5Omessage.c H5Omtime.c \
H5Oname.c H5Onull.c H5Opline.c H5Orefcount.c \