summaryrefslogtreecommitdiffstats
path: root/src/H5MFaggr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5MFaggr.c')
-rw-r--r--src/H5MFaggr.c161
1 files changed, 146 insertions, 15 deletions
diff --git a/src/H5MFaggr.c b/src/H5MFaggr.c
index 6f68fd7..f015b19 100644
--- a/src/H5MFaggr.c
+++ b/src/H5MFaggr.c
@@ -57,6 +57,8 @@
/********************/
/* Local Prototypes */
/********************/
+static herr_t H5MF_aggr_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type,
+ H5F_blk_aggr_t *aggr);
/*********************/
@@ -231,15 +233,14 @@ HDfprintf(stderr, "%s: aggr = {%a, %Hu, %Hu}\n", FUNC, aggr->addr, aggr->tot_siz
if(H5F_addr_gt((eoa + size), f->shared->tmp_addr))
HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")
+ /* Release "other" aggregator, if it exists, is at the end of the allocated space,
+ * has allocated more than one block and the unallocated space is greater than its
+ * allocation block size.
+ */
if ((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) &&
- ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {
-
- if(H5FD_free(f->shared->lf, dxpl_id, other_alloc_type, f, other_aggr->addr, other_aggr->size) < 0)
+ (other_aggr->tot_size > other_aggr->size) && ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {
+ if(H5MF_aggr_free(f, dxpl_id, other_alloc_type, other_aggr) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
-
- other_aggr->addr = 0;
- other_aggr->tot_size = 0;
- other_aggr->size = 0;
} /* end if */
/* Allocate space from the VFD (i.e. at the end of the file) */
@@ -275,14 +276,14 @@ HDfprintf(stderr, "%s: Allocating block\n", FUNC);
if(H5F_addr_gt((eoa + aggr->alloc_size), f->shared->tmp_addr))
HGOTO_ERROR(H5E_RESOURCE, H5E_BADRANGE, HADDR_UNDEF, "'normal' file space allocation request will overlap into 'temporary' file space")
+ /* Release "other" aggregator, if it exists, is at the end of the allocated space,
+ * has allocated more than one block and the unallocated space is greater than its
+ * allocation block size.
+ */
if((other_aggr->size > 0) && (H5F_addr_eq((other_aggr->addr + other_aggr->size), eoa)) &&
- ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {
-
- if(H5FD_free(f->shared->lf, dxpl_id, other_alloc_type, f, other_aggr->addr, other_aggr->size) < 0)
+ (other_aggr->tot_size > other_aggr->size) && ((other_aggr->tot_size - other_aggr->size) >= other_aggr->alloc_size)) {
+ if(H5MF_aggr_free(f, dxpl_id, other_alloc_type, other_aggr) < 0)
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, HADDR_UNDEF, "can't free aggregation block")
- other_aggr->addr = 0;
- other_aggr->tot_size = 0;
- other_aggr->size = 0;
} /* end if */
/* Allocate space from the VFD (i.e. at the end of the file) */
@@ -633,8 +634,10 @@ H5MF_aggr_query(const H5F_t *f, const H5F_blk_aggr_t *aggr, haddr_t *addr,
/* Check if this aggregator is active */
if(f->shared->feature_flags & aggr->feature_flag) {
- *addr = aggr->addr;
- *size = aggr->size;
+ if(addr)
+ *addr = aggr->addr;
+ if(size)
+ *size = aggr->size;
} /* end if */
FUNC_LEAVE_NOAPI(SUCCEED)
@@ -766,3 +769,131 @@ done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5MF_free_aggrs() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_can_shrink_eoa
+ *
+ * Purpose: Check if the remaining space in the aggregator is at EOA
+ *
+ * Return: Success: non-negative (TRUE/FALSE)
+ * Failure: negative
+ *
+ * Programmer: Vailin Choi
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5MF_aggr_can_shrink_eoa(H5F_t *f, H5FD_mem_t type, H5F_blk_aggr_t *aggr)
+{
+ haddr_t eoa = HADDR_UNDEF; /* EOA for the file */
+ htri_t ret_value = FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(aggr);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+
+ /* Get the EOA for the file */
+ if(HADDR_UNDEF == (eoa = H5F_get_eoa(f, type)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "Unable to get eoa")
+
+ /* Check if the aggregator is at EOA */
+ if(aggr->size > 0 && H5F_addr_defined(aggr->addr))
+ ret_value = H5F_addr_eq(eoa, aggr->addr + aggr->size);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_aggr_can_shrink_eoa() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggr_free
+ *
+ * Purpose: Free the aggregator's space in the file.
+ *
+ * Note: Does _not_ put the space on a free list
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5MF_aggr_free(H5F_t *f, hid_t dxpl_id, H5FD_mem_t type, H5F_blk_aggr_t *aggr)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Sanity check */
+ HDassert(f);
+ HDassert(f->shared->lf);
+ HDassert(aggr);
+ HDassert(H5F_addr_defined(aggr->addr));
+ HDassert(aggr->size > 0);
+ HDassert(H5F_INTENT(f) & H5F_ACC_RDWR);
+ HDassert(aggr->feature_flag == H5FD_FEAT_AGGREGATE_METADATA || aggr->feature_flag == H5FD_FEAT_AGGREGATE_SMALLDATA);
+ HDassert(f->shared->feature_flags & aggr->feature_flag);
+
+ /* Free the remaining space at EOA in the aggregator */
+ if(H5FD_free(f->shared->lf, dxpl_id, type, f, aggr->addr, aggr->size) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "can't free aggregation block")
+
+ /* Reset the aggregator */
+ aggr->tot_size = 0;
+ aggr->addr = HADDR_UNDEF;
+ aggr->size = 0;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5MF_aggr_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5MF_aggrs_try_shrink_eoa
+ *
+ * Purpose: Check the metadata & small block aggregators to see if
+ * EOA shrink is possible; if so, shrink each aggregator
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Vailin Choi
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5MF_aggrs_try_shrink_eoa(H5F_t *f, hid_t dxpl_id)
+{
+ htri_t ma_status; /* Whether the metadata aggregator can shrink the EOA */
+ htri_t sda_status; /* Whether the small data aggregator can shrink the EOA */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(FAIL)
+
+ /* Check args */
+ HDassert(f);
+ HDassert(f->shared);
+
+ if((ma_status = H5MF_aggr_can_shrink_eoa(f, H5FD_MEM_DEFAULT, &(f->shared->meta_aggr))) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query metadata aggregator stats")
+ if(ma_status > 0)
+ if(H5MF_aggr_free(f, dxpl_id, H5FD_MEM_DEFAULT, &(f->shared->meta_aggr)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa")
+
+ if((sda_status = H5MF_aggr_can_shrink_eoa(f, H5FD_MEM_DRAW, &(f->shared->sdata_aggr))) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGET, FAIL, "can't query small data aggregator stats")
+ if(sda_status > 0)
+ if(H5MF_aggr_free(f, dxpl_id, H5FD_MEM_DRAW, &(f->shared->sdata_aggr)) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTSHRINK, FAIL, "can't check for shrinking eoa")
+
+ ret_value = (ma_status || sda_status);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5MF_aggrs_try_shrink_eoa() */
+