summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5F.c44
-rw-r--r--src/H5FD.c759
-rw-r--r--src/H5FDlog.c4
-rw-r--r--src/H5FDprivate.h2
-rw-r--r--src/H5FDpublic.h36
-rw-r--r--src/H5FS.c13
-rw-r--r--src/H5FSsection.c21
-rw-r--r--src/H5SL.c231
-rw-r--r--src/H5checksum.c33
-rw-r--r--src/H5private.h1
10 files changed, 667 insertions, 477 deletions
diff --git a/src/H5F.c b/src/H5F.c
index 045705f..48da779 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -308,7 +308,7 @@ H5F_get_access_plist(H5F_t *f)
/* Copy properties of the file access property list */
if(H5P_set(new_plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial meta data cache resize config.")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set initial metadata cache resize config.")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set data cache element size")
if(H5P_set(new_plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
@@ -321,11 +321,11 @@ H5F_get_access_plist(H5F_t *f)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set alignment")
if(H5P_set(new_plist, H5F_ACS_GARBG_COLCT_REF_NAME, &(f->shared->gc_ref)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set garbage collect reference")
- if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->lf->def_meta_block_size)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set meta data cache size")
+ if(H5P_set(new_plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(f->shared->lf->meta_aggr.alloc_size)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set metadata cache size")
if(H5P_set(new_plist, H5F_ACS_SIEVE_BUF_SIZE_NAME, &(f->shared->sieve_buf_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't sieve buffer size")
- if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->lf->def_sdata_block_size)) < 0)
+ if(H5P_set(new_plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->lf->sdata_aggr.alloc_size)) < 0)
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")
@@ -882,7 +882,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
if(NULL == (plist = H5I_object(fapl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not file access property list")
if(H5P_get(plist, H5F_ACS_META_CACHE_INIT_CONFIG_NAME, &(f->shared->mdc_initCacheCfg)) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial meta data cache resize config")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get initial metadata cache resize config")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_ELMT_SIZE_NAME, &(f->shared->rdcc_nelmts)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get data cache element size")
if(H5P_get(plist, H5F_ACS_DATA_CACHE_BYTE_SIZE_NAME, &(f->shared->rdcc_nbytes)) < 0)
@@ -924,12 +924,12 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf)
} /* end if */
/*
- * Create a meta data cache with the specified number of elements.
+ * Create a metadata cache with the specified number of elements.
* The cache might be created with a different number of elements and
* the access property list should be updated to reflect that.
*/
if(SUCCEED != H5AC_create(f, &(f->shared->mdc_initCacheCfg)))
- HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create meta data cache")
+ HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create metadata cache")
/* Create the file's "open object" information */
if(H5FO_create(f) < 0)
@@ -1697,12 +1697,12 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
if(H5D_flush(f, dxpl_id, flags) < 0)
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache")
- /* flush (and invalidate, if requested) the entire meta data cache */
+ /* flush (and invalidate, if requested) the entire metadata cache */
H5AC_flags = 0;
if((flags & H5F_FLUSH_INVALIDATE) != 0 )
H5AC_flags |= H5AC__FLUSH_INVALIDATE_FLAG;
if(H5AC_flush(f, dxpl_id, H5AC_flags) < 0)
- HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush meta data cache")
+ HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush metadata cache")
/*
* If we are invalidating everything (which only happens just before
@@ -1710,29 +1710,11 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
* "small data" blocks back to the free lists in the file.
*/
if(flags & H5F_FLUSH_INVALIDATE) {
- if(f->shared->lf->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- /* Return the unused portion of the metadata block to a free list */
- if(f->shared->lf->eoma != 0)
- if(H5FD_free(f->shared->lf, H5FD_MEM_DEFAULT, dxpl_id,
- f->shared->lf->eoma, f->shared->lf->cur_meta_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free metadata block")
-
- /* Reset metadata block information, just in case */
- f->shared->lf->eoma = 0;
- f->shared->lf->cur_meta_block_size = 0;
- } /* end if */
-
- if(f->shared->lf->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- /* Return the unused portion of the "small data" block to a free list */
- if(f->shared->lf->eosda != 0)
- if(H5FD_free(f->shared->lf, H5FD_MEM_DRAW, dxpl_id,
- f->shared->lf->eosda, f->shared->lf->cur_sdata_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free 'small data' block")
+ if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->meta_aggr), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset metadata block")
- /* Reset "small data" block information, just in case */
- f->shared->lf->eosda = 0;
- f->shared->lf->cur_sdata_block_size = 0;
- } /* end if */
+ if(H5FD_aggr_reset(f->shared->lf, &(f->shared->lf->sdata_aggr), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't reset 'small data' block")
} /* end if */
/* Write the superblock to disk */
diff --git a/src/H5FD.c b/src/H5FD.c
index 0cf70ca..e9974ed 100644
--- a/src/H5FD.c
+++ b/src/H5FD.c
@@ -60,10 +60,15 @@ static herr_t H5FD_pl_close(hid_t driver_id, herr_t (*free_func)(void *),
static herr_t H5FD_free_cls(H5FD_class_t *cls);
static haddr_t H5FD_alloc_from_free_list(H5FD_t *file, H5FD_mem_t type,
hsize_t size);
-static haddr_t H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
- hsize_t size);
-static haddr_t H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id,
- hsize_t size);
+static haddr_t H5FD_aggr_alloc(H5FD_t *file, H5FD_blk_aggr_t *aggr,
+ H5FD_blk_aggr_t *other_aggr, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
+static herr_t H5FD_aggr_adjoin(const H5FD_t *file, H5FD_blk_aggr_t *aggr,
+ H5FD_free_t *last);
+static htri_t H5FD_aggr_can_extend(const H5FD_t *file, const H5FD_blk_aggr_t *aggr,
+ haddr_t eoa, haddr_t end);
+static herr_t H5FD_aggr_shift(H5FD_blk_aggr_t *aggr, hsize_t extra);
+static herr_t H5FD_aggr_query(const H5FD_t *file, const H5FD_blk_aggr_t *aggr,
+ haddr_t *addr, hsize_t *size);
static haddr_t H5FD_real_alloc(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
static herr_t H5FD_free_freelist(H5FD_t *file);
static haddr_t H5FD_update_eoa(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size);
@@ -1055,10 +1060,12 @@ H5FD_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
HDmemset(file->fl, 0, sizeof(file->fl));
if(H5P_get(plist, H5F_ACS_META_BLOCK_SIZE_NAME, &(meta_block_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get meta data block size")
- file->def_meta_block_size = meta_block_size;
+ file->meta_aggr.feature_flag = H5FD_FEAT_AGGREGATE_METADATA;
+ file->meta_aggr.alloc_size = meta_block_size;
if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(sdata_block_size)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' block size")
- file->def_sdata_block_size = sdata_block_size;
+ file->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA;
+ file->sdata_aggr.alloc_size = sdata_block_size;
file->accum_loc = HADDR_UNDEF;
if(H5P_get(plist, H5F_ACS_ALIGN_THRHD_NAME, &(file->threshold)) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get alignment threshold")
@@ -1536,13 +1543,14 @@ HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
if(type != H5FD_MEM_DRAW) {
/* Handle metadata differently from "raw" data */
- if((ret_value = H5FD_alloc_metadata(file, type, dxpl_id, size)) == HADDR_UNDEF)
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate for metadata")
- } else {
+ if(HADDR_UNDEF == (ret_value = H5FD_aggr_alloc(file, &(file->meta_aggr), &(file->sdata_aggr), type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata")
+ } /* end if */
+ else {
/* Allocate "raw" data */
- if((ret_value = H5FD_alloc_raw(file, type, dxpl_id, size)) == HADDR_UNDEF)
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate for raw data")
- }
+ if(HADDR_UNDEF == (ret_value = H5FD_aggr_alloc(file, &(file->sdata_aggr), &(file->meta_aggr), type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data")
+ } /* end else */
done:
#ifdef H5FD_ALLOC_DEBUG
@@ -1807,8 +1815,8 @@ HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
/*-------------------------------------------------------------------------
- * Function: H5FD_alloc_metadata
- * Purpose: Try to allocate SIZE bytes of memory from the metadata
+ * Function: H5FD_aggr_alloc
+ * Purpose: Try to allocate SIZE bytes of memory from an aggregator
* block if possible.
*
* This is split from H5FD_alloc().
@@ -1816,245 +1824,430 @@ HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
* Failure: The undefined address HADDR_UNDEF
* Programmer: Bill Wendling
* 2. December, 2002
- * Modifications:
*
*-------------------------------------------------------------------------
*/
static haddr_t
-H5FD_alloc_metadata(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+H5FD_aggr_alloc(H5FD_t *file, H5FD_blk_aggr_t *aggr, H5FD_blk_aggr_t *other_aggr,
+ H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
{
- haddr_t ret_value = HADDR_UNDEF;
+ haddr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5FD_alloc_metadata, HADDR_UNDEF)
+ FUNC_ENTER_NOAPI_NOINIT(H5FD_aggr_alloc)
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
#endif /* H5FD_ALLOC_DEBUG */
/* check args */
- assert(file);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(other_aggr);
+ HDassert(other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(other_aggr->feature_flag != aggr->feature_flag);
+ HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+ HDassert(size > 0);
/*
- * If the metadata aggregation feature is enabled for this VFL
- * driver, allocate "generic" metadata space and sub-allocate out of
+ * If the aggregation feature is enabled for this VFL
+ * driver, allocate "generic" space and sub-allocate out of
* that, if possible. Otherwise just allocate through
* H5FD_real_alloc()
*/
+ if(file->feature_flags & aggr->feature_flag) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_size, aggr->size);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Check if the space requested is larger than the space left in the block */
+ if(size > aggr->size) {
+ haddr_t new_space; /* Address for newly allocated space */
- /*
- * Allocate all types of metadata out of the metadata block
- */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- /*
- * Check if the space requested is larger than the space left in
- * the block
- */
- if(size > file->cur_meta_block_size) {
- haddr_t new_meta; /* Address for new metadata */
-
- /*
- * Check if the block asked for is too large for a metadata
- * block
- */
- if(size >= file->def_meta_block_size) {
+ /* Check if the block asked for is too large for 'normal' aggregator block */
+ if(size >= aggr->alloc_size) {
/* Allocate more room for this new block the regular way */
- if(HADDR_UNDEF==(new_meta = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block")
+ if(HADDR_UNDEF == (new_space = H5FD_real_alloc(file, type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
- /*
- * Check if the new metadata is at the end of the current
- * metadata block
- */
- if(file->eoma + file->cur_meta_block_size == new_meta) {
+ /* Check if the new space is at the end of the current block */
+ if((aggr->addr + aggr->size) == new_space) {
/*
- * Treat the allocation request as if the current
- * metadata block grew by the amount allocated and
- * just update the eoma address. Don't bother
- * updating the cur_meta_block_size since it will
+ * Treat the allocation request as if the current block
+ * grew by the amount allocated and just update the address.
+ *
+ * Don't bother updating the block's size since it will
* just grow and shrink by the same amount.
+ *
+ * _Do_ add to the total size aggregated.
+ *
*/
- ret_value = file->eoma;
- file->eoma += size;
- } else {
- /* Use the new metadata block for the space allocated */
- ret_value = new_meta;
- }
- } else {
- /* Allocate another metadata block */
+ ret_value = aggr->addr;
+ aggr->addr += size;
+ aggr->tot_size += size;
+ } /* end if */
+ else {
+ /* Check if the new space is at the end of the _other_ block */
+ if(other_aggr->size > 0 && (other_aggr->addr + other_aggr->size) == new_space) {
#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Allocating 'metadata' block\n", FUNC);
+HDfprintf(stderr, "%s: New block is at end of 'other' block: other_aggr = {%a, %Hu, %Hu}\n", FUNC, other_aggr->addr, other_aggr->tot_size, other_aggr->size);
#endif /* H5FD_ALLOC_DEBUG */
- if(HADDR_UNDEF==(new_meta = H5FD_real_alloc(file, H5FD_MEM_DEFAULT, dxpl_id,
- file->def_meta_block_size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block")
+ /* If the other block has used at least the
+ * 'allocation' amount for that block, shift the
+ * newly allocated space down over the remainder
+ * in the 'other block', shift the 'other block'
+ * up by the same amount and free it. (Which
+ * should amount to "bubbling" the remainder in
+ * the 'other block' to the end of the file and
+ * then "popping" the bubble by shrinking the
+ * file)
+ */
+ if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
+ H5FD_mem_t alloc_type = (other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+ haddr_t free_addr = (new_space + size) - other_aggr->size; /* Address of free space in 'other block' shifted toward end of the file */
+ hsize_t free_size = other_aggr->size; /* Size of the free space in 'other block' */
- /*
- * Check if the new metadata is at the end of the current
- * metadata block
- */
- if(file->eoma + file->cur_meta_block_size == new_meta) {
- file->cur_meta_block_size += file->def_meta_block_size;
- } else {
- /*
- * Return the unused portion of the metadata block to
- * a free list
- */
- if(file->eoma != 0)
- if(H5FD_free(file, H5FD_MEM_DEFAULT, dxpl_id, file->eoma,
- file->cur_meta_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free metadata block")
-
- /* Point the metadata block at the newly allocated block */
- file->eoma = new_meta;
- file->cur_meta_block_size = file->def_meta_block_size;
- }
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Freeing 'other' block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Reset 'other' block's info */
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+
+ /* Shift newly allocated space down */
+ new_space -= free_size;
+
+ /* Return the unused portion of the 'other' block to a free list */
+ if(H5FD_free(file, alloc_type, dxpl_id, free_addr, free_size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+ } /* end if */
+ } /* end if */
+
+ /* Use the new space allocated, leaving the old block */
+ ret_value = new_space;
+ } /* end else */
+ } /* end if */
+ else {
+ H5FD_mem_t alloc_type = (aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+
+ /* Allocate another block */
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Allocating block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ if(HADDR_UNDEF == (new_space = H5FD_real_alloc(file, alloc_type, dxpl_id, aggr->alloc_size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate aggregation block")
+
+ /* Check if the new space is at the end of the current block */
+ if(aggr->addr + aggr->size == new_space) {
+ aggr->size += aggr->alloc_size;
+ aggr->tot_size += aggr->alloc_size;
+ } /* end if */
+ else {
+ hsize_t new_size; /* Size of new aggregator block */
+
+ /* Return the unused portion of the block to a free list */
+ if(aggr->size > 0)
+ if(H5FD_free(file, alloc_type, dxpl_id, aggr->addr, aggr->size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+
+ /* Check if the new space is at the end of the _other_ block */
+ if(other_aggr->size > 0 && (other_aggr->addr + other_aggr->size) == new_space) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: New block is at end of 'other' block: other_aggr = {%a, %Hu, %Hu}\n", FUNC, other_aggr->addr, other_aggr->tot_size, other_aggr->size);
+#endif /* H5FD_ALLOC_DEBUG */
+#ifdef QAK
+ /* If the other block has used at least the
+ * 'allocation' amount for that block, give the
+ * remaining free space in the 'other' block to
+ * the new space allocated for 'this' block.
+ */
+ if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Absorbing 'other' block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Absorb the remaining free space into newly allocated block */
+ new_space -= other_aggr->size;
+ new_size = aggr->alloc_size + other_aggr->size;
+
+ /* Reset the info for the 'other' block */
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+ } /* end if */
+ else
+ new_size = aggr->alloc_size;
+#else /* QAK */
+ /* If the other block has used at least the
+ * 'allocation' amount for that block, shift the
+ * newly allocated space down over the remainder
+ * in the 'other block', shift the 'other block'
+ * up by the same amount and free it. (Which
+ * should amount to "bubbling" the remainder in
+ * the 'other block' to the end of the file and
+ * then "popping" the bubble by shrinking the
+ * file)
+ */
+ if((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size) {
+ H5FD_mem_t other_type = (other_aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+ haddr_t free_addr = (new_space + aggr->alloc_size) - other_aggr->size; /* Address of free space in 'other block' shifted toward end of the file */
+ hsize_t free_size = other_aggr->size; /* Size of the free space in 'other block' */
+
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Freeing 'other' block\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
+ /* Reset 'other' block's info */
+ other_aggr->addr = 0;
+ other_aggr->tot_size = 0;
+ other_aggr->size = 0;
+
+ /* Shift newly allocated space down */
+ new_space -= free_size;
+
+ /* Return the unused portion of the 'other' block to a free list */
+ if(H5FD_free(file, other_type, dxpl_id, free_addr, free_size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
+ } /* end if */
+ new_size = aggr->alloc_size;
+#endif /* QAK */
+ } /* end if */
+ else
+ new_size = aggr->alloc_size;
+
+ /* Point the aggregator at the newly allocated block */
+ aggr->addr = new_space;
+ aggr->size = new_size;
+ aggr->tot_size = new_size;
+ } /* end else */
/* Allocate space out of the metadata block */
- ret_value = file->eoma;
- file->cur_meta_block_size -= size;
- file->eoma += size;
- }
- } else {
- /* Allocate space out of the metadata block */
- ret_value = file->eoma;
- file->cur_meta_block_size -= size;
- file->eoma += size;
+ ret_value = aggr->addr;
+ aggr->size -= size;
+ aggr->addr += size;
+ } /* end else */
+ } /* end if */
+ else {
+ /* Allocate space out of the block */
+ ret_value = aggr->addr;
+ aggr->size -= size;
+ aggr->addr += size;
}
- } else {
+ } /* end if */
+ else {
/* Allocate data the regular way */
- if(HADDR_UNDEF==(ret_value = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate metadata block")
- }
+ if(HADDR_UNDEF == (ret_value = H5FD_real_alloc(file, type, dxpl_id, size)))
+ HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate file space")
+ } /* end else */
done:
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
#endif /* H5FD_ALLOC_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc_metadata() */
+} /* end H5FD_aggr_alloc() */
/*-------------------------------------------------------------------------
- * Function: H5FD_alloc_raw
- * Purpose: Try to allocate SIZE bytes of raw data.
+ * Function: H5FD_aggr_adjoin
+ *
+ * Purpose: Check if a newly freed block of space in the file adjoins an
+ * aggregator block
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
*
- * This is split from H5FD_alloc().
- * Return: Success: The format address of the new file memory.
- * Failure: The undefined address HADDR_UNDEF
- * Programmer: Bill Wendling
- * 2. December, 2002
- * Modifications:
*-------------------------------------------------------------------------
*/
-static haddr_t
-H5FD_alloc_raw(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, hsize_t size)
+static herr_t
+H5FD_aggr_adjoin(const H5FD_t *file, H5FD_blk_aggr_t *aggr, H5FD_free_t *last)
{
- haddr_t ret_value = HADDR_UNDEF;
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_adjoin)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(file->cls);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(last);
+
+ /* Check if this free block adjoins the aggregator */
+ if((file->feature_flags & aggr->feature_flag) && aggr->size > 0) {
+ hbool_t adjoins = FALSE; /* Whether the block adjoined the aggregator */
+
+ /* Does the newly freed space adjoin the end of the aggregator */
+ if((aggr->addr + aggr->size) == last->addr) {
+ last->addr = aggr->addr;
+ adjoins = TRUE;
+ } /* end if */
+ /* Does the newly freed space adjoin the beginning of the aggregator */
+ else if((last->addr + last->size) == aggr->addr)
+ adjoins = TRUE;
- FUNC_ENTER_NOAPI(H5FD_alloc_raw, HADDR_UNDEF)
+ /* Reset aggregator information, if adjoined */
+ if(adjoins) {
#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, size = %Hu\n", FUNC, (unsigned)type, size);
+HDfprintf(stderr, "%s: Adjoined flag = %lx aggregator\n", "H5FD_aggr_adjoin", aggr->feature_flag);
#endif /* H5FD_ALLOC_DEBUG */
+ last->size += aggr->size;
+ aggr->addr = 0;
+ aggr->size = 0;
+ } /* end if */
+ } /* end if */
- /* check args */
- assert(file);
- assert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
- assert(size > 0);
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_aggr_adjoin() */
- /*
- * If the "small data" aggregation feature is enabled for this VFL driver,
- * allocate "small data" space and sub-allocate out of that, if
- * possible. Otherwise just allocate through H5FD_real_alloc()
- */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- /*
- * Check if the space requested is larger than the space left in
- * the block
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_can_extend
+ *
+ * Purpose: Check is an aggregator block can be extended
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5FD_aggr_can_extend(const H5FD_t *file, const H5FD_blk_aggr_t *aggr, haddr_t eoa,
+ haddr_t end)
+{
+ htri_t ret_value = FALSE;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_can_extend)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Check if this aggregator is active */
+ if(file->feature_flags & aggr->feature_flag) {
+ /* If the aggregator block is at the end of the file, and the block to
+ * test adjoins the beginning of the aggregator block, then it's
+ * extendable
*/
- if(size > file->cur_sdata_block_size) {
- haddr_t new_data; /* Address for new raw data block */
+ if((aggr->addr + aggr->size) == eoa && end == aggr->addr)
+ HGOTO_DONE(TRUE)
+ } /* end if */
- /* Check if the block asked for is too large for the "small data" block */
- if(size >= file->def_sdata_block_size) {
- /* Allocate more room for this new block the regular way */
- if(HADDR_UNDEF==(new_data = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5FD_aggr_can_extend() */
- /*
- * Check if the new raw data is at the end of the current
- * "small data" block
- */
- if(file->eosda + file->cur_sdata_block_size == new_data) {
- /*
- * Treat the allocation request as if the current
- * "small data" block grew by the amount allocated
- * and just update the eosda address. Don't bother
- * updating the cur_sdata_block_size since it will
- * just grow and shrink by the same amount.
- */
- ret_value = file->eosda;
- file->eosda += size;
- } else {
- /* Use the new "small data" block for the space allocated */
- ret_value = new_data;
- }
- } else {
- /* Allocate another "small data" block */
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Allocating 'small data' block\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- if(HADDR_UNDEF==(new_data = H5FD_real_alloc(file, type, dxpl_id,
- file->def_sdata_block_size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block")
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_extend
+ *
+ * Purpose: Shift an aggregator block in the file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_aggr_shift(H5FD_blk_aggr_t *aggr, hsize_t extra)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_shift)
- /*
- * Check if the new raw data is at the end of the current
- * "small data" block
- */
- if(file->eosda + file->cur_sdata_block_size == new_data) {
- file->cur_sdata_block_size += file->def_sdata_block_size;
- } else {
- /*
- * Return the unused portion of the "small data"
- * block to a free list
- */
- if(file->eosda != 0)
- if(H5FD_free(file, H5FD_MEM_DRAW, dxpl_id, file->eosda,
- file->cur_sdata_block_size) < 0)
- HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, HADDR_UNDEF, "can't free 'small data' block")
+ /* Check args */
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
- /*
- * Point the "small data" block at the newly
- * allocated block
- */
- file->eosda = new_data;
- file->cur_sdata_block_size = file->def_sdata_block_size;
- }
+ /* Shift the aggregator block by the extra amount */
+ aggr->addr += extra;
- /* Allocate space out of the "small data" block */
- ret_value = file->eosda;
- file->cur_sdata_block_size -= size;
- file->eosda += size;
- }
- } else {
- /* Allocate space out of the "small data" block */
- ret_value = file->eosda;
- file->cur_sdata_block_size -= size;
- file->eosda += size;
- }
- } else {
- /* Allocate data the regular way */
- if(HADDR_UNDEF==(ret_value = H5FD_real_alloc(file, type, dxpl_id, size)))
- HGOTO_ERROR(H5E_VFL, H5E_CANTALLOC, HADDR_UNDEF, "can't allocate raw data block")
- }
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_aggr_shift() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_query
+ *
+ * Purpose: Query a block aggregator's current address & size info
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5FD_aggr_query(const H5FD_t *file, const H5FD_blk_aggr_t *aggr, haddr_t *addr,
+ hsize_t *size)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_aggr_query)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Check if this aggregator is active */
+ if(file->feature_flags & aggr->feature_flag) {
+ *addr = aggr->addr;
+ *size = aggr->size;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5FD_aggr_query() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5FD_aggr_reset
+ *
+ * Purpose: Reset a block aggregator, returning any space back to file
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, December 13, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5FD_aggr_reset(H5FD_t *file, H5FD_blk_aggr_t *aggr, hid_t dxpl_id)
+{
+ H5FD_mem_t alloc_type; /* Type of file memory to work with */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5FD_aggr_reset, FAIL)
+
+ /* Check args */
+ HDassert(file);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Set the type of memory in the file */
+ alloc_type = (aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA ? H5FD_MEM_DEFAULT : H5FD_MEM_DRAW); /* Type of file memory to work with */
+
+ /* Check if this aggregator is active */
+ if(file->feature_flags & aggr->feature_flag) {
+ /* Return the unused portion of the metadata block to a free list */
+ if(aggr->size > 0)
+ if(H5FD_free(file, alloc_type, dxpl_id, aggr->addr, aggr->size) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "can't free aggregator block")
+
+ /* Reset aggregator block information */
+ aggr->tot_size = 0;
+ aggr->addr = 0;
+ aggr->size = 0;
+ } /* end if */
done:
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: ret_value = %a\n", FUNC, ret_value);
-#endif /* H5FD_ALLOC_DEBUG */
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5FD_alloc_raw() */
+} /* end H5FD_aggr_reset() */
/*-------------------------------------------------------------------------
@@ -2248,18 +2441,11 @@ done:
* Purpose: Private version of H5FDfree()
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Robb Matzke
* Wednesday, August 4, 1999
*
- * Modifications:
- * Bill Wendling, February 20, 2003
- * Added support for Flexible PHDF5. If the process is the
- * Set-Aside-Process, then we execute this function. Clients
- * don't.
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -2269,15 +2455,16 @@ H5FD_free(H5FD_t *file, H5FD_mem_t type, hid_t dxpl_id, haddr_t addr, hsize_t si
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5FD_free, FAIL)
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
-#endif /* H5FD_ALLOC_DEBUG */
/* Check args */
HDassert(file);
HDassert(file->cls);
HDassert(type >= H5FD_MEM_DEFAULT && type < H5FD_MEM_NTYPES);
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
+#endif /* H5FD_ALLOC_DEBUG */
+
if(!H5F_addr_defined(addr) || addr > file->maxaddr ||
H5F_addr_overflow(addr, size) || (addr + size) > file->maxaddr)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid region")
@@ -2291,6 +2478,9 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type
mapped_type = type;
else
mapped_type = file->cls->fl_map[type];
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: mapped_type = %u\n", FUNC, (unsigned)mapped_type);
+#endif /* H5FD_ALLOC_DEBUG */
/*
* If the request maps to a free list then add memory to the free list
@@ -2454,57 +2644,20 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type
last->next = file->fl[mapped_type];
file->fl[mapped_type] = last;
} /* end else */
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: mapped_type = %u, last = {%a, %Hu}\n", FUNC, (unsigned)mapped_type, last->addr, last->size);
+#endif /* H5FD_ALLOC_DEBUG */
/* Check if we increased the size of the largest block on the list */
file->maxsize = MAX(file->maxsize, last->size);
/* Check if this free block adjoins the "metadata aggregator" */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA && file->eoma != 0) {
- hbool_t adjoins = FALSE; /* Whether the block adjoined the metadata aggregator */
-
- /* Does the new block adjoin the end of the metadata aggregator */
- if((file->eoma + file->cur_meta_block_size) == last->addr) {
- last->addr = file->eoma;
- adjoins = TRUE;
- } /* end if */
- /* Does the new block adjoin the beginning of the metadata aggregator */
- else if((last->addr + last->size) == file->eoma)
- adjoins = TRUE;
-
- /* Reset metadata aggregator information, if adjoined */
- if(adjoins) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Adjoined metadata aggregator\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- last->size += file->cur_meta_block_size;
- file->eoma = 0;
- file->cur_meta_block_size = 0;
- } /* end if */
- } /* end if */
+ if(H5FD_aggr_adjoin(file, &(file->meta_aggr), last) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "aggregator deallocation request failed")
/* Check if this free block adjoins the "small data aggregator" */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA && file->eosda != 0) {
- hbool_t adjoins = FALSE; /* Whether the block adjoined the small-data aggregator */
-
- /* Does the new block adjoin the end of the small-data aggregator */
- if((file->eosda + file->cur_sdata_block_size) == last->addr) {
- last->addr = file->eosda;
- adjoins = TRUE;
- } /* end if */
- /* Does the new block adjoin the beginning of the small-data aggregator */
- else if((last->addr + last->size) == file->eosda)
- adjoins = TRUE;
-
- /* Reset small-data aggregator information, if adjoined */
- if(adjoins) {
-#ifdef H5FD_ALLOC_DEBUG
-HDfprintf(stderr, "%s: Adjoined small data aggregator\n", FUNC);
-#endif /* H5FD_ALLOC_DEBUG */
- last->size += file->cur_sdata_block_size;
- file->eosda = 0;
- file->cur_sdata_block_size = 0;
- } /* end if */
- } /* end if */
+ if(H5FD_aggr_adjoin(file, &(file->sdata_aggr), last) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "aggregator deallocation request failed")
/* Check if this free block is at the end of file allocated space.
* Truncate it if this is true. */
@@ -2512,6 +2665,9 @@ HDfprintf(stderr, "%s: Adjoined small data aggregator\n", FUNC);
haddr_t eoa;
eoa = file->cls->get_eoa(file, type);
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: eoa = %a\n", FUNC, eoa);
+#endif /* H5FD_ALLOC_DEBUG */
if(eoa == (last->addr + last->size)) {
#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, last->addr);
@@ -2527,13 +2683,16 @@ HDfprintf(stderr, "%s: Reducing file size to = %a\n", FUNC, last->addr);
} /* end if */
} /* end if */
} else if(file->cls->free) {
+#ifdef H5FD_ALLOC_DEBUG
+HDfprintf(stderr, "%s: Letting VFD free space\n", FUNC);
+#endif /* H5FD_ALLOC_DEBUG */
if((file->cls->free)(file, type, dxpl_id, addr, size) < 0)
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver free request failed")
} else {
/* leak memory */
-#ifdef H5F_DEBUG
+#ifdef H5FD_ALLOC_DEBUG
HDfprintf(stderr, "%s: LEAKED MEMORY!!! type = %u, addr = %a, size = %Hu\n", FUNC, (unsigned)type, addr, size);
-#endif /* H5F_DEBUG */
+#endif /* H5FD_ALLOC_DEBUG */
} /* end else */
done:
@@ -2684,22 +2843,25 @@ done:
htri_t
H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size, hsize_t extra_requested)
{
- haddr_t eoa; /* End of address space in the file */
- htri_t ret_value=FALSE; /* Return value */
+ haddr_t end; /* End of block in file */
+ haddr_t eoa; /* End of address space in the file */
+ htri_t ret_value = FALSE; /* Return value */
FUNC_ENTER_NOAPI(H5FD_can_extend, FAIL)
/* Retrieve the end of the address space */
- if(HADDR_UNDEF==(eoa=H5FD_get_eoa(file, type)))
+ if(HADDR_UNDEF == (eoa = H5FD_get_eoa(file, type)))
HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "driver get_eoa request failed")
+ /* Compute end of block */
+ end = addr + size;
+
/* Check if the block is exactly at the end of the file */
- if((addr+size)==eoa)
+ if(end == eoa)
HGOTO_DONE(TRUE)
else {
H5FD_free_t *curr; /* Current free block being inspected */
H5FD_mem_t mapped_type; /* Memory type, after mapping */
- haddr_t end; /* End of block in file */
/* Map request type to free list */
if(H5FD_MEM_DEFAULT==file->cls->fl_map[type])
@@ -2707,34 +2869,25 @@ H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr, hsize_t size,
else
mapped_type = file->cls->fl_map[type];
- /* Check if block is inside the metadata or small data accumulator */
+ /* Check if block is inside the metadata or small data aggregator */
if(mapped_type!=H5FD_MEM_DRAW) {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- /* If the metadata block is at the end of the file, and
- * the block to test adjoins the beginning of the metadata
- * block, then it's extendable
- */
- if(file->eoma + file->cur_meta_block_size == eoa &&
- (addr+size)==file->eoma)
- HGOTO_DONE(TRUE)
- } /* end if */
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->meta_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
+ else if(ret_value > 0)
+ HGOTO_DONE(TRUE)
} /* end if */
else {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- /* If the small data block is at the end of the file, and
- * the block to test adjoins the beginning of the small data
- * block, then it's extendable
- */
- if(file->eosda + file->cur_sdata_block_size == eoa &&
- (addr+size)==file->eosda)
- HGOTO_DONE(TRUE)
- } /* end if */
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->sdata_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if 'small data' aggregation block can be extended")
+ else if(ret_value > 0)
+ HGOTO_DONE(TRUE)
} /* end else */
/* Scan through the existing blocks for the mapped type to see if we can extend one */
if(mapped_type >= H5FD_MEM_DEFAULT) {
curr = file->fl[mapped_type];
- end = addr + size;
while(curr != NULL) {
if(end == curr->addr) {
if(extra_requested <= curr->size)
@@ -2805,24 +2958,18 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n
else {
/* (Check if block is inside the metadata or small data accumulator) */
if(mapped_type!=H5FD_MEM_DRAW) {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA)
- /* If the metadata block is at the end of the file, and
- * the block to test adjoins the beginning of the metadata
- * block, then it's extendable
- */
- if((file->eoma + file->cur_meta_block_size) == eoa &&
- end == file->eoma)
- update_eoma=TRUE;
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->meta_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
+ else if(ret_value > 0)
+ update_eoma = TRUE;
} /* end if */
else {
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA)
- /* If the small data block is at the end of the file, and
- * the block to test adjoins the beginning of the small data
- * block, then it's extendable
- */
- if((file->eosda + file->cur_sdata_block_size) == eoa &&
- end == file->eosda)
- update_eosda=TRUE;
+ /* Check for test block able to extend metadata aggregation block */
+ if((ret_value = H5FD_aggr_can_extend(file, &(file->sdata_aggr), eoa, end)) < 0)
+ HGOTO_ERROR(H5E_VFL, H5E_CANTINIT, FAIL, "can't determine if metadata aggregation block can be extended")
+ else if(ret_value > 0)
+ update_eosda = TRUE;
} /* end else */
} /* end else */
@@ -2838,11 +2985,11 @@ HDfprintf(stderr, "%s: type = %u, addr = %a, size = %Hu, extra_requested = %Hu\n
HGOTO_ERROR(H5E_VFL, H5E_NOSPACE, FAIL, "file allocation request failed")
/* Update the metadata and/or small data block */
- assert(!(update_eoma && update_eosda));
+ HDassert(!(update_eoma && update_eosda));
if(update_eoma)
- file->eoma+=extra_requested;
+ H5FD_aggr_shift(&(file->meta_aggr), extra_requested);
if(update_eosda)
- file->eosda+=extra_requested;
+ H5FD_aggr_shift(&(file->sdata_aggr), extra_requested);
} /* end if */
/* If the block we are extending isn't at the end of the file, find a free block to extend into */
else {
@@ -3927,17 +4074,11 @@ H5FD_get_freespace(const H5FD_t *file)
/* Retrieve the 'eoa' for the file */
eoa = file->cls->get_eoa(file, H5FD_MEM_DEFAULT);
- /* Check for aggregating metadata allocations */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_METADATA) {
- ma_addr = file->eoma;
- ma_size = file->cur_meta_block_size;
- } /* end if */
+ /* Retrieve metadata aggregator info, if available */
+ H5FD_aggr_query(file, &(file->meta_aggr), &ma_addr, &ma_size);
- /* Check for aggregating small data allocations */
- if(file->feature_flags & H5FD_FEAT_AGGREGATE_SMALLDATA) {
- sda_addr = file->eosda;
- sda_size = file->cur_sdata_block_size;
- } /* end if */
+ /* Retrieve 'small data' aggregator info, if available */
+ H5FD_aggr_query(file, &(file->sdata_aggr), &sda_addr, &sda_size);
/* Iterate over all the types of memory, to retrieve amount of free space for each */
for(type = H5FD_MEM_DEFAULT; type < H5FD_MEM_NTYPES; H5_INC_ENUM(H5FD_mem_t,type)) {
@@ -3962,7 +4103,7 @@ H5FD_get_freespace(const H5FD_t *file)
} /* end for */
/* Check for aggregating metadata allocations */
- if(H5F_addr_defined(ma_addr)) {
+ if(ma_size > 0) {
/* Add in the reserved space for metadata to the available free space */
/* (if it's not at the tail of the file) */
if(H5F_addr_ne(ma_addr + ma_size, eoa))
@@ -3970,7 +4111,7 @@ H5FD_get_freespace(const H5FD_t *file)
} /* end if */
/* Check for aggregating small data allocations */
- if(H5F_addr_defined(sda_addr)) {
+ if(sda_size > 0) {
/* Add in the reserved space for metadata to the available free space */
/* (if it's not at the tail of the file) */
if(H5F_addr_ne(sda_addr + sda_size, eoa))
diff --git a/src/H5FDlog.c b/src/H5FDlog.c
index 3109e09..df07c0a 100644
--- a/src/H5FDlog.c
+++ b/src/H5FDlog.c
@@ -234,7 +234,11 @@ static const H5FD_class_t H5FD_log_g = {
H5FD_log_flush, /*flush */
NULL, /*lock */
NULL, /*unlock */
+#ifdef OLD_WAY
H5FD_FLMAP_NOLIST /*fl_map */
+#else /* OLD_WAY */
+ H5FD_FLMAP_SINGLE /*fl_map */
+#endif /* OLD_WAY */
};
diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h
index 202b7d1..6f3a8de 100644
--- a/src/H5FDprivate.h
+++ b/src/H5FDprivate.h
@@ -74,5 +74,7 @@ H5_DLL htri_t H5FD_can_extend(const H5FD_t *file, H5FD_mem_t type, haddr_t addr,
hsize_t size, hsize_t extra_requested);
H5_DLL herr_t H5FD_extend(H5FD_t *file, H5FD_mem_t type, haddr_t addr,
hsize_t size, hsize_t extra_requested);
+H5_DLL herr_t H5FD_aggr_reset(H5FD_t *file, H5FD_blk_aggr_t *aggr, hid_t dxpl_id);
#endif /* !_H5FDprivate_H */
+
diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h
index ebf006b..ea92649 100644
--- a/src/H5FDpublic.h
+++ b/src/H5FDpublic.h
@@ -222,6 +222,15 @@ typedef struct H5FD_free_t {
struct H5FD_free_t *next;
} H5FD_free_t;
+/* Structure for metadata & "small [raw] data" block aggregation fields */
+typedef struct H5FD_blk_aggr_t {
+ unsigned long feature_flag; /* Feature flag type */
+ hsize_t alloc_size; /* Size for allocating new blocks */
+ hsize_t tot_size; /* Total amount of bytes aggregated into block */
+ hsize_t size; /* Current size of block left */
+ haddr_t addr; /* Location of block left */
+} H5FD_blk_aggr_t;
+
/*
* The main datatype for each driver. Public fields common to all drivers
* are declared here and the driver appends private fields in memory.
@@ -234,27 +243,11 @@ struct H5FD_t {
hsize_t threshold; /* Threshold for alignment */
hsize_t alignment; /* Allocation alignment */
- /* Metadata aggregation fields */
- hsize_t def_meta_block_size; /* Metadata allocation
- * block size (if
- * aggregating metadata) */
- hsize_t cur_meta_block_size; /* Current size of metadata
- * allocation region left */
- haddr_t eoma; /* End of metadata
- * allocated region */
- /* (ie. beginning of space available) */
-
- /* "Small data" aggregation fields */
- hsize_t def_sdata_block_size; /* "Small data"
- * allocation block size
- * (if aggregating "small
- * data") */
- hsize_t cur_sdata_block_size; /* Current size of "small
- * data" allocation
- * region left */
- haddr_t eosda; /* End of "small data"
- * allocated region */
- /* (ie. beginning of space available) */
+ /* Block aggregation info */
+ H5FD_blk_aggr_t meta_aggr; /* Metadata aggregation info */
+ /* (if aggregating metadata allocations) */
+ H5FD_blk_aggr_t sdata_aggr; /* "Small data" aggregation info */
+ /* (if aggregating "small data" allocations) */
/* Metadata accumulator fields */
unsigned char *meta_accum; /* Buffer to hold the accumulated metadata */
@@ -304,3 +297,4 @@ H5_DLL herr_t H5FDflush(H5FD_t *file, hid_t dxpl_id, unsigned closing);
}
#endif
#endif
+
diff --git a/src/H5FS.c b/src/H5FS.c
index f1907b2..2dd2833 100644
--- a/src/H5FS.c
+++ b/src/H5FS.c
@@ -101,6 +101,9 @@ H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr, const H5FS_create_t *fs_c
H5FS_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5FS_create, NULL)
+#ifdef QAK
+HDfprintf(stderr, "%s: Creating free space manager, nclasses = %Zu\n", FUNC, nclasses);
+#endif /* QAK */
/* Check arguments. */
HDassert(fs_addr);
@@ -373,13 +376,13 @@ HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_c
else {
unsigned sect_status = 0; /* Free space section's status in the metadata cache */
- /* Check the free space section's status in the metadata cache */
- if(H5AC_get_entry_status(f, fspace->sect_addr, &sect_status) < 0)
+ /* Check if we've allocated any section info in the file & if it's still in the cache */
+ if(H5F_addr_defined(fspace->sect_addr) && H5AC_get_entry_status(f, fspace->sect_addr, &sect_status) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTGET, FAIL, "unable to check metadata cache status for free space header")
- /* If this free list header's section info is still in the cache, don't
- * unpin the header - let the section info do it, when the section
- * into is evicted from the cache. -QAK
+ /* If this free list header's section info exists and is still in the
+ * cache, don't unpin the header - let the section info do it,
+ * when the section info is evicted from the cache. -QAK
*/
if(!(sect_status & H5AC_ES__IN_CACHE)) {
/* Unpin the free space header in the cache */
diff --git a/src/H5FSsection.c b/src/H5FSsection.c
index 505223a..c589aa0 100644
--- a/src/H5FSsection.c
+++ b/src/H5FSsection.c
@@ -187,6 +187,9 @@ H5FS_sinfo_pin(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
H5FS_sinfo_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_pin)
+#ifdef QAK
+HDfprintf(stderr, "%s: Called, fspace->sect_addr = %a\n", FUNC, fspace->sect_addr);
+#endif /* QAK */
/* Check arguments. */
HDassert(f);
@@ -194,6 +197,9 @@ H5FS_sinfo_pin(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
/* Create new section info, if it doesn't exist yet */
if(!H5F_addr_defined(fspace->sect_addr)) {
+#ifdef QAK
+HDfprintf(stderr, "%s: Allocating new section info\n", FUNC);
+#endif /* QAK */
/* Sanity check */
HDassert(fspace->tot_sect_count == 0);
HDassert(fspace->serial_sect_count == 0);
@@ -208,6 +214,9 @@ H5FS_sinfo_pin(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace)
fspace->alloc_sect_size = (size_t)fspace->sect_size;
if(HADDR_UNDEF == (fspace->sect_addr = H5MF_alloc(f, H5FD_MEM_FSPACE_SINFO, dxpl_id, fspace->alloc_sect_size)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, NULL, "file allocation failed for free space sections")
+#ifdef QAK
+HDfprintf(stderr, "%s: New section info, addr = %a, size = %Hu\n", FUNC, fspace->sect_addr, fspace->alloc_sect_size);
+#endif /* QAK */
/* Cache the new free space section info (pinned) */
if(H5AC_set(f, dxpl_id, H5AC_FSPACE_SINFO, fspace->sect_addr, sinfo, H5AC__PIN_ENTRY_FLAG) < 0)
@@ -1209,12 +1218,6 @@ HDfprintf(stderr, "%s: request = %Hu\n", FUNC, request);
HDassert(request);
HDassert(node);
- /* Check if we need to go get the sections */
- if(fspace->sinfo == NULL) {
- if(NULL == (fspace->sinfo = H5FS_sinfo_pin(f, dxpl_id, fspace)))
- HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't pin sections")
- } /* end if */
-
/* Check for any sections on free space list */
#ifdef QAK
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
@@ -1222,6 +1225,12 @@ HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", FUNC, fspace->serial_
HDfprintf(stderr, "%s: fspace->ghost_sect_count = %Hu\n", FUNC, fspace->ghost_sect_count);
#endif /* QAK */
if(fspace->tot_sect_count > 0) {
+ /* Check if we need to go get the sections */
+ if(fspace->sinfo == NULL) {
+ if(NULL == (fspace->sinfo = H5FS_sinfo_pin(f, dxpl_id, fspace)))
+ HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, FAIL, "can't pin sections")
+ } /* end if */
+
/* Look for node in bins */
if((ret_value = H5FS_sect_find_node(fspace, request, node)) < 0)
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "can't remove section from bins")
diff --git a/src/H5SL.c b/src/H5SL.c
index 94f0d23..a720182 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -90,69 +90,93 @@
#define H5SL_LOCATE_FIND_FOUND(SLIST,X,UPDATE,I) \
HGOTO_DONE(X);
-/* Define a code template for updating the "update" vector for the "DOUPDATE" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_YES_UPDATE(X,UPDATE,I) \
- UPDATE[I]=&X->forward[I];
-/* Define a code template for _NOT_ updating the "update" vector for the "DOUPDATE" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_NO_UPDATE(X,UPDATE,I)
+/* Define a code template for "OP"s that update the "update" vector for the H5SL_LOCATE macro */
+#define H5SL_LOCATE_INSERT_UPDATE(X, UPDATE, I) \
+ UPDATE[I] = &X->forward[I];
+#define H5SL_LOCATE_REMOVE_UPDATE(X, UPDATE, I) \
+ UPDATE[I] = &X->forward[I];
+
+/* Define a code template for "OP"s that _DON'T_ update the "update" vector for the H5SL_LOCATE macro */
+#define H5SL_LOCATE_SEARCH_UPDATE(X, UPDATE, I)
+#define H5SL_LOCATE_FIND_UPDATE(X, UPDATE, I)
+
/* Define a code template for comparing scalar keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SCALAR_CMP(TYPE,PKEY1,PKEY2) \
- (*(TYPE *)PKEY1 < *(TYPE *)PKEY2)
+#define H5SL_LOCATE_SCALAR_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+ (*(TYPE *)((PNODE)->key) < *(TYPE *)PKEY)
/* Define a code template for comparing string keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_STRING_CMP(TYPE,PKEY1,PKEY2) \
- (HDstrcmp(PKEY1, PKEY2) < 0)
+#define H5SL_LOCATE_STRING_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+ (((PNODE)->hashval == HASHVAL) ? (HDstrcmp((PNODE)->key, PKEY) < 0) : ((PNODE)->hashval < HASHVAL))
/* Define a code template for comparing H5_obj_t keys for the "CMP" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_OBJ_CMP(TYPE,PKEY1,PKEY2) \
- ((((TYPE *)PKEY1)->fileno < ((TYPE *)PKEY2)->fileno) ? TRUE : (((TYPE *)PKEY1)->addr < ((TYPE *)PKEY2)->addr))
+#define H5SL_LOCATE_OBJ_CMP(TYPE, PNODE, PKEY, HASHVAL) \
+ ((((TYPE *)((PNODE)->key))->fileno < ((TYPE *)PKEY)->fileno) ? TRUE : (((TYPE *)((PNODE)->key))->addr < ((TYPE *)PKEY)->addr))
+
/* Define a code template for comparing scalar keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_SCALAR_EQ(TYPE,PKEY1,PKEY2) \
- (*(TYPE *)PKEY1 == *(TYPE *)PKEY2)
+#define H5SL_LOCATE_SCALAR_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+ (*(TYPE *)((PNODE)->key) == *(TYPE *)PKEY)
/* Define a code template for comparing string keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_STRING_EQ(TYPE,PKEY1,PKEY2) \
- (HDstrcmp(PKEY1, PKEY2) == 0)
+#define H5SL_LOCATE_STRING_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+ (((PNODE)->hashval == HASHVAL) && (HDstrcmp(((PNODE)->key), PKEY) == 0))
+
+/* Define a code template for comparing H5_obj_t keys for the "EQ" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_OBJ_EQ(TYPE, PNODE, PKEY, HASHVAL) \
+ ((((TYPE *)((PNODE)->key))->fileno == ((TYPE *)PKEY)->fileno) && (((TYPE *)((PNODE)->key))->addr == ((TYPE *)PKEY)->addr))
+
+
+/* Define a code template for initializing the hash value for scalar keys for the "HASHINIT" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_SCALAR_HASHINIT(KEY, HASHVAL)
+
+/* Define a code template for initializing the hash value for string keys for the "HASHINIT" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_STRING_HASHINIT(KEY, HASHVAL) \
+ HASHVAL = H5_hash_string(KEY);
+
+/* Define a code template for initializing the hash value for H5_obj_t keys for the "HASHINIT" in the H5SL_LOCATE macro */
+#define H5SL_LOCATE_OBJ_HASHINIT(KEY, HASHVAL)
-/* Define a code template for comparing H5_obj_ keys for the "EQ" in the H5SL_LOCATE macro */
-#define H5SL_LOCATE_OBJ_EQ(TYPE,PKEY1,PKEY2) \
- ((((TYPE *)PKEY1)->fileno == ((TYPE *)PKEY2)->fileno) && (((TYPE *)PKEY1)->addr == ((TYPE *)PKEY2)->addr))
/* Macro used to find node for operation */
-#define H5SL_LOCATE(OP,DOUPDATE,CMP,SLIST,X,UPDATE,I,TYPE,KEY,CHECKED) \
- CHECKED=NULL; \
- for(I=(int)SLIST->curr_level; I>=0; I--) { \
- if(X->forward[I]!=CHECKED) { \
- while(X->forward[I] && H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE,X->forward[I]->key,KEY) ) \
- X=X->forward[I]; \
- CHECKED=X->forward[I]; \
+#define H5SL_LOCATE(OP, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+{ \
+ H5SL_node_t *_checked; /* Pointer to last node checked */ \
+ int _i; /* Local index variable */ \
+ \
+ _checked = NULL; \
+ H5_GLUE3(H5SL_LOCATE_,CMP,_HASHINIT)(KEY, HASHVAL) \
+ for(_i = (int)SLIST->curr_level; _i >= 0; _i--) { \
+ if(X->forward[_i] != _checked) { \
+ while(X->forward[_i] && H5_GLUE3(H5SL_LOCATE_,CMP,_CMP)(TYPE, X->forward[_i], KEY, HASHVAL) ) \
+ X = X->forward[_i]; \
+ _checked = X->forward[_i]; \
} /* end if */ \
- H5_GLUE3(H5SL_LOCATE_,DOUPDATE,_UPDATE)(X,UPDATE,I) \
+ H5_GLUE3(H5SL_LOCATE_,OP,_UPDATE)(X, UPDATE, _i) \
} /* end for */ \
- X=X->forward[0]; \
- if(X!=NULL && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE,X->key,KEY) ) { \
+ X = X->forward[0]; \
+ if(X != NULL && H5_GLUE3(H5SL_LOCATE_,CMP,_EQ)(TYPE, X, KEY, HASHVAL) ) { \
/* What to do when a node is found */ \
- H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST,X,UPDATE,I) \
- } /* end if */
+ H5_GLUE3(H5SL_LOCATE_,OP,_FOUND)(SLIST, X, UPDATE, _i) \
+ } /* end if */ \
+}
/* Macro used to insert node */
-#define H5SL_INSERT(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(INSERT, YES, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_INSERT(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(INSERT, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Macro used to remove node */
-#define H5SL_REMOVE(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(REMOVE, YES, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_REMOVE(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(REMOVE, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Macro used to search for node */
-#define H5SL_SEARCH(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(SEARCH, NO, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_SEARCH(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(SEARCH, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Macro used to find a node */
-#define H5SL_FIND(CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED) \
- H5SL_LOCATE(FIND, NO, CMP, SLIST, X, UPDATE, I, TYPE, KEY, CHECKED)
+#define H5SL_FIND(CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL) \
+ H5SL_LOCATE(FIND, CMP, SLIST, X, UPDATE, TYPE, KEY, HASHVAL)
/* Private typedefs & structs */
@@ -162,6 +186,7 @@ struct H5SL_node_t {
const void *key; /* Pointer to node's key */
void *item; /* Pointer to node's item */
size_t level; /* The level of this node */
+ uint32_t hashval; /* Hash value for key (only for strings, currently) */
struct H5SL_node_t **forward; /* Array of forward pointers from this node */
struct H5SL_node_t *backward; /* Backward pointer from this node */
};
@@ -183,7 +208,7 @@ struct H5SL_t {
/* Static functions */
static size_t H5SL_random_level(int p1, size_t max_level);
-static H5SL_node_t * H5SL_new_node(size_t lvl, void *item, const void *key);
+static H5SL_node_t * H5SL_new_node(size_t lvl, void *item, const void *key, uint32_t hashval);
static H5SL_node_t *H5SL_insert_common(H5SL_t *slist, void *item, const void *key);
static herr_t H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
static herr_t H5SL_close_common(H5SL_t *slist, H5SL_operator_t op, void *op_data);
@@ -295,24 +320,25 @@ H5SL_random_level(int p1, size_t max_level)
REVISION LOG
--------------------------------------------------------------------------*/
static H5SL_node_t *
-H5SL_new_node(size_t lvl, void *item, const void *key)
+H5SL_new_node(size_t lvl, void *item, const void *key, uint32_t hashval)
{
H5SL_node_t *ret_value; /* New skip list node */
- FUNC_ENTER_NOAPI_NOINIT(H5SL_new_node);
+ FUNC_ENTER_NOAPI_NOINIT(H5SL_new_node)
/* Allocate the node */
- if((ret_value=H5FL_ARR_MALLOC(H5SL_node_ptr_t,(lvl+1)))==NULL)
- HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (ret_value = H5FL_ARR_MALLOC(H5SL_node_ptr_t, (lvl + 1))))
+ HGOTO_ERROR(H5E_SLIST, H5E_NOSPACE, NULL, "memory allocation failed")
/* Initialize node */
- ret_value->key=key;
- ret_value->item=item;
- ret_value->level=lvl;
- ret_value->forward=(H5SL_node_t **)((unsigned char *)ret_value+sizeof(H5SL_node_t));
+ ret_value->key = key;
+ ret_value->item = item;
+ ret_value->level = lvl;
+ ret_value->hashval = hashval;
+ ret_value->forward = (H5SL_node_t **)((unsigned char *)ret_value + sizeof(H5SL_node_t));
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5SL_new_node() */
@@ -341,8 +367,8 @@ static H5SL_node_t *
H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
{
H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
+ uint32_t hashval = 0; /* Hash value for key */
size_t lvl; /* Level of new node */
int i; /* Local index value */
H5SL_node_t *ret_value; /* Return value */
@@ -364,31 +390,31 @@ H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_INSERT(SCALAR, slist, x, update, i, const int, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_INSERT(SCALAR, slist, x, update, i, const haddr_t, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_INSERT(STRING, slist, x, update, i, char *, key, checked)
+ H5SL_INSERT(STRING, slist, x, update, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_INSERT(SCALAR, slist, x, update, i, const hsize_t, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_INSERT(SCALAR, slist, x, update, i, const unsigned, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_INSERT(SCALAR, slist, x, update, i, const size_t, key, checked)
+ H5SL_INSERT(SCALAR, slist, x, update, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_INSERT(OBJ, slist, x, update, i, const H5_obj_t, key, checked)
+ H5SL_INSERT(OBJ, slist, x, update, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -408,8 +434,8 @@ H5SL_insert_common(H5SL_t *slist, void *item, const void *key)
} /* end if */
/* Create new node of proper level */
- if((x=H5SL_new_node(lvl,item,key))==NULL)
- HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"can't create new skip list node");
+ if(NULL == (x = H5SL_new_node(lvl, item, key, hashval)))
+ HGOTO_ERROR(H5E_SLIST ,H5E_NOSPACE, NULL, "can't create new skip list node")
/* Update the backward links */
if(*update[0]!=NULL) {
@@ -600,8 +626,8 @@ H5SL_create(H5SL_type_t type, double p, size_t max_level)
new_slist->nobjs=0;
/* Allocate the header node */
- if((header=H5SL_new_node(max_level-1,NULL,NULL))==NULL)
- HGOTO_ERROR(H5E_SLIST,H5E_NOSPACE,NULL,"memory allocation failed");
+ if(NULL == (header = H5SL_new_node((max_level - 1), NULL, NULL, ULONG_MAX)))
+ HGOTO_ERROR(H5E_SLIST ,H5E_NOSPACE, NULL, "can't create new skip list node")
/* Initialize header node's forward pointers */
for(u=0; u<max_level; u++)
@@ -776,9 +802,8 @@ void *
H5SL_remove(H5SL_t *slist, const void *key)
{
H5SL_node_t **update[H5SL_LEVEL_MAX]; /* 'update' vector */
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value=NULL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_remove);
@@ -798,31 +823,31 @@ H5SL_remove(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const int, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const haddr_t, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_REMOVE(STRING, slist, x, update, i, char *, key, checked)
+ H5SL_REMOVE(STRING, slist, x, update, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const hsize_t, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const unsigned, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_REMOVE(SCALAR, slist, x, update, i, const size_t, key, checked)
+ H5SL_REMOVE(SCALAR, slist, x, update, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_REMOVE(OBJ, slist, x, update, i, const H5_obj_t, key, checked)
+ H5SL_REMOVE(OBJ, slist, x, update, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -927,9 +952,8 @@ H5SL_remove_first(H5SL_t *slist)
void *
H5SL_search(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_search);
@@ -949,31 +973,31 @@ H5SL_search(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_SEARCH(OBJ, slist, x, -, i, const H5_obj_t, key, checked)
+ H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -1010,9 +1034,8 @@ done:
void *
H5SL_less(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_less);
@@ -1032,31 +1055,31 @@ H5SL_less(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_SEARCH(OBJ, slist, x, -, i, const H5_obj_t, key, checked)
+ H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -1106,9 +1129,8 @@ done:
void *
H5SL_greater(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_greater);
@@ -1128,31 +1150,31 @@ H5SL_greater(H5SL_t *slist, const void *key)
x = slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_SEARCH(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_SEARCH(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_SEARCH(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_SEARCH(SCALAR, slist, x, -, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_SEARCH(OBJ, slist, x, -, i, const H5_obj_t, key, checked)
+ H5SL_SEARCH(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
@@ -1192,9 +1214,8 @@ done:
H5SL_node_t *
H5SL_find(H5SL_t *slist, const void *key)
{
- H5SL_node_t *checked; /* Pointer to last node checked */
H5SL_node_t *x; /* Current node to examine */
- int i; /* Local index value */
+ uint32_t hashval = 0; /* Hash value for key */
H5SL_node_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5SL_find);
@@ -1214,31 +1235,31 @@ H5SL_find(H5SL_t *slist, const void *key)
x=slist->header;
switch(slist->type) {
case H5SL_TYPE_INT:
- H5SL_FIND(SCALAR, slist, x, -, i, const int, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const int, key, -)
break;
case H5SL_TYPE_HADDR:
- H5SL_FIND(SCALAR, slist, x, -, i, const haddr_t, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const haddr_t, key, -)
break;
case H5SL_TYPE_STR:
- H5SL_FIND(STRING, slist, x, -, i, char *, key, checked)
+ H5SL_FIND(STRING, slist, x, -, char *, key, hashval)
break;
case H5SL_TYPE_HSIZE:
- H5SL_FIND(SCALAR, slist, x, -, i, const hsize_t, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const hsize_t, key, -)
break;
case H5SL_TYPE_UNSIGNED:
- H5SL_FIND(SCALAR, slist, x, -, i, const unsigned, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const unsigned, key, -)
break;
case H5SL_TYPE_SIZE:
- H5SL_FIND(SCALAR, slist, x, -, i, const size_t, key, checked)
+ H5SL_FIND(SCALAR, slist, x, -, const size_t, key, -)
break;
case H5SL_TYPE_OBJ:
- H5SL_FIND(OBJ, slist, x, -, i, const H5_obj_t, key, checked)
+ H5SL_FIND(OBJ, slist, x, -, const H5_obj_t, key, -)
break;
} /* end switch */
diff --git a/src/H5checksum.c b/src/H5checksum.c
index f2e344d..e42f152 100644
--- a/src/H5checksum.c
+++ b/src/H5checksum.c
@@ -459,3 +459,36 @@ H5_checksum_metadata(const void *data, size_t len, uint32_t initval)
FUNC_LEAVE_NOAPI(H5_checksum_lookup3(data, len, initval))
} /* end H5_checksum_metadata() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5_hash_string
+ *
+ * Purpose: Provide a simple & fast routine for hashing strings
+ *
+ * Note: This algorithm is the 'djb2' algorithm described on this page:
+ * http://www.cse.yorku.ca/~oz/hash.html
+ *
+ * Return: hash of input string (can't fail)
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, December 11, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+uint32_t
+H5_hash_string(const char *str)
+{
+ uint32_t hash = 5381;
+ int c;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5_hash_string)
+
+ /* Sanity check */
+ HDassert(str);
+
+ while(c = *str++)
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ FUNC_LEAVE_NOAPI(hash)
+} /* end H5_hash_string() */
+
diff --git a/src/H5private.h b/src/H5private.h
index 3ac4da3..11f3037 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -1415,6 +1415,7 @@ H5_DLL uint32_t H5_checksum_fletcher32(const void *data, size_t len);
H5_DLL uint32_t H5_checksum_crc(const void *data, size_t len);
H5_DLL uint32_t H5_checksum_lookup3(const void *data, size_t len, uint32_t initval);
H5_DLL uint32_t H5_checksum_metadata(const void *data, size_t len, uint32_t initval);
+H5_DLL uint32_t H5_hash_string(const char *str);
/* Functions for debugging */
H5_DLL herr_t H5_buffer_dump(FILE *stream, int indent, uint8_t *buf,