summaryrefslogtreecommitdiffstats
path: root/src/H5F.c
diff options
context:
space:
mode:
authorNeil Fortner <nfortne2@hdfgroup.org>2011-02-08 17:32:56 (GMT)
committerNeil Fortner <nfortne2@hdfgroup.org>2011-02-08 17:32:56 (GMT)
commit0863d303729a1008b5954984adffa8223997fc2f (patch)
treecc273980f8c4a225cdde2100698b5300c2e060d2 /src/H5F.c
parentf3ee1cc38d0604116afbffe72cd98dabfe1014a7 (diff)
downloadhdf5-0863d303729a1008b5954984adffa8223997fc2f.zip
hdf5-0863d303729a1008b5954984adffa8223997fc2f.tar.gz
hdf5-0863d303729a1008b5954984adffa8223997fc2f.tar.bz2
[svn-r20064] Purpose: Implement external file cache
Description: Implements a cache of files opened through external links. Adds the public functions H5Pset_elink_file_cache_size(), H5Pget_elink_file_cache_size(), and H5Frelease_file_cache(). Tested: jam, amani, heiwa (h5committest), fedora 64.
Diffstat (limited to 'src/H5F.c')
-rw-r--r--src/H5F.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 46d9407..f84dea2 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -292,6 +292,7 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
H5P_genplist_t *new_plist; /* New property list */
H5P_genplist_t *old_plist; /* Old property list */
void *driver_info=NULL;
+ unsigned efc_size = 0;
hid_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5F_get_access_plist, FAIL)
@@ -330,6 +331,10 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size")
if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag")
+ 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)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set elink file cache size")
/*
* Since we're resetting the driver ID and info, close them if they
@@ -840,6 +845,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
} /* end if */
else {
H5P_genplist_t *plist; /* Property list */
+ unsigned efc_size; /* External file cache size */
size_t u; /* Local index variable */
HDassert(lf != NULL);
@@ -902,6 +908,11 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size")
f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA;
+ if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get elink file cache size")
+ if(efc_size > 0)
+ if(NULL == (f->shared->efc = H5F_efc_create(efc_size)))
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache")
/* Get the VFD values to cache */
f->shared->maxaddr = H5FD_get_maxaddr(lf);
@@ -998,6 +1009,13 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush)
if(H5F_flush(f, dxpl_id) < 0)
HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache")
+ /* Release the external file cache */
+ if(f->shared->efc) {
+ if(H5F_efc_destroy(f->shared->efc) < 0)
+ HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache")
+ f->shared->efc = NULL;
+ } /* end if */
+
/* Release objects that depend on the superblock being initialized */
if(f->shared->sblock) {
/* Shutdown file free space manager(s) */
@@ -1903,6 +1921,13 @@ H5F_try_close(H5F_t *f)
if(H5F_close_mounts(f) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files")
+ /* If there is more than one reference to the shared file struct and the
+ * file has an external file cache, we should see if it can be closed. This
+ * can happen if a cycle is formed with external file caches */
+ if(f->shared->efc && (f->shared->nrefs > 1))
+ if(H5F_efc_try_close(f) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't attempt to close EFC")
+
/* Delay flush until the shared file struct is closed, in H5F_dest. If the
* application called H5Fclose, it would have been flushed in that function
* (unless it will have been flushed in H5F_dest anyways). */
@@ -2929,3 +2954,40 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Fget_free_sections() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Frelease_file_cache
+ *
+ * Purpose: Releases the external file cache associated with the
+ * provided file, potentially closing any cached files
+ * unless they are held open from somewhere\ else.
+ *
+ * Return: Success: non-negative
+ * Failure: negative
+ *
+ * Programmer: Neil Fortner; December 30, 2010
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Frelease_file_cache(hid_t file_id)
+{
+ H5F_t *file; /* File */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Frelease_file_cache, FAIL)
+ H5TRACE1("e", "i", file_id);
+
+ /* Check args */
+ if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID")
+
+ /* Release the EFC */
+ if(file->shared->efc)
+ if(H5F_efc_release(file->shared->efc) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Frelease_file_cache() */
+