summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2009-06-11 23:31:44 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2009-06-11 23:31:44 (GMT)
commitcae7ea3584994c9e8b33385a8bd60060380d6c63 (patch)
tree25d57653f4df8ed377097fa5d9840b27a5dfed39
parentb127ee77c07c5780836d284de0bccdefb08290b4 (diff)
downloadhdf5-cae7ea3584994c9e8b33385a8bd60060380d6c63.zip
hdf5-cae7ea3584994c9e8b33385a8bd60060380d6c63.tar.gz
hdf5-cae7ea3584994c9e8b33385a8bd60060380d6c63.tar.bz2
[svn-r17039] Description:
Convert indirect fractal heap blocks to use deferred file space allocation (by using the temporary file space feature), which should ease up the metadata fragmentation that can occur when lots of objects are added to a fractal heap (like adding many links to a group). Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode Linux/32 2.6 (jam) w/PGI compilers, w/C++ & FORTRAN, w/threadsafe, in debug mode Linux/64-amd64 2.6 (smirom) w/Intel compilers w/default API=1.6.x, w/C++ & FORTRAN, in production mode Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN, w/szip filter, in production mode Linux/64-ia64 2.6 (cobalt) w/Intel compilers, w/C++ & FORTRAN, in production mode Linux/64-ia64 2.4 (tg-login3) w/parallel, w/FORTRAN, in debug mode Linux/64-amd64 2.6 (abe) w/parallel, w/FORTRAN, in production mode Mac OS X/32 10.5.7 (amazon) in debug mode Mac OS X/32 10.5.7 (amazon) w/C++ & FORTRAN, w/threadsafe,
-rw-r--r--src/H5HFcache.c69
-rw-r--r--src/H5HFiblock.c32
2 files changed, 82 insertions, 19 deletions
diff --git a/src/H5HFcache.c b/src/H5HFcache.c
index a75a8b8..6d250d1 100644
--- a/src/H5HFcache.c
+++ b/src/H5HFcache.c
@@ -1056,6 +1056,57 @@ HDfprintf(stderr, "%s: iblock->filt_ents[%Zu] = {%Zu, %x}\n", FUNC, u, iblock->f
HDassert(max_child == iblock->max_child);
#endif /* NDEBUG */
+ /* Check for needing to re-allocate indirect block from 'temp.' to 'normal' file space */
+ if(H5F_IS_TMP_ADDR(f, addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Re-allocating indirect block in temporary space - addr = %a\n", FUNC, addr);
+#endif /* QAK */
+ /* Sanity check */
+ HDassert(H5F_addr_eq(iblock->addr, addr));
+
+ /* Allocate 'normal' space for the new indirect block on disk */
+ if(HADDR_UNDEF == (addr = H5MF_alloc(f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
+
+ /* Sanity check */
+ HDassert(!H5F_addr_eq(iblock->addr, addr));
+
+ /* Let the metadata cache know the block moved */
+ if(H5AC_rename(f, H5AC_FHEAP_IBLOCK, iblock->addr, addr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move indirect block")
+
+ /* Update the internal address for the block */
+ iblock->addr = addr;
+
+ /* Check for root indirect block */
+ if(NULL == iblock->parent) {
+ /* Update information about indirect block's location */
+ hdr->man_dtable.table_addr = addr;
+
+ /* Mark that heap header was modified */
+ if(H5HF_hdr_dirty(hdr) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end if */
+ else {
+ H5HF_indirect_t *par_iblock; /* Parent indirect block */
+ unsigned par_entry; /* Entry in parent indirect block */
+
+ /* Get parent information */
+ par_iblock = iblock->parent;
+ par_entry = iblock->par_entry;
+
+ /* Update information about indirect block's location */
+ par_iblock->ents[par_entry].addr = addr;
+
+ /* Mark that parent was modified */
+ if(H5HF_iblock_dirty(par_iblock) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
+ } /* end if */
+ } /* end if */
+
+ /* Indirect block must be in 'normal' file space now */
+ HDassert(!H5F_IS_TMP_ADDR(f, addr));
+
/* Write the indirect block */
if(H5F_block_write(f, H5FD_MEM_FHEAP_IBLOCK, addr, iblock->size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFLUSH, FAIL, "unable to save fractal heap indirect block to disk")
@@ -1112,10 +1163,14 @@ HDfprintf(stderr, "%s: Destroying indirect block\n", FUNC);
/* Check for freeing file space for indirect block */
if(iblock->cache_info.free_file_space_on_destroy) {
- /* Release the space on disk */
- /* (XXX: Nasty usage of internal DXPL value! -QAK) */
- if(H5MF_xfree(f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->cache_info.addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block")
+ /* Check if the indirect block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(f, iblock->cache_info.addr)) {
+ /* Release the space on disk */
+ /* (XXX: Nasty usage of internal DXPL value! -QAK) */
+ if(H5MF_xfree(f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->cache_info.addr, (hsize_t)iblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block")
+ } /* end if */
} /* end if */
/* Set the shared heap header's file context for this operation */
@@ -1680,12 +1735,12 @@ HDfprintf(stderr, "%s: Re-allocating direct block in temporary space - addr = %a
if(H5HF_iblock_dirty(par_iblock) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark heap header as dirty")
} /* end else */
-
- /* Direct block must be in 'normal' file space now */
- HDassert(!H5F_IS_TMP_ADDR(f, addr));
} /* end if */
} /* end else */
+ /* Direct block must be in 'normal' file space now */
+ HDassert(!H5F_IS_TMP_ADDR(f, addr));
+
/* Write the direct block */
#ifdef QAK
HDfprintf(stderr, "%s: addr = %a, write_size = %Zu\n", FUNC, addr, write_size);
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c
index 8f9eb24..3383ef9 100644
--- a/src/H5HFiblock.c
+++ b/src/H5HFiblock.c
@@ -578,6 +578,9 @@ HDfprintf(stderr, "%s: iblock->nrows = %u, iblock->max_rows = %u\n", FUNC, ibloc
HDfprintf(stderr, "%s: new_next_entry = %u\n", FUNC, new_next_entry);
#endif /* QAK */
+ /* Check if the indirect block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(hdr->f, iblock->addr)) {
/* Currently, the old block data is "thrown away" after the space is reallocated,
* to avoid data copy in H5MF_realloc() call by just free'ing the space and
* allocating new space.
@@ -587,16 +590,17 @@ HDfprintf(stderr, "%s: new_next_entry = %u\n", FUNC, new_next_entry);
*
* QAK - 3/14/2006
*/
- /* Free previous indirect block disk space */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ /* Free previous indirect block disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ } /* end if */
/* Compute size of buffer needed for new indirect block */
iblock->nrows = new_nrows;
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
- /* Allocate space for the new indirect block on disk */
- if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ /* Allocate [temporary] space for the new indirect block on disk */
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
#ifdef QAK
HDfprintf(stderr, "%s: Check 1.0 - iblock->addr = %a, new_addr = %a\n", FUNC, iblock->addr, new_addr);
@@ -739,6 +743,9 @@ HDfprintf(stderr, "%s: new_nrows = %u\n", FUNC, new_nrows);
HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
#endif /* QAK */
+ /* Check if the indirect block is NOT currently allocated in temp. file space */
+ /* (temp. file space does not need to be freed) */
+ if(!H5F_IS_TMP_ADDR(hdr->f, iblock->addr)) {
/* Currently, the old block data is "thrown away" after the space is reallocated,
* to avoid data copy in H5MF_realloc() call by just free'ing the space and
* allocating new space.
@@ -748,9 +755,10 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
*
* QAK - 6/12/2006
*/
- /* Free previous indirect block disk space */
- if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
- HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ /* Free previous indirect block disk space */
+ if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0)
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block file space")
+ } /* end if */
/* Compute free space in rows to delete */
acc_dblock_free = 0;
@@ -762,8 +770,8 @@ HDfprintf(stderr, "%s: iblock->nrows = %u\n", FUNC, iblock->nrows);
iblock->nrows = new_nrows;
iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock);
- /* Allocate space for the new indirect block on disk */
- if(HADDR_UNDEF == (new_addr = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ /* Allocate [temporary] space for the new indirect block on disk */
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size)))
HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
#ifdef QAK
HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr);
@@ -1078,8 +1086,8 @@ HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows);
else
iblock->child_iblocks = NULL;
- /* Allocate space for the indirect block on disk */
- if(HADDR_UNDEF == (*addr_p = H5MF_alloc(hdr->f, H5FD_MEM_FHEAP_IBLOCK, dxpl_id, (hsize_t)iblock->size)))
+ /* Allocate [temporary] space for the indirect block on disk */
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc_tmp(hdr->f, (hsize_t)iblock->size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block")
iblock->addr = *addr_p;