diff options
Diffstat (limited to 'src/H5HFiblock.c')
-rw-r--r-- | src/H5HFiblock.c | 113 |
1 files changed, 89 insertions, 24 deletions
diff --git a/src/H5HFiblock.c b/src/H5HFiblock.c index 7bb7884..70e3aac 100644 --- a/src/H5HFiblock.c +++ b/src/H5HFiblock.c @@ -70,6 +70,9 @@ H5FL_DEFINE(H5HF_indirect_t); /* Declare a free list to manage the H5HF_indirect_ent_t sequence information */ H5FL_SEQ_DEFINE(H5HF_indirect_ent_t); +/* Declare a free list to manage the H5HF_indirect_filt_ent_t sequence information */ +H5FL_SEQ_DEFINE(H5HF_indirect_filt_ent_t); + /*****************************/ /* Library Private Variables */ @@ -154,24 +157,12 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu\n", FUNC, iblock->block_off); /* Mark block as evictable again when no child blocks depend on it */ if(iblock->rc == 0) { - H5HF_indirect_t *tmp_iblock = NULL; /* Temporary pointer to indirect block */ - #ifdef QAK HDfprintf(stderr, "%s: indirect block ref. count at zero, iblock->addr = %a\n", FUNC, iblock->addr); #endif /* QAK */ - /* Lock indirect block */ - if(iblock->nchildren == 0) { - if(NULL == (tmp_iblock = H5HF_man_iblock_protect(iblock->hdr, H5AC_dxpl_id, iblock->addr, iblock->nrows, NULL, 0, H5AC_WRITE))) - HGOTO_ERROR(H5E_HEAP, H5E_CANTPROTECT, FAIL, "unable to protect fractal heap indirect block") - HDassert(tmp_iblock == iblock); - } /* end if */ - if(H5AC_unpin_entry(iblock->hdr->f, iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPIN, FAIL, "unable to unpin fractal heap indirect block") -/* XXX: If the indirect block has no children, delete indirect block's entry - * from cache. - */ if(iblock->nchildren == 0) { #ifdef QAK HDfprintf(stderr, "%s: Removing indirect block from cache, iblock->addr = %a\n", FUNC, iblock->addr); @@ -200,10 +191,9 @@ HDfprintf(stderr, "%s: Removing indirect block from cache, iblock->addr = %a\n", if(H5MF_xfree(iblock->hdr->f, H5FD_MEM_FHEAP_IBLOCK, H5AC_dxpl_id, iblock->addr, (hsize_t)iblock->size) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free fractal heap indirect block disk space") - /* Unlock indirect block with delete flag */ - if(H5AC_unprotect(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr, tmp_iblock, H5AC__DIRTIED_FLAG|H5AC__DELETED_FLAG) < 0) - HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block") - tmp_iblock = NULL; + /* Evict the indirect block from the metadata cache */ + if(H5AC_expunge_entry(iblock->hdr->f, H5AC_dxpl_id, H5AC_FHEAP_IBLOCK, iblock->addr) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "unable to remove indirect block from cache") } /* end if */ } /* end if */ @@ -488,15 +478,14 @@ HDfprintf(stderr, "%s: Check 1.0 - iblock->addr = %a, new_addr = %a\n", FUNC, ib iblock->addr = new_addr; } /* end if */ - /* Re-allocate direct block entry table */ + /* Re-allocate child block entry array */ if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct entries") + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for direct entries") /* Check for skipping over rows and add free section for skipped rows */ if(skip_direct_rows) { /* Add skipped blocks to heap's free space */ - if(H5HF_hdr_skip_blocks(hdr, dxpl_id, iblock, next_entry, - (new_next_entry - next_entry)) < 0) + if(H5HF_hdr_skip_blocks(hdr, dxpl_id, iblock, next_entry, (new_next_entry - next_entry)) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't add skipped blocks to heap's free space") } /* end if */ @@ -509,6 +498,26 @@ HDfprintf(stderr, "%s: Check 1.0 - iblock->addr = %a, new_addr = %a\n", FUNC, ib acc_dblock_free += hdr->man_dtable.row_tot_dblock_free[row]; } /* end for */ + /* Check for needing to re-allocate filtered entry array */ + if(hdr->filter_len > 0 && old_nrows < hdr->man_dtable.max_direct_rows) { + unsigned dir_rows; /* Number of direct rows in this indirect block */ + + /* Compute the number of direct rows for this indirect block */ + dir_rows = MIN(iblock->nrows, hdr->man_dtable.max_direct_rows); +HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows); + HDassert(dir_rows > old_nrows); + + /* Re-allocate filtered direct block entry array */ + if(NULL == (iblock->filt_ents = H5FL_SEQ_REALLOC(H5HF_indirect_filt_ent_t, iblock->filt_ents, (size_t)(dir_rows * hdr->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries") + + /* Initialize new entries allocated */ + for(u = (old_nrows * hdr->man_dtable.cparam.width); u < (dir_rows * hdr->man_dtable.cparam.width); u++) { + iblock->filt_ents[u].size = 0; + iblock->filt_ents[u].filter_mask = 0; + } /* end for */ + } /* end if */ + /* Mark indirect block as dirty */ if(H5HF_iblock_dirty(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") @@ -612,10 +621,17 @@ HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr); iblock->addr = new_addr; } /* end if */ - /* Re-allocate direct block entry table */ + /* Re-allocate child block entry array */ if(NULL == (iblock->ents = H5FL_SEQ_REALLOC(H5HF_indirect_ent_t, iblock->ents, (iblock->nrows * hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for direct entries") + /* Check for needing to re-allocate filtered entry array */ + if(hdr->filter_len > 0 && new_nrows < hdr->man_dtable.max_direct_rows) { + /* Re-allocate filtered direct block entry array */ + if(NULL == (iblock->filt_ents = H5FL_SEQ_REALLOC(H5HF_indirect_filt_ent_t, iblock->filt_ents, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_HEAP, H5E_NOSPACE, FAIL, "memory allocation failed for filtered direct entries") + } /* end if */ + /* Mark indirect block as dirty */ if(H5HF_iblock_dirty(iblock) < 0) HGOTO_ERROR(H5E_HEAP, H5E_CANTDIRTY, FAIL, "can't mark indirect block as dirty") @@ -842,7 +858,7 @@ HDfprintf(stderr, "%s: nrows = %u, max_rows = %u\n", FUNC, nrows, max_rows); /* Compute size of buffer needed for indirect block */ iblock->size = H5HF_MAN_INDIRECT_SIZE(hdr, iblock); - /* Allocate indirect block entry tables */ + /* Allocate child block entry array */ if(NULL == (iblock->ents = H5FL_SEQ_MALLOC(H5HF_indirect_ent_t, (size_t)(iblock->nrows * hdr->man_dtable.cparam.width)))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries") @@ -850,6 +866,23 @@ HDfprintf(stderr, "%s: nrows = %u, max_rows = %u\n", FUNC, nrows, max_rows); for(u = 0; u < (iblock->nrows * hdr->man_dtable.cparam.width); u++) iblock->ents[u].addr = HADDR_UNDEF; + /* Check for I/O filters to apply to this heap */ + if(hdr->filter_len > 0) { + unsigned dir_rows; /* Number of direct rows in this indirect block */ + + /* Compute the number of direct rows for this indirect block */ + dir_rows = MIN(iblock->nrows, hdr->man_dtable.max_direct_rows); +#ifdef QAK +HDfprintf(stderr, "%s: dir_rows = %u\n", FUNC, dir_rows); +#endif /* QAK */ + + /* Allocate & initialize indirect block filtered entry array */ + if(NULL == (iblock->filt_ents = H5FL_SEQ_CALLOC(H5HF_indirect_filt_ent_t, (size_t)(dir_rows * hdr->man_dtable.cparam.width)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for block entries") + } /* end if */ + else + iblock->filt_ents = 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))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for fractal heap indirect block") @@ -979,6 +1012,21 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, /* Point at the direct block */ iblock->ents[entry].addr = child_addr; + /* Check for I/O filters on this heap */ + if(iblock->hdr->filter_len > 0) { + unsigned row; /* Row for entry */ + + /* Sanity check */ + HDassert(iblock->filt_ents); + + /* Compute row for entry */ + row = entry / iblock->hdr->man_dtable.cparam.width; + + /* If this is a direct block, set its initial size */ + if(row < iblock->hdr->man_dtable.max_direct_rows) + iblock->filt_ents[entry].size = iblock->hdr->man_dtable.row_block_size[row]; + } /* end if */ + /* Check for max. entry used */ if(entry > iblock->max_child) iblock->max_child = entry; @@ -1028,9 +1076,26 @@ HDfprintf(stderr, "%s: iblock->block_off = %Hu, iblock->nchildren = %u\n", FUNC, /* Reset address of entry */ iblock->ents[entry].addr = HADDR_UNDEF; + /* Check for I/O filters on this heap */ + if(iblock->hdr->filter_len > 0) { + unsigned row; /* Row for entry */ + + /* Sanity check */ + HDassert(iblock->filt_ents); + + /* Compute row for entry */ + row = entry / iblock->hdr->man_dtable.cparam.width; + + /* If this is a direct block, set its initial size */ + if(row < iblock->hdr->man_dtable.max_direct_rows) { + iblock->filt_ents[entry].size = 0; + iblock->filt_ents[entry].filter_mask = 0; + } /* end if */ + } /* end if */ + /* Decrement the # of child blocks */ /* (If the number of children drop to 0, the indirect block will be - * removed from the heap when it's ref. count drops to zero and the + * removed from the heap when its ref. count drops to zero and the * metadata cache calls the indirect block destructor) */ iblock->nchildren--; @@ -1113,7 +1178,7 @@ H5HF_man_iblock_entry_addr(H5HF_indirect_t *iblock, unsigned entry, haddr_t *chi HDassert(iblock); HDassert(child_addr); - /* Reset address of entry */ + /* Retrieve address of entry */ *child_addr = iblock->ents[entry].addr; FUNC_LEAVE_NOAPI(SUCCEED) |