diff options
Diffstat (limited to 'src/H5HFhdr.c')
-rw-r--r-- | src/H5HFhdr.c | 112 |
1 files changed, 78 insertions, 34 deletions
diff --git a/src/H5HFhdr.c b/src/H5HFhdr.c index f8a0bb0..db0093e 100644 --- a/src/H5HFhdr.c +++ b/src/H5HFhdr.c @@ -43,6 +43,7 @@ /* Local Macros */ /****************/ +#ifndef NDEBUG /* Limit on the size of the max. direct block size */ /* (This is limited to 32-bits currently, because I think it's unlikely to * need to be larger, the 32-bit limit for H5V_log2_of2(n), and @@ -55,6 +56,8 @@ * need to be larger, and its encoded with a maxiumum of 16-bits - QAK) */ #define H5HF_WIDTH_LIMIT (64 * 1024) +#endif /* NDEBUG */ + /******************/ /* Local Typedefs */ @@ -76,7 +79,7 @@ /*********************/ /* Declare a free list to manage the H5HF_hdr_t struct */ -H5FL_DEFINE(H5HF_hdr_t); +H5FL_DEFINE_STATIC(H5HF_hdr_t); /*****************************/ @@ -107,7 +110,7 @@ H5HF_hdr_t * H5HF_hdr_alloc(H5F_t *f) { H5HF_hdr_t *hdr = NULL; /* Shared fractal heap header */ - H5HF_hdr_t *ret_value = NULL; /* Return value */ + H5HF_hdr_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5HF_hdr_alloc) @@ -118,7 +121,7 @@ H5HF_hdr_alloc(H5F_t *f) /* Allocate space for the shared information */ if(NULL == (hdr = H5FL_CALLOC(H5HF_hdr_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fractal heap shared header") + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "allocation failed for fractal heap shared header") /* Set the internal parameters for the heap */ hdr->f = f; @@ -129,9 +132,9 @@ H5HF_hdr_alloc(H5F_t *f) ret_value = hdr; done: - if(!ret_value) - if(hdr) - (void)H5HF_cache_hdr_dest(f, hdr); + if(!ret_value && hdr) + if(H5HF_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, NULL, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_alloc() */ @@ -219,7 +222,7 @@ H5HF_hdr_finish_init_phase1(H5HF_hdr_t *hdr) HDassert(hdr); /* Compute/cache some values */ - hdr->heap_off_size = H5HF_SIZEOF_OFFSET_BITS(hdr->man_dtable.cparam.max_index); + hdr->heap_off_size = (uint8_t)H5HF_SIZEOF_OFFSET_BITS(hdr->man_dtable.cparam.max_index); if(H5HF_dtable_init(&hdr->man_dtable) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize doubling table info") @@ -400,20 +403,28 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Set "huge" object tracker v2 B-tree address to indicate that there aren't any yet */ hdr->huge_bt2_addr = HADDR_UNDEF; - /* Note that the shared info is dirty (it's not written to the file yet) */ - hdr->dirty = TRUE; - /* First phase of header final initialization */ /* (doesn't need ID length set up) */ if(H5HF_hdr_finish_init_phase1(hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't finish phase #1 of header final initialization") /* Copy any I/O filter pipeline */ - /* (This code is not in the "finish init phase" routines because those + /* (This code is not in the "finish init phase" routines because those * routines are also called from the cache 'load' callback, and the filter * length is already set in that case (its stored in the header on disk)) */ if(cparam->pline.nused > 0) { + /* Check if the filters in the DCPL can be applied to this dataset */ + if(H5Z_can_apply_direct(&(cparam->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "I/O filters can't operate on this heap") + + /* Mark the filters as checked */ + hdr->checked_filters = TRUE; + + /* Make the "set local" filter callbacks for this dataset */ + if(H5Z_set_local_direct(&(cparam->pline)) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "unable to set local filter parameters") + /* Copy the I/O filter pipeline from the creation parameters to the header */ if(NULL == H5O_msg_copy(H5O_PLINE_ID, &(cparam->pline), &(hdr->pline))) HGOTO_ERROR(H5E_HEAP, H5E_CANTCOPY, HADDR_UNDEF, "can't copy I/O filter pipeline") @@ -421,7 +432,7 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Pay attention to the latest version flag for the file */ if(H5F_USE_LATEST_FORMAT(hdr->f)) /* Set the latest version for the I/O pipeline message */ - if(H5Z_set_latest_version(&(hdr->pline)) < 0) + if(H5O_pline_set_latest_version(&(hdr->pline)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, HADDR_UNDEF, "can't set latest version of I/O filter pipeline") /* Compute the I/O filters' encoded size */ @@ -434,18 +445,22 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) + 4 /* Size of filter mask for filtered root direct block */ + hdr->filter_len; /* Size of encoded I/O filter info */ } /* end if */ - else + else { /* Set size of header on disk */ hdr->heap_size = H5HF_HEADER_SIZE(hdr); + /* Mark filters as checked, for performance reasons */ + hdr->checked_filters = TRUE; + } /* end else */ + /* Set the length of IDs in the heap */ - /* (This code is not in the "finish init phase" routines because those + /* (This code is not in the "finish init phase" routines because those * routines are also called from the cache 'load' callback, and the ID * length is already set in that case (its stored in the header on disk)) */ switch(cparam->id_len) { case 0: /* Set the length of heap IDs to just enough to hold the offset & length of 'normal' objects in the heap */ - hdr->id_len = 1 + hdr->heap_off_size + hdr->heap_len_size; + hdr->id_len = (unsigned)1 + hdr->heap_off_size + hdr->heap_len_size; break; case 1: /* Set the length of heap IDs to just enough to hold the information needed to directly access 'huge' objects in the heap */ @@ -490,15 +505,15 @@ H5HF_hdr_create(H5F_t *f, hid_t dxpl_id, const H5HF_create_t *cparam) /* Cache the new fractal heap header */ if(H5AC_set(f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, HADDR_UNDEF, "can't add fractal heap header to cache") + HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, HADDR_UNDEF, "can't add fractal heap header to cache") /* Set address of heap header to return */ ret_value = hdr->heap_addr; done: - if(!H5F_addr_defined(ret_value)) - if(hdr) - (void)H5HF_cache_hdr_dest(NULL, hdr); + if(!H5F_addr_defined(ret_value) && hdr) + if(H5HF_hdr_free(hdr) < 0) + HDONE_ERROR(H5E_HEAP, H5E_CANTRELEASE, HADDR_UNDEF, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_create() */ @@ -663,9 +678,6 @@ H5HF_hdr_dirty(H5HF_hdr_t *hdr) if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTMARKDIRTY, FAIL, "unable to mark fractal heap header as dirty") - /* Set the dirty flags for the heap header */ - hdr->dirty = TRUE; - done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5HF_hdr_dirty() */ @@ -1182,7 +1194,7 @@ H5HF_hdr_reverse_iter(H5HF_hdr_t *hdr, hid_t dxpl_id, haddr_t dblock_addr) /* (Skip direct block that will be deleted, if we find it) */ tmp_entry = curr_entry; while(tmp_entry >= 0 && - (H5F_addr_eq(iblock->ents[tmp_entry].addr, dblock_addr) || + (H5F_addr_eq(iblock->ents[tmp_entry].addr, dblock_addr) || !H5F_addr_defined(iblock->ents[tmp_entry].addr))) tmp_entry--; /* Check for no earlier blocks in this indirect block */ @@ -1320,6 +1332,43 @@ done: /*------------------------------------------------------------------------- + * Function: H5HF_hdr_free + * + * Purpose: Free shared fractal heap header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Oct 27 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5HF_hdr_free(H5HF_hdr_t *hdr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_hdr_free) + + /* + * Check arguments. + */ + HDassert(hdr); + + /* Free the block size lookup table for the doubling table */ + H5HF_dtable_dest(&hdr->man_dtable); + + /* Release any I/O pipeline filter information */ + if(hdr->pline.nused) + H5O_msg_reset(H5O_PLINE_ID, &(hdr->pline)); + + /* Free the shared info itself */ + hdr = H5FL_FREE(H5HF_hdr_t, hdr); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5HF_hdr_free() */ + + +/*------------------------------------------------------------------------- * Function: H5HF_hdr_delete * * Purpose: Delete a fractal heap, starting with the header @@ -1335,7 +1384,8 @@ done: herr_t H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id) { - herr_t ret_value = SUCCEED; + unsigned cache_flags = H5AC__NO_FLAGS_SET; /* Flags for unprotecting heap header */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5HF_hdr_delete, FAIL) @@ -1403,18 +1453,12 @@ H5HF_hdr_delete(H5HF_hdr_t *hdr, hid_t dxpl_id) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap 'huge' objects and tracker") } /* end if */ - /* Release header's disk space */ - if(H5MF_xfree(hdr->f, H5FD_MEM_FHEAP_HDR, dxpl_id, hdr->heap_addr, (hsize_t)hdr->heap_size) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to release fractal heap header") - - /* Finished deleting header */ - if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header") - hdr = NULL; + /* Indicate that the heap header should be deleted & file space freed */ + cache_flags |= H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG; done: - /* Unprotect the header, if an error occurred */ - if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + /* Unprotect the header with appropriate flags */ + if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_HDR, hdr->heap_addr, hdr, cache_flags) < 0) HDONE_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap header") FUNC_LEAVE_NOAPI(ret_value) |