mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-04-12 17:31:09 +08:00
[svn-r12525] Description:
Refactored free space manager to use metadata cache for serialized free space sections. This speeds up the fractal heap test considerably... Tested: FreeBSD 4.11 (sleipnir) Linux 2.4/32 (chicago) Linux 2.4/64 (mir) Mac OS X (amazon)
This commit is contained in:
parent
d296efb47e
commit
c951c27830
1
MANIFEST
1
MANIFEST
@ -481,6 +481,7 @@
|
||||
./src/H5FSpkg.h
|
||||
./src/H5FSprivate.h
|
||||
./src/H5FSpublic.h
|
||||
./src/H5FSsection.c
|
||||
./src/H5G.c
|
||||
./src/H5Gdeprec.c
|
||||
./src/H5Gent.c
|
||||
|
1
src/H5.c
1
src/H5.c
@ -231,7 +231,6 @@ H5_term_library(void)
|
||||
* that depend on them. -QAK
|
||||
*/
|
||||
if(pending==0) {
|
||||
pending += DOWN(FS);
|
||||
pending += DOWN(AC);
|
||||
pending += DOWN(Z);
|
||||
pending += DOWN(FD);
|
||||
|
@ -487,6 +487,7 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] =
|
||||
"fractal heap direct blocks",
|
||||
"fractal heap indirect blocks",
|
||||
"free space headers",
|
||||
"free space sections",
|
||||
"test entry" /* for testing only -- not used for actual files */
|
||||
};
|
||||
|
||||
|
@ -58,6 +58,7 @@ typedef enum {
|
||||
H5AC_FHEAP_DBLOCK_ID, /*fractal heap direct block */
|
||||
H5AC_FHEAP_IBLOCK_ID, /*fractal heap indirect block */
|
||||
H5AC_FSPACE_HDR_ID, /*free space header */
|
||||
H5AC_FSPACE_SINFO_ID,/*free space sections */
|
||||
H5AC_TEST_ID, /*test entry -- not used for actual files */
|
||||
H5AC_NTYPES /* Number of types, must be last */
|
||||
} H5AC_type_t;
|
||||
|
@ -707,7 +707,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#define H5C__H5C_T_MAGIC 0x005CAC0E
|
||||
#define H5C__MAX_NUM_TYPE_IDS 13
|
||||
#define H5C__MAX_NUM_TYPE_IDS 14
|
||||
#define H5C__PREFIX_LEN 32
|
||||
|
||||
struct H5C_t
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "H5Fpkg.h" /* File access */
|
||||
#include "H5FDprivate.h" /* File drivers */
|
||||
#include "H5FLprivate.h" /* Free lists */
|
||||
#include "H5FSprivate.h" /* File free space */
|
||||
#include "H5Gprivate.h" /* Groups */
|
||||
#include "H5Iprivate.h" /* IDs */
|
||||
#include "H5MMprivate.h" /* Memory management */
|
||||
@ -2333,13 +2332,6 @@ H5F_flush(H5F_t *f, hid_t dxpl_id, H5F_scope_t scope, unsigned flags)
|
||||
if (H5F_flush(f->mtab.child[i].file, dxpl_id, scope, flags) < 0)
|
||||
nerrors++;
|
||||
|
||||
/* Flush any cached free space info */
|
||||
/* (Make certain that this is before the metadata cache flush, so the
|
||||
* updated free space info in the metadata cache gets flushed out to disk)
|
||||
*/
|
||||
if (H5FS_flush(f, dxpl_id, flags) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush free space info")
|
||||
|
||||
/* Flush any cached dataset storage raw data */
|
||||
if (H5D_flush(f, dxpl_id, flags) < 0)
|
||||
HGOTO_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush dataset cache")
|
||||
|
@ -69,7 +69,7 @@ typedef enum H5FD_mem_t {
|
||||
* -QAK
|
||||
*/
|
||||
#define H5FD_MEM_FSPACE_HDR H5FD_MEM_OHDR
|
||||
#define H5FD_MEM_FSPACE_SECTS H5FD_MEM_LHEAP
|
||||
#define H5FD_MEM_FSPACE_SINFO H5FD_MEM_LHEAP
|
||||
|
||||
/*
|
||||
* A free-list map which maps all types of allocation requests to a single
|
||||
|
3102
src/H5FS.c
3102
src/H5FS.c
File diff suppressed because it is too large
Load Diff
780
src/H5FScache.c
780
src/H5FScache.c
@ -35,6 +35,7 @@
|
||||
#include "H5private.h" /* Generic Functions */
|
||||
#include "H5Eprivate.h" /* Error handling */
|
||||
#include "H5FSpkg.h" /* File free space */
|
||||
#include "H5Vprivate.h" /* Vectors and arrays */
|
||||
|
||||
/****************/
|
||||
/* Local Macros */
|
||||
@ -42,12 +43,20 @@
|
||||
|
||||
/* File free space format version #'s */
|
||||
#define H5FS_HDR_VERSION 0 /* Header */
|
||||
#define H5FS_SINFO_VERSION 0 /* Serialized sections */
|
||||
|
||||
|
||||
/******************/
|
||||
/* Local Typedefs */
|
||||
/******************/
|
||||
|
||||
/* User data for skip list iterator callback for iterating over section size nodes when syncing */
|
||||
typedef struct {
|
||||
H5FS_sinfo_t *sinfo; /* Free space section info */
|
||||
uint8_t **p; /* Pointer to address of buffer pointer to serialize with */
|
||||
unsigned sect_cnt_size; /* # of bytes to encode section size counts in */
|
||||
} H5FS_iter_ud_t;
|
||||
|
||||
|
||||
/********************/
|
||||
/* Package Typedefs */
|
||||
@ -58,11 +67,21 @@
|
||||
/* Local Prototypes */
|
||||
/********************/
|
||||
|
||||
/* Section info routines */
|
||||
static herr_t H5FS_sinfo_free_sect_cb(void *item, void *key, void *op_data);
|
||||
static herr_t H5FS_sinfo_free_node_cb(void *item, void *key, void *op_data);
|
||||
static herr_t H5FS_sinfo_serialize_sect_cb(void *_item, void UNUSED *key, void *_udata);
|
||||
static herr_t H5FS_sinfo_serialize_node_cb(void *_item, void UNUSED *key, void *_udata);
|
||||
|
||||
/* Metadata cache callbacks */
|
||||
static H5FS_hdr_t *H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
|
||||
static herr_t H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_hdr_t *hdr);
|
||||
static herr_t H5FS_cache_hdr_clear(H5F_t *f, H5FS_hdr_t *hdr, hbool_t destroy);
|
||||
static herr_t H5FS_cache_hdr_size(const H5F_t *f, const H5FS_hdr_t *hdr, size_t *size_ptr);
|
||||
static H5FS_t *H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
|
||||
static herr_t H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_t *fspace);
|
||||
static herr_t H5FS_cache_hdr_clear(H5F_t *f, H5FS_t *fspace, hbool_t destroy);
|
||||
static herr_t H5FS_cache_hdr_size(const H5F_t *f, const H5FS_t *fspace, size_t *size_ptr);
|
||||
static H5FS_sinfo_t *H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2);
|
||||
static herr_t H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_sinfo_t *sinfo);
|
||||
static herr_t H5FS_cache_sinfo_clear(H5F_t *f, H5FS_sinfo_t *sinfo, hbool_t destroy);
|
||||
static herr_t H5FS_cache_sinfo_size(const H5F_t *f, const H5FS_sinfo_t *sinfo, size_t *size_ptr);
|
||||
|
||||
/*********************/
|
||||
/* Package Variables */
|
||||
@ -78,6 +97,16 @@ const H5AC_class_t H5AC_FSPACE_HDR[1] = {{
|
||||
(H5AC_size_func_t)H5FS_cache_hdr_size,
|
||||
}};
|
||||
|
||||
/* H5FS serialized sections inherit cache-like properties from H5AC */
|
||||
const H5AC_class_t H5AC_FSPACE_SINFO[1] = {{
|
||||
H5AC_FSPACE_SINFO_ID,
|
||||
(H5AC_load_func_t)H5FS_cache_sinfo_load,
|
||||
(H5AC_flush_func_t)H5FS_cache_sinfo_flush,
|
||||
(H5AC_dest_func_t)H5FS_cache_sinfo_dest,
|
||||
(H5AC_clear_func_t)H5FS_cache_sinfo_clear,
|
||||
(H5AC_size_func_t)H5FS_cache_sinfo_size,
|
||||
}};
|
||||
|
||||
|
||||
/*****************************/
|
||||
/* Library Private Variables */
|
||||
@ -91,15 +120,17 @@ const H5AC_class_t H5AC_FSPACE_HDR[1] = {{
|
||||
/* Declare a free list to manage free space header data to/from disk */
|
||||
H5FL_BLK_DEFINE_STATIC(header_block);
|
||||
|
||||
/* Declare a free list to manage free space section data to/from disk */
|
||||
H5FL_BLK_DEFINE_STATIC(sect_block);
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_cache_hdr_load
|
||||
*
|
||||
* Purpose: Loads a free space header from the disk.
|
||||
* Purpose: Loads a free space manager header from the disk.
|
||||
*
|
||||
* Return: Success: Pointer to a new free space header
|
||||
*
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
@ -108,15 +139,17 @@ H5FL_BLK_DEFINE_STATIC(header_block);
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5FS_hdr_t *
|
||||
H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void UNUSED *udata2)
|
||||
static H5FS_t *
|
||||
H5FS_cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_fs_prot, void UNUSED *udata2)
|
||||
{
|
||||
H5FS_hdr_t *hdr = NULL; /* Free space header info */
|
||||
H5FS_t *fspace = NULL; /* Free space header info */
|
||||
const H5FS_prot_t *fs_prot = (const H5FS_prot_t *)_fs_prot; /* User data for protecting */
|
||||
size_t size; /* Header size */
|
||||
uint8_t *buf = NULL; /* Temporary buffer */
|
||||
const uint8_t *p; /* Pointer into raw data buffer */
|
||||
uint32_t metadata_chksum; /* Metadata checksum value */
|
||||
H5FS_hdr_t *ret_value; /* Return value */
|
||||
unsigned nclasses; /* Number of section classes */
|
||||
H5FS_t *ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_hdr_load)
|
||||
#ifdef QAK
|
||||
@ -126,11 +159,11 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
|
||||
/* Check arguments */
|
||||
HDassert(f);
|
||||
HDassert(H5F_addr_defined(addr));
|
||||
HDassert(fs_prot);
|
||||
|
||||
/* Allocate space for the free space header */
|
||||
if(NULL == (hdr = H5FL_MALLOC(H5FS_hdr_t)))
|
||||
/* Allocate a new free space manager */
|
||||
if(NULL == (fspace = H5FS_new(fs_prot->nclasses, fs_prot->classes, fs_prot->cls_init_udata)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
|
||||
HDmemset(&hdr->cache_info, 0, sizeof(H5AC_info_t));
|
||||
|
||||
/* Compute the size of the free space header on disk */
|
||||
size = H5FS_HEADER_SIZE(f);
|
||||
@ -166,56 +199,58 @@ HDfprintf(stderr, "%s: Load free space header, addr = %a\n", FUNC, addr);
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "incorrect metadata checksum for free space header")
|
||||
|
||||
/* Client ID */
|
||||
hdr->client = *p++;
|
||||
if(hdr->client >= H5FS_NUM_CLIENT_ID)
|
||||
fspace->client = *p++;
|
||||
if(fspace->client >= H5FS_NUM_CLIENT_ID)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "unknown client ID in free space header")
|
||||
|
||||
/* Total space tracked */
|
||||
H5F_DECODE_LENGTH(f, p, hdr->tot_space);
|
||||
H5F_DECODE_LENGTH(f, p, fspace->tot_space);
|
||||
|
||||
/* Total # of free space sections tracked */
|
||||
H5F_DECODE_LENGTH(f, p, hdr->tot_sect_count);
|
||||
H5F_DECODE_LENGTH(f, p, fspace->tot_sect_count);
|
||||
|
||||
/* # of serializable free space sections tracked */
|
||||
H5F_DECODE_LENGTH(f, p, hdr->serial_sect_count);
|
||||
H5F_DECODE_LENGTH(f, p, fspace->serial_sect_count);
|
||||
|
||||
/* # of ghost free space sections tracked */
|
||||
H5F_DECODE_LENGTH(f, p, hdr->ghost_sect_count);
|
||||
H5F_DECODE_LENGTH(f, p, fspace->ghost_sect_count);
|
||||
|
||||
/* # of section classes */
|
||||
UINT16DECODE(p, hdr->nclasses);
|
||||
UINT16DECODE(p, nclasses);
|
||||
if(fspace->nclasses != nclasses)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "unknown section class count mismatch")
|
||||
|
||||
/* Shrink percent */
|
||||
UINT16DECODE(p, hdr->shrink_percent);
|
||||
UINT16DECODE(p, fspace->shrink_percent);
|
||||
|
||||
/* Expand percent */
|
||||
UINT16DECODE(p, hdr->expand_percent);
|
||||
UINT16DECODE(p, fspace->expand_percent);
|
||||
|
||||
/* Size of address space free space sections are within (log2 of actual value) */
|
||||
UINT16DECODE(p, hdr->max_sect_addr);
|
||||
UINT16DECODE(p, fspace->max_sect_addr);
|
||||
|
||||
/* Max. size of section to track */
|
||||
H5F_DECODE_LENGTH(f, p, hdr->max_sect_size);
|
||||
H5F_DECODE_LENGTH(f, p, fspace->max_sect_size);
|
||||
|
||||
/* Address of serialized free space sections */
|
||||
H5F_addr_decode(f, &p, &hdr->sect_addr);
|
||||
H5F_addr_decode(f, &p, &fspace->sect_addr);
|
||||
|
||||
/* Size of serialized free space sections */
|
||||
H5F_DECODE_LENGTH(f, p, hdr->sect_size);
|
||||
H5F_DECODE_LENGTH(f, p, fspace->sect_size);
|
||||
|
||||
/* Allocated size of serialized free space sections */
|
||||
H5F_DECODE_LENGTH(f, p, hdr->alloc_sect_size);
|
||||
H5F_DECODE_LENGTH(f, p, fspace->alloc_sect_size);
|
||||
|
||||
HDassert((size_t)(p - buf) == size);
|
||||
|
||||
/* Set return value */
|
||||
ret_value = hdr;
|
||||
ret_value = fspace;
|
||||
|
||||
done:
|
||||
if(buf)
|
||||
H5FL_BLK_FREE(header_block, buf);
|
||||
if(!ret_value && hdr)
|
||||
(void)H5FS_cache_hdr_dest(f, hdr);
|
||||
if(!ret_value && fspace)
|
||||
(void)H5FS_cache_hdr_dest(f, fspace);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FS_cache_hdr_load() */ /*lint !e818 Can't make udata a pointer to const */
|
||||
@ -235,7 +270,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_hdr_t *hdr)
|
||||
H5FS_cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_t *fspace)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@ -247,9 +282,9 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
|
||||
/* check arguments */
|
||||
HDassert(f);
|
||||
HDassert(H5F_addr_defined(addr));
|
||||
HDassert(hdr);
|
||||
HDassert(fspace);
|
||||
|
||||
if(hdr->cache_info.is_dirty) {
|
||||
if(fspace->cache_info.is_dirty) {
|
||||
uint8_t *buf = NULL; /* Temporary raw data buffer */
|
||||
uint8_t *p; /* Pointer into raw data buffer */
|
||||
size_t size; /* Header size on disk */
|
||||
@ -280,43 +315,43 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
|
||||
p += 4;
|
||||
|
||||
/* Client ID */
|
||||
*p++ = hdr->client;
|
||||
*p++ = fspace->client;
|
||||
|
||||
/* Total space tracked */
|
||||
H5F_ENCODE_LENGTH(f, p, hdr->tot_space);
|
||||
H5F_ENCODE_LENGTH(f, p, fspace->tot_space);
|
||||
|
||||
/* Total # of free space sections tracked */
|
||||
H5F_ENCODE_LENGTH(f, p, hdr->tot_sect_count);
|
||||
H5F_ENCODE_LENGTH(f, p, fspace->tot_sect_count);
|
||||
|
||||
/* # of serializable free space sections tracked */
|
||||
H5F_ENCODE_LENGTH(f, p, hdr->serial_sect_count);
|
||||
H5F_ENCODE_LENGTH(f, p, fspace->serial_sect_count);
|
||||
|
||||
/* # of ghost free space sections tracked */
|
||||
H5F_ENCODE_LENGTH(f, p, hdr->ghost_sect_count);
|
||||
H5F_ENCODE_LENGTH(f, p, fspace->ghost_sect_count);
|
||||
|
||||
/* # of section classes */
|
||||
UINT16ENCODE(p, hdr->nclasses);
|
||||
UINT16ENCODE(p, fspace->nclasses);
|
||||
|
||||
/* Shrink percent */
|
||||
UINT16ENCODE(p, hdr->shrink_percent);
|
||||
UINT16ENCODE(p, fspace->shrink_percent);
|
||||
|
||||
/* Expand percent */
|
||||
UINT16ENCODE(p, hdr->expand_percent);
|
||||
UINT16ENCODE(p, fspace->expand_percent);
|
||||
|
||||
/* Size of address space free space sections are within (log2 of actual value) */
|
||||
UINT16ENCODE(p, hdr->max_sect_addr);
|
||||
UINT16ENCODE(p, fspace->max_sect_addr);
|
||||
|
||||
/* Max. size of section to track */
|
||||
H5F_ENCODE_LENGTH(f, p, hdr->max_sect_size);
|
||||
H5F_ENCODE_LENGTH(f, p, fspace->max_sect_size);
|
||||
|
||||
/* Address of serialized free space sections */
|
||||
H5F_addr_encode(f, &p, hdr->sect_addr);
|
||||
H5F_addr_encode(f, &p, fspace->sect_addr);
|
||||
|
||||
/* Size of serialized free space sections */
|
||||
H5F_ENCODE_LENGTH(f, p, hdr->sect_size);
|
||||
H5F_ENCODE_LENGTH(f, p, fspace->sect_size);
|
||||
|
||||
/* Allocated size of serialized free space sections */
|
||||
H5F_ENCODE_LENGTH(f, p, hdr->alloc_sect_size);
|
||||
H5F_ENCODE_LENGTH(f, p, fspace->alloc_sect_size);
|
||||
|
||||
/* Write the free space header. */
|
||||
HDassert((size_t)(p - buf) == size);
|
||||
@ -325,11 +360,11 @@ HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", F
|
||||
|
||||
H5FL_BLK_FREE(header_block, buf);
|
||||
|
||||
hdr->cache_info.is_dirty = FALSE;
|
||||
fspace->cache_info.is_dirty = FALSE;
|
||||
} /* end if */
|
||||
|
||||
if(destroy)
|
||||
if(H5FS_cache_hdr_dest(f, hdr) < 0)
|
||||
if(H5FS_cache_hdr_dest(f, fspace) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space header")
|
||||
|
||||
done:
|
||||
@ -352,19 +387,34 @@ done:
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
herr_t
|
||||
H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_hdr_t *hdr)
|
||||
H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_t *fspace)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_cache_hdr_dest)
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_hdr_dest)
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
HDassert(hdr);
|
||||
HDassert(fspace);
|
||||
|
||||
/* Free the shared info itself */
|
||||
H5FL_FREE(H5FS_hdr_t, hdr);
|
||||
/* Terminate the section classes for this free space list */
|
||||
for(u = 0; u < fspace->nclasses ; u++) {
|
||||
/* Call the class termination routine, if there is one */
|
||||
if(fspace->sect_cls[u].term_cls)
|
||||
if((fspace->sect_cls[u].term_cls)(&fspace->sect_cls[u]) < 0)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_CANTRELEASE, FAIL, "unable to finalize section class")
|
||||
} /* end for */
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
/* Release the memory for the free space section classes */
|
||||
fspace->sect_cls = H5FL_SEQ_FREE(H5FS_section_class_t, fspace->sect_cls);
|
||||
|
||||
/* Free free space info */
|
||||
H5FL_FREE(H5FS_t, fspace);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FS_cache_hdr_dest() */
|
||||
|
||||
|
||||
@ -382,7 +432,7 @@ H5FS_cache_hdr_dest(H5F_t UNUSED *f, H5FS_hdr_t *hdr)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_cache_hdr_clear(H5F_t *f, H5FS_hdr_t *hdr, hbool_t destroy)
|
||||
H5FS_cache_hdr_clear(H5F_t *f, H5FS_t *fspace, hbool_t destroy)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@ -391,13 +441,13 @@ H5FS_cache_hdr_clear(H5F_t *f, H5FS_hdr_t *hdr, hbool_t destroy)
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
HDassert(hdr);
|
||||
HDassert(fspace);
|
||||
|
||||
/* Reset the dirty flag. */
|
||||
hdr->cache_info.is_dirty = FALSE;
|
||||
fspace->cache_info.is_dirty = FALSE;
|
||||
|
||||
if(destroy)
|
||||
if(H5FS_cache_hdr_dest(f, hdr) < 0)
|
||||
if(H5FS_cache_hdr_dest(f, fspace) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space header")
|
||||
|
||||
done:
|
||||
@ -421,13 +471,13 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_cache_hdr_size(const H5F_t *f, const H5FS_hdr_t *hdr, size_t *size_ptr)
|
||||
H5FS_cache_hdr_size(const H5F_t *f, const H5FS_t *fspace, size_t *size_ptr)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_cache_hdr_size)
|
||||
|
||||
/* check arguments */
|
||||
HDassert(f);
|
||||
HDassert(hdr);
|
||||
HDassert(fspace);
|
||||
HDassert(size_ptr);
|
||||
|
||||
/* Set size value */
|
||||
@ -436,3 +486,613 @@ H5FS_cache_hdr_size(const H5F_t *f, const H5FS_hdr_t *hdr, size_t *size_ptr)
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* H5FS_cache_hdr_size() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_cache_sinfo_load
|
||||
*
|
||||
* Purpose: Loads free space sections from the disk.
|
||||
*
|
||||
* Return: Success: Pointer to a new free space section info
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@ncsa.uiuc.edu
|
||||
* July 31 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5FS_sinfo_t *
|
||||
H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *udata1, void *_fspace)
|
||||
{
|
||||
H5FS_sinfo_t *sinfo = NULL; /* Free space section info */
|
||||
H5FS_t *fspace = (H5FS_t *)_fspace; /* User data for protecting */
|
||||
haddr_t fs_addr; /* Free space header address */
|
||||
size_t old_sect_size; /* Old section size */
|
||||
uint8_t *buf = NULL; /* Temporary buffer */
|
||||
const uint8_t *p; /* Pointer into raw data buffer */
|
||||
uint32_t metadata_chksum; /* Metadata checksum value */
|
||||
H5FS_sinfo_t *ret_value; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_load)
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Load free space sections, addr = %a\n", FUNC, addr);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Check arguments */
|
||||
HDassert(f);
|
||||
HDassert(H5F_addr_defined(addr));
|
||||
HDassert(fspace);
|
||||
|
||||
/* Allocate a new free space section info */
|
||||
if(NULL == (sinfo = H5FS_sinfo_new(f, fspace)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
|
||||
|
||||
/* Link free space manager to section info */
|
||||
/* (for deserializing sections) */
|
||||
HDassert(fspace->sinfo == NULL);
|
||||
fspace->sinfo = sinfo;
|
||||
|
||||
/* Allocate space for the buffer to serialize the sections into */
|
||||
old_sect_size = fspace->sect_size;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: fspace->sect_size = %Hu\n", FUNC, fspace->sect_size);
|
||||
#endif /* QAK */
|
||||
if(NULL == (buf = H5FL_BLK_MALLOC(sect_block, (size_t)fspace->sect_size)))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
|
||||
|
||||
/* Read buffer from disk */
|
||||
if(H5F_block_read(f, H5FD_MEM_FSPACE_SINFO, fspace->sect_addr, (size_t)fspace->sect_size, dxpl_id, buf) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_READERROR, NULL, "can't read free space sections")
|
||||
|
||||
/* Deserialize free sections from buffer available */
|
||||
p = buf;
|
||||
|
||||
/* Magic number */
|
||||
if(HDmemcmp(p, H5FS_SINFO_MAGIC, H5FS_SIZEOF_MAGIC))
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space sections signature")
|
||||
p += H5FS_SIZEOF_MAGIC;
|
||||
|
||||
/* Version */
|
||||
if(*p++ != H5FS_SINFO_VERSION)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "wrong free space sections version")
|
||||
|
||||
/* Metadata flags (unused, currently) */
|
||||
/* XXX: Plan out metadata flags (including "read-only duplicate" feature) */
|
||||
if(*p++ != 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "unknown metadata flag in free space sections")
|
||||
|
||||
/* Metadata checksum (unused, currently) */
|
||||
UINT32DECODE(p, metadata_chksum);
|
||||
/* XXX: Verify checksum */
|
||||
if(metadata_chksum != 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "incorrect metadata checksum for free space sections")
|
||||
|
||||
/* Address of free space header for these sections */
|
||||
H5F_addr_decode(f, &p, &fs_addr);
|
||||
if(H5F_addr_ne(fs_addr, fspace->addr))
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, NULL, "incorrect header address for free space sections")
|
||||
|
||||
/* Check for any serialized sections */
|
||||
if(fspace->serial_sect_count > 0) {
|
||||
hsize_t old_tot_sect_count; /* Total section count from header */
|
||||
hsize_t old_serial_sect_count; /* Total serializable section count from header */
|
||||
hsize_t old_ghost_sect_count; /* Total ghost section count from header */
|
||||
hsize_t old_tot_space; /* Total space managed from header */
|
||||
unsigned sect_cnt_size; /* The size of the section size counts */
|
||||
|
||||
/* Compute the size of the section counts */
|
||||
sect_cnt_size = MAX(1, (H5V_log2_gen(fspace->serial_sect_count) + 7) / 8);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sect_cnt_size = %u\n", FUNC, sect_cnt_size);
|
||||
HDfprintf(stderr, "%s: fspace->sect_len_size = %u\n", FUNC, fspace->sect_len_size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Reset the section count, the "add" routine will update it */
|
||||
old_tot_sect_count = fspace->tot_sect_count;
|
||||
old_serial_sect_count = fspace->serial_sect_count;
|
||||
old_ghost_sect_count = fspace->ghost_sect_count;
|
||||
old_tot_space = fspace->tot_space;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: fspace->tot_sect_count = %Hu\n", FUNC, fspace->tot_sect_count);
|
||||
HDfprintf(stderr, "%s: fspace->serial_sect_count = %Hu\n", FUNC, fspace->serial_sect_count);
|
||||
HDfprintf(stderr, "%s: fspace->ghost_sect_count = %Hu\n", FUNC, fspace->ghost_sect_count);
|
||||
HDfprintf(stderr, "%s: fspace->tot_space = %Hu\n", FUNC, fspace->tot_space);
|
||||
#endif /* QAK */
|
||||
fspace->tot_sect_count = 0;
|
||||
fspace->serial_sect_count = 0;
|
||||
fspace->ghost_sect_count = 0;
|
||||
fspace->tot_space = 0;
|
||||
|
||||
/* Walk through the buffer, deserializing sections */
|
||||
do {
|
||||
hsize_t sect_size; /* Current section size */
|
||||
size_t node_count; /* # of sections of this size */
|
||||
size_t u; /* Local index variable */
|
||||
|
||||
/* The number of sections of this node's size */
|
||||
UINT64DECODE_VAR(p, node_count, sect_cnt_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: node_count = %Zu\n", FUNC, node_count);
|
||||
#endif /* QAK */
|
||||
HDassert(node_count);
|
||||
|
||||
/* The size of the sections for this node */
|
||||
UINT64DECODE_VAR(p, sect_size, sinfo->sect_len_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sect_size = %Hu\n", FUNC, sect_size);
|
||||
#endif /* QAK */
|
||||
HDassert(sect_size);
|
||||
|
||||
/* Loop over nodes of this size */
|
||||
for(u = 0; u < node_count; u++) {
|
||||
H5FS_section_info_t *new_sect; /* Section that was deserialized */
|
||||
haddr_t sect_addr; /* Address of free space section in the address space */
|
||||
unsigned sect_type; /* Type of free space section */
|
||||
unsigned des_flags; /* Flags from deserialize callback */
|
||||
|
||||
/* The address of the section */
|
||||
UINT64DECODE_VAR(p, sect_addr, sinfo->sect_off_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sect_addr = %a\n", FUNC, sect_addr);
|
||||
#endif /* QAK */
|
||||
|
||||
/* The type of this section */
|
||||
sect_type = *p++;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sect_type = %u\n", FUNC, sect_type);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Call 'deserialize' callback for this section */
|
||||
des_flags = 0;
|
||||
HDassert(fspace->sect_cls[sect_type].deserialize);
|
||||
if(NULL == (new_sect = (*fspace->sect_cls[sect_type].deserialize)(&fspace->sect_cls[sect_type], dxpl_id, p, sect_addr, sect_size, &des_flags)))
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTDECODE, NULL, "can't deserialize section")
|
||||
|
||||
/* Update offset in serialization buffer */
|
||||
p += fspace->sect_cls[sect_type].serial_size;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: fspace->sect_cls[%u].serial_size = %Zu\n", FUNC, sect_type, fspace->sect_cls[sect_type].serial_size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Insert section in free space manager, unless requested not to */
|
||||
if(!(des_flags & H5FS_DESERIALIZE_NO_ADD))
|
||||
if(H5FS_sect_add(f, dxpl_id, fspace, new_sect, H5FS_ADD_DESERIALIZING, NULL) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTINSERT, NULL, "can't add section to free space manager")
|
||||
} /* end for */
|
||||
} while(p < (buf + old_sect_size));
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((size_t)(p - buf) == old_sect_size);
|
||||
HDassert(old_sect_size == fspace->sect_size);
|
||||
HDassert(old_tot_sect_count == fspace->tot_sect_count);
|
||||
HDassert(old_serial_sect_count == fspace->serial_sect_count);
|
||||
HDassert(old_ghost_sect_count == fspace->ghost_sect_count);
|
||||
HDassert(old_tot_space == fspace->tot_space);
|
||||
} /* end if */
|
||||
|
||||
/* Set return value */
|
||||
ret_value = sinfo;
|
||||
|
||||
done:
|
||||
if(buf)
|
||||
H5FL_BLK_FREE(sect_block, buf);
|
||||
if(!ret_value && sinfo)
|
||||
(void)H5FS_cache_sinfo_dest(f, sinfo);
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FS_cache_sinfo_load() */ /*lint !e818 Can't make udata a pointer to const */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_sinfo_serialize_sect_cb
|
||||
*
|
||||
* Purpose: Skip list iterator callback to serialize free space sections
|
||||
* of a particular size
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Monday, May 8, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_sinfo_serialize_sect_cb(void *_item, void UNUSED *key, void *_udata)
|
||||
{
|
||||
H5FS_section_class_t *sect_cls; /* Class of section */
|
||||
H5FS_section_info_t *sect= (H5FS_section_info_t *)_item; /* Free space section to work on */
|
||||
H5FS_iter_ud_t *udata = (H5FS_iter_ud_t *)_udata; /* Callback info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_serialize_sect_cb)
|
||||
|
||||
/* Check arguments. */
|
||||
HDassert(sect);
|
||||
HDassert(udata->sinfo);
|
||||
HDassert(udata->p);
|
||||
|
||||
/* Get section's class */
|
||||
sect_cls = &udata->sinfo->fspace->sect_cls[sect->type];
|
||||
|
||||
/* Check if this section should be serialized (i.e. is not a ghost section) */
|
||||
if(!(sect_cls->flags & H5FS_CLS_GHOST_OBJ)) {
|
||||
/* The address of the section */
|
||||
UINT64ENCODE_VAR(*udata->p, sect->addr, udata->sinfo->sect_off_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sect->addr = %a\n", FUNC, sect->addr);
|
||||
#endif /* QAK */
|
||||
|
||||
/* The type of this section */
|
||||
*(*udata->p)++ = (uint8_t)sect->type;
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sect->type = %u\n", FUNC, (unsigned)sect->type);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Call 'serialize' callback for this section */
|
||||
if(sect_cls->serialize) {
|
||||
if((*sect_cls->serialize)(sect_cls, sect, *udata->p) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTSERIALIZE, FAIL, "can't syncronize section")
|
||||
|
||||
/* Update offset in serialization buffer */
|
||||
(*udata->p) += sect_cls->serial_size;
|
||||
} /* end if */
|
||||
else
|
||||
HDassert(sect_cls->serial_size == 0);
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5FS_sinfo_serialize_sect_cb() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_sinfo_serialize_node_cb
|
||||
*
|
||||
* Purpose: Skip list iterator callback to serialize free space sections
|
||||
* in a bin
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Monday, May 8, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_sinfo_serialize_node_cb(void *_item, void UNUSED *key, void *_udata)
|
||||
{
|
||||
H5FS_node_t *fspace_node = (H5FS_node_t *)_item; /* Free space size node to work on */
|
||||
H5FS_iter_ud_t *udata = (H5FS_iter_ud_t *)_udata; /* Callback info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_sinfo_serialize_node_cb)
|
||||
|
||||
/* Check arguments. */
|
||||
HDassert(fspace_node);
|
||||
HDassert(udata->sinfo);
|
||||
HDassert(udata->p);
|
||||
|
||||
/* Check if this node has any serializable sections */
|
||||
if(fspace_node->serial_count > 0) {
|
||||
/* The number of serializable sections of this node's size */
|
||||
UINT64ENCODE_VAR(*udata->p, fspace_node->serial_count, udata->sect_cnt_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: fspace_node->serial_count = %Zu\n", FUNC, fspace_node->serial_count);
|
||||
#endif /* QAK */
|
||||
|
||||
/* The size of the sections for this node */
|
||||
UINT64ENCODE_VAR(*udata->p, fspace_node->sect_size, udata->sinfo->sect_len_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sect_size = %Hu\n", FUNC, fspace_node->sect_size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Iterate through all the sections of this size */
|
||||
HDassert(fspace_node->sect_list);
|
||||
if(H5SL_iterate(fspace_node->sect_list, H5FS_sinfo_serialize_sect_cb, udata) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over section nodes")
|
||||
} /* end if */
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5FS_sinfo_serialize_node_cb() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_cache_sinfo_flush
|
||||
*
|
||||
* Purpose: Flushes a dirty free space section info to disk.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@ncsa.uiuc.edu
|
||||
* July 31 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_cache_sinfo_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FS_sinfo_t *sinfo)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_flush)
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Flushing free space header, addr = %a, destroy = %u\n", FUNC, addr, (unsigned)destroy);
|
||||
#endif /* QAK */
|
||||
|
||||
/* check arguments */
|
||||
HDassert(f);
|
||||
HDassert(H5F_addr_defined(addr));
|
||||
HDassert(sinfo);
|
||||
|
||||
if(sinfo->cache_info.is_dirty) {
|
||||
H5FS_iter_ud_t udata; /* User data for callbacks */
|
||||
uint8_t *buf = NULL; /* Temporary raw data buffer */
|
||||
uint8_t *p; /* Pointer into raw data buffer */
|
||||
unsigned bin; /* Current bin we are on */
|
||||
|
||||
/* Allocate temporary buffer */
|
||||
if((buf = H5FL_BLK_MALLOC(sect_block, (size_t)sinfo->fspace->sect_size)) == NULL)
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
|
||||
|
||||
p = buf;
|
||||
|
||||
/* Magic number */
|
||||
HDmemcpy(p, H5FS_SINFO_MAGIC, H5FS_SIZEOF_MAGIC);
|
||||
p += H5FS_SIZEOF_MAGIC;
|
||||
|
||||
/* Version # */
|
||||
*p++ = H5FS_SINFO_VERSION;
|
||||
|
||||
/* Metadata status flags */
|
||||
/* XXX: Set this? */
|
||||
*p++ = 0;
|
||||
|
||||
/* Metadata checksum */
|
||||
/* XXX: Set this! (After all the metadata is in the buffer) */
|
||||
HDmemset(p, 0, 4);
|
||||
p += 4;
|
||||
|
||||
/* Address of free space header for these sections */
|
||||
H5F_addr_encode(f, &p, sinfo->fspace->addr);
|
||||
|
||||
/* Set up user data for iterator */
|
||||
udata.sinfo = sinfo;
|
||||
udata.p = &p;
|
||||
udata.sect_cnt_size = MAX(1, (H5V_log2_gen(sinfo->fspace->serial_sect_count) + 7) / 8);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: udata.sect_cnt_size = %u\n", FUNC, udata.sect_cnt_size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Iterate over all the bins */
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: Serializing section bins\n", FUNC);
|
||||
#endif /* QAK */
|
||||
for(bin = 0; bin < sinfo->nbins; bin++) {
|
||||
/* Check if there are any sections in this bin */
|
||||
if(sinfo->bins[bin].bin_list) {
|
||||
/* Iterate over list of section size nodes for bin */
|
||||
if(H5SL_iterate(sinfo->bins[bin].bin_list, H5FS_sinfo_serialize_node_cb, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_BADITER, FAIL, "can't iterate over section size nodes")
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
|
||||
/* Sanity check */
|
||||
HDassert((size_t)(p - buf) == sinfo->fspace->sect_size);
|
||||
HDassert(sinfo->fspace->sect_size <= sinfo->fspace->alloc_sect_size);
|
||||
#ifdef QAK
|
||||
HDfprintf(stderr, "%s: sinfo->fspace->sect_size = %Hu\n", FUNC, sinfo->fspace->sect_size);
|
||||
HDfprintf(stderr, "%s: sinfo->fspace->alloc_sect_size = %Hu\n", FUNC, sinfo->fspace->alloc_sect_size);
|
||||
#endif /* QAK */
|
||||
|
||||
/* Write buffer to disk */
|
||||
if(H5F_block_write(f, H5FD_MEM_FSPACE_SINFO, sinfo->fspace->sect_addr, (size_t)sinfo->fspace->sect_size, dxpl_id, buf) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFLUSH, FAIL, "unable to save free space sections to disk")
|
||||
|
||||
H5FL_BLK_FREE(sect_block, buf);
|
||||
|
||||
sinfo->cache_info.is_dirty = FALSE;
|
||||
} /* end if */
|
||||
|
||||
if(destroy)
|
||||
if(H5FS_cache_sinfo_dest(f, sinfo) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space section info")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5FS_cache_sinfo_flush() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_sinfo_free_sect_cb
|
||||
*
|
||||
* Purpose: Free a size-tracking node for a bin
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Saturday, March 11, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_sinfo_free_sect_cb(void *_sect, void UNUSED *key, void *op_data)
|
||||
{
|
||||
H5FS_section_info_t *sect = (H5FS_section_info_t *)_sect; /* Section to free */
|
||||
const H5FS_sinfo_t *sinfo = (const H5FS_sinfo_t *)op_data; /* Free space manager for section */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_sect_cb)
|
||||
|
||||
HDassert(sect);
|
||||
HDassert(sinfo);
|
||||
|
||||
/* Call the section's class 'free' method on the section */
|
||||
(*sinfo->fspace->sect_cls[sect->type].free)(sect);
|
||||
|
||||
FUNC_LEAVE_NOAPI(0)
|
||||
} /* H5FS_sinfo_free_sect_cb() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_sinfo_free_node_cb
|
||||
*
|
||||
* Purpose: Free a size-tracking node for a bin
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
*
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Saturday, March 11, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_sinfo_free_node_cb(void *item, void UNUSED *key, void *op_data)
|
||||
{
|
||||
H5FS_node_t *fspace_node = (H5FS_node_t *)item; /* Temporary pointer to free space list node */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_sinfo_free_node_cb)
|
||||
|
||||
HDassert(fspace_node);
|
||||
HDassert(op_data);
|
||||
|
||||
/* Release the skip list for sections of this size */
|
||||
H5SL_destroy(fspace_node->sect_list, H5FS_sinfo_free_sect_cb, op_data);
|
||||
|
||||
/* Release free space list node */
|
||||
H5FL_FREE(H5FS_node_t, fspace_node);
|
||||
|
||||
FUNC_LEAVE_NOAPI(0)
|
||||
} /* H5FS_sinfo_free_node_cb() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_cache_sinfo_dest
|
||||
*
|
||||
* Purpose: Destroys a free space section info in memory.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@ncsa.uiuc.edu
|
||||
* July 31 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
herr_t
|
||||
H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo)
|
||||
{
|
||||
unsigned u; /* Local index variable */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_dest)
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
HDassert(sinfo);
|
||||
HDassert(sinfo->fspace);
|
||||
HDassert(sinfo->bins);
|
||||
|
||||
/* Clear out lists of nodes */
|
||||
for(u = 0; u < sinfo->nbins; u++)
|
||||
if(sinfo->bins[u].bin_list) {
|
||||
H5SL_destroy(sinfo->bins[u].bin_list, H5FS_sinfo_free_node_cb, sinfo);
|
||||
sinfo->bins[u].bin_list = NULL;
|
||||
} /* end if */
|
||||
|
||||
/* Release bins for skip lists */
|
||||
sinfo->bins = H5FL_SEQ_FREE(H5FS_bin_t, sinfo->bins);
|
||||
|
||||
/* Release skip list for merging sections */
|
||||
if(sinfo->merge_list)
|
||||
if(H5SL_close(sinfo->merge_list) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTCLOSEOBJ, FAIL, "can't destroy section merging skip list")
|
||||
|
||||
/* Unpin the free space header in the cache */
|
||||
/* (make certain this is last action with section info, to allow for header
|
||||
* disappearing immediately)
|
||||
*/
|
||||
if(H5AC_unpin_entry(f, sinfo->fspace) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTUNPIN, FAIL, "unable to unpin free space header")
|
||||
|
||||
/* Release free space section info */
|
||||
H5FL_FREE(H5FS_sinfo_t, sinfo);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FS_cache_sinfo_dest() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_cache_sinfo_clear
|
||||
*
|
||||
* Purpose: Mark a free space section info in memory as non-dirty.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@ncsa.uiuc.edu
|
||||
* July 31 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_cache_sinfo_clear(H5F_t *f, H5FS_sinfo_t *sinfo, hbool_t destroy)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5FS_cache_sinfo_clear)
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
*/
|
||||
HDassert(sinfo);
|
||||
|
||||
/* Reset the dirty flag. */
|
||||
sinfo->cache_info.is_dirty = FALSE;
|
||||
|
||||
if(destroy)
|
||||
if(H5FS_cache_sinfo_dest(f, sinfo) < 0)
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTFREE, FAIL, "unable to destroy free space section info")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FS_cache_sinfo_clear() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_cache_sinfo_size
|
||||
*
|
||||
* Purpose: Compute the size in bytes of a free space section info
|
||||
* on disk, and return it in *size_ptr. On failure,
|
||||
* the value of *size_ptr is undefined.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* koziol@ncsa.uiuc.edu
|
||||
* July 31 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5FS_cache_sinfo_size(const H5F_t UNUSED *f, const H5FS_sinfo_t *sinfo, size_t *size_ptr)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FS_cache_sinfo_size)
|
||||
|
||||
/* check arguments */
|
||||
HDassert(sinfo);
|
||||
HDassert(size_ptr);
|
||||
|
||||
/* Set size value */
|
||||
*size_ptr = sinfo->fspace->sect_size;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* H5FS_cache_sinfo_size() */
|
||||
|
||||
|
@ -74,9 +74,9 @@
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5FS_hdr_debug
|
||||
* Function: H5FS_debug
|
||||
*
|
||||
* Purpose: Prints debugging info about a free space header.
|
||||
* Purpose: Prints debugging info about a free space manager.
|
||||
*
|
||||
* Return: Non-negative on success/Negative on failure
|
||||
*
|
||||
@ -87,12 +87,13 @@
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5FS_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
|
||||
H5FS_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
|
||||
{
|
||||
H5FS_hdr_t *hdr = NULL; /* Free space header info */
|
||||
H5FS_t *fspace = NULL; /* Free space header info */
|
||||
H5FS_prot_t fs_prot; /* Information for protecting free space manager */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI(H5FS_hdr_debug, FAIL)
|
||||
FUNC_ENTER_NOAPI(H5FS_debug, FAIL)
|
||||
|
||||
/*
|
||||
* Check arguments.
|
||||
@ -103,10 +104,15 @@ H5FS_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
|
||||
HDassert(indent >= 0);
|
||||
HDassert(fwidth >= 0);
|
||||
|
||||
/* Initialize user data for protecting the free space manager */
|
||||
fs_prot.nclasses = 0;
|
||||
fs_prot.classes = NULL;
|
||||
fs_prot.cls_init_udata = NULL;
|
||||
|
||||
/*
|
||||
* Load the free space header.
|
||||
*/
|
||||
if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, addr, NULL, NULL, H5AC_READ)))
|
||||
if(NULL == (fspace = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, addr, &fs_prot, NULL, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, FAIL, "unable to load free space header")
|
||||
|
||||
/* Print opening message */
|
||||
@ -117,50 +123,50 @@ H5FS_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent,
|
||||
*/
|
||||
HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
|
||||
"Free space client:",
|
||||
(hdr->client == H5FS_CLIENT_FHEAP_ID ? "Fractal heap" : "Unknown"));
|
||||
(fspace->client == H5FS_CLIENT_FHEAP_ID ? "Fractal heap" : "Unknown"));
|
||||
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
|
||||
"Total free space tracked:",
|
||||
hdr->tot_space);
|
||||
fspace->tot_space);
|
||||
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
|
||||
"Total number of free space sections tracked:",
|
||||
hdr->tot_sect_count);
|
||||
fspace->tot_sect_count);
|
||||
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
|
||||
"Number of serializable free space sections tracked:",
|
||||
hdr->serial_sect_count);
|
||||
fspace->serial_sect_count);
|
||||
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
|
||||
"Number of ghost free space sections tracked:",
|
||||
hdr->ghost_sect_count);
|
||||
fspace->ghost_sect_count);
|
||||
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
|
||||
"Number of free space section classes:",
|
||||
hdr->nclasses);
|
||||
fspace->nclasses);
|
||||
HDfprintf(stream, "%*s%-*s %u%%\n", indent, "", fwidth,
|
||||
"Shrink percent:",
|
||||
hdr->shrink_percent);
|
||||
fspace->shrink_percent);
|
||||
HDfprintf(stream, "%*s%-*s %u%%\n", indent, "", fwidth,
|
||||
"Expand percent:",
|
||||
hdr->expand_percent);
|
||||
fspace->expand_percent);
|
||||
HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
|
||||
"# of bits for section address space:",
|
||||
hdr->max_sect_addr);
|
||||
fspace->max_sect_addr);
|
||||
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
|
||||
"Maximum section size:",
|
||||
hdr->max_sect_size);
|
||||
fspace->max_sect_size);
|
||||
HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
|
||||
"Serialized sections address:",
|
||||
hdr->sect_addr);
|
||||
fspace->sect_addr);
|
||||
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
|
||||
"Serialized sections size used:",
|
||||
hdr->sect_size);
|
||||
fspace->sect_size);
|
||||
HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
|
||||
"Serialized sections size allocated:",
|
||||
hdr->alloc_sect_size);
|
||||
fspace->alloc_sect_size);
|
||||
|
||||
done:
|
||||
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0)
|
||||
if(fspace && H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, addr, fspace, H5AC__NO_FLAGS_SET) < 0)
|
||||
HDONE_ERROR(H5E_FSPACE, H5E_PROTECT, FAIL, "unable to release free space header")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5FS_hdr_debug() */
|
||||
} /* end H5FS_debug() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -219,7 +225,8 @@ herr_t
|
||||
H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth,
|
||||
haddr_t fs_addr, haddr_t client_addr)
|
||||
{
|
||||
H5FS_hdr_t *hdr = NULL; /* Free space header info */
|
||||
H5FS_t *fspace = NULL; /* Free space header info */
|
||||
H5FS_prot_t fs_prot; /* Information for protecting free space manager */
|
||||
H5FS_client_t client; /* The client of the free space */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@ -236,19 +243,24 @@ H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent
|
||||
HDassert(H5F_addr_defined(fs_addr));
|
||||
HDassert(H5F_addr_defined(client_addr));
|
||||
|
||||
/* Initialize user data for protecting the free space manager */
|
||||
fs_prot.nclasses = 0;
|
||||
fs_prot.classes = NULL;
|
||||
fs_prot.cls_init_udata = NULL;
|
||||
|
||||
/*
|
||||
* Load the free space header.
|
||||
*/
|
||||
if(NULL == (hdr = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, NULL, NULL, H5AC_READ)))
|
||||
if(NULL == (fspace = H5AC_protect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, &fs_prot, NULL, H5AC_READ)))
|
||||
HGOTO_ERROR(H5E_FSPACE, H5E_CANTLOAD, FAIL, "unable to load free space header")
|
||||
|
||||
/* Retrieve the client id */
|
||||
client = hdr->client;
|
||||
client = fspace->client;
|
||||
|
||||
/* Release the free space header */
|
||||
if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
|
||||
if(H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__NO_FLAGS_SET) < 0)
|
||||
HDONE_ERROR(H5E_FSPACE, H5E_PROTECT, FAIL, "unable to release free space header")
|
||||
hdr = NULL;
|
||||
fspace = NULL;
|
||||
|
||||
/* Print opening message */
|
||||
HDfprintf(stream, "%*sFree Space Sections...\n", indent, "");
|
||||
@ -268,7 +280,7 @@ H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent
|
||||
} /* end switch */
|
||||
|
||||
done:
|
||||
if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, hdr, H5AC__NO_FLAGS_SET) < 0)
|
||||
if(fspace && H5AC_unprotect(f, dxpl_id, H5AC_FSPACE_HDR, fs_addr, fspace, H5AC__NO_FLAGS_SET) < 0)
|
||||
HDONE_ERROR(H5E_FSPACE, H5E_PROTECT, FAIL, "unable to release free space header")
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
|
140
src/H5FSpkg.h
140
src/H5FSpkg.h
@ -27,11 +27,15 @@
|
||||
#ifndef _H5FSpkg_H
|
||||
#define _H5FSpkg_H
|
||||
|
||||
/* Uncomment this macro to enable extra sanity checking */
|
||||
/* #define H5FS_DEBUG */
|
||||
|
||||
/* Get package's private header */
|
||||
#include "H5FSprivate.h" /* File free space */
|
||||
|
||||
/* Other private headers needed by this file */
|
||||
#include "H5ACprivate.h" /* Metadata cache */
|
||||
#include "H5SLprivate.h" /* Skip lists */
|
||||
|
||||
/**************************/
|
||||
/* Package Private Macros */
|
||||
@ -42,7 +46,7 @@
|
||||
|
||||
/* Free space signatures */
|
||||
#define H5FS_HDR_MAGIC "FSHD" /* Header */
|
||||
#define H5FS_SECTS_MAGIC "FSSS" /* Serialized sections */
|
||||
#define H5FS_SINFO_MAGIC "FSSE" /* Serialized sections */
|
||||
|
||||
/* "Standard" size of prefix information for free space metadata */
|
||||
#define H5FS_METADATA_PREFIX_SIZE ( \
|
||||
@ -73,34 +77,26 @@
|
||||
+ H5F_SIZEOF_SIZE(f) /* Allocated size of serialized free space sections */ \
|
||||
)
|
||||
|
||||
/* Size of the free space serialized sections on disk */
|
||||
#define H5FS_SINFO_PREFIX_SIZE(f) ( \
|
||||
/* General metadata fields */ \
|
||||
H5FS_METADATA_PREFIX_SIZE \
|
||||
\
|
||||
/* Free space serialized sections specific fields */ \
|
||||
+ H5F_SIZEOF_ADDR(f) /* Address of free space header for these sections */ \
|
||||
)
|
||||
|
||||
|
||||
/****************************/
|
||||
/* Package Private Typedefs */
|
||||
/****************************/
|
||||
|
||||
/* Free space header info */
|
||||
typedef struct H5FS_hdr_t {
|
||||
/* Information for H5AC cache functions, _must_ be first field in structure */
|
||||
H5AC_info_t cache_info;
|
||||
|
||||
/* Statistics */
|
||||
hsize_t tot_space; /* Total amount of space tracked */
|
||||
hsize_t tot_sect_count; /* Total # of sections tracked */
|
||||
hsize_t serial_sect_count; /* # of serializable sections tracked */
|
||||
hsize_t ghost_sect_count; /* # of un-serializable sections tracked */
|
||||
|
||||
/* Creation information */
|
||||
H5FS_client_t client; /* Type of user of this free space manager */
|
||||
unsigned nclasses; /* Number of section classes handled */
|
||||
unsigned shrink_percent; /* Percent of "normal" serialized size to shrink serialized space at */
|
||||
unsigned expand_percent; /* Percent of "normal" serialized size to expand serialized space at */
|
||||
unsigned max_sect_addr; /* Size of address space free sections are within (log2 of actual value) */
|
||||
hsize_t max_sect_size; /* Maximum size of section to track */
|
||||
|
||||
/* Serialized space information */
|
||||
haddr_t sect_addr; /* Address of the section info in the file */
|
||||
hsize_t sect_size; /* Size of the section info in the file */
|
||||
hsize_t alloc_sect_size; /* Allocated size of the section info in the file */
|
||||
} H5FS_hdr_t;
|
||||
/* Information for protecting a free space manager header */
|
||||
typedef struct H5FS_prot_t {
|
||||
size_t nclasses; /* Number of section classes */
|
||||
const H5FS_section_class_t **classes; /* Array of section class info */
|
||||
void *cls_init_udata; /* Pointer to class init user data */
|
||||
} H5FS_prot_t;
|
||||
|
||||
/* Free space section bin info */
|
||||
typedef struct H5FS_bin_t {
|
||||
@ -110,13 +106,23 @@ typedef struct H5FS_bin_t {
|
||||
H5SL_t *bin_list; /* Skip list of differently sized sections */
|
||||
} H5FS_bin_t;
|
||||
|
||||
/* Main free space info */
|
||||
struct H5FS_t {
|
||||
/* Stored values (from header) */
|
||||
H5FS_hdr_t *hdr; /* Pointer to header info */
|
||||
/* Free space node for free space sections of the same size */
|
||||
typedef struct H5FS_node_t {
|
||||
hsize_t sect_size; /* Size of all sections on list */
|
||||
size_t serial_count; /* # of serializable sections on list */
|
||||
size_t ghost_count; /* # of un-serializable sections on list */
|
||||
H5SL_t *sect_list; /* Skip list to hold pointers to actual free list section node */
|
||||
} H5FS_node_t;
|
||||
|
||||
/* Computed/cached values */
|
||||
haddr_t addr; /* Address of free space header on disk */
|
||||
/* Information about sections managed */
|
||||
typedef struct H5FS_sinfo_t {
|
||||
/* Information for H5AC cache functions, _must_ be first field in structure */
|
||||
H5AC_info_t cache_info;
|
||||
|
||||
/* Stored information */
|
||||
H5FS_bin_t *bins; /* Array of lists of lists of free sections */
|
||||
|
||||
/* Computed/cached values */
|
||||
unsigned nbins; /* Number of bins */
|
||||
size_t serial_size; /* Total size of all serializable sections */
|
||||
size_t tot_size_count; /* Total number of differently sized sections */
|
||||
@ -125,14 +131,43 @@ struct H5FS_t {
|
||||
unsigned sect_prefix_size; /* Size of the section serialization prefix (in bytes) */
|
||||
unsigned sect_off_size; /* Size of a section offset (in bytes) */
|
||||
unsigned sect_len_size; /* Size of a section length (in bytes) */
|
||||
hbool_t must_deserialize; /* Sections must be deserialized */
|
||||
hbool_t dirty; /* Space information is dirty */
|
||||
H5FS_t *fspace; /* Pointer to free space manager that owns sections */
|
||||
|
||||
/* Memory data structures (not stored directly) */
|
||||
H5FS_section_class_t *sect_cls; /* Array of section classes for this free list */
|
||||
H5FS_section_info_t *single; /* Section information when free list has only one free section */
|
||||
/* Memory data structures (not stored directly) */
|
||||
H5SL_t *merge_list; /* Skip list to hold sections for detecting merges */
|
||||
H5FS_bin_t *bins; /* Array of lists of lists of free sections */
|
||||
} H5FS_sinfo_t;
|
||||
|
||||
/* Main free space info */
|
||||
struct H5FS_t {
|
||||
/* Information for H5AC cache functions, _must_ be first field in structure */
|
||||
H5AC_info_t cache_info;
|
||||
|
||||
/* Stored information */
|
||||
/* Statistics about sections managed */
|
||||
hsize_t tot_space; /* Total amount of space tracked */
|
||||
hsize_t tot_sect_count; /* Total # of sections tracked */
|
||||
hsize_t serial_sect_count; /* # of serializable sections tracked */
|
||||
hsize_t ghost_sect_count; /* # of un-serializable sections tracked */
|
||||
|
||||
/* Creation parameters */
|
||||
H5FS_client_t client; /* Type of user of this free space manager */
|
||||
unsigned nclasses; /* Number of section classes handled */
|
||||
unsigned shrink_percent; /* Percent of "normal" serialized size to shrink serialized space at */
|
||||
unsigned expand_percent; /* Percent of "normal" serialized size to expand serialized space at */
|
||||
unsigned max_sect_addr; /* Size of address space free sections are within (log2 of actual value) */
|
||||
hsize_t max_sect_size; /* Maximum size of section to track */
|
||||
|
||||
/* Serialized section information */
|
||||
haddr_t sect_addr; /* Address of the section info in the file */
|
||||
hsize_t sect_size; /* Size of the section info in the file */
|
||||
hsize_t alloc_sect_size; /* Allocated size of the section info in the file */
|
||||
|
||||
/* Computed/cached values */
|
||||
haddr_t addr; /* Address of free space header on disk */
|
||||
H5FS_sinfo_t *sinfo; /* Section information */
|
||||
|
||||
/* Memory data structures (not stored directly) */
|
||||
H5FS_section_class_t *sect_cls; /* Array of section classes for this free list */
|
||||
};
|
||||
|
||||
|
||||
@ -143,22 +178,45 @@ struct H5FS_t {
|
||||
/* H5FS header inherits cache-like properties from H5AC */
|
||||
H5_DLLVAR const H5AC_class_t H5AC_FSPACE_HDR[1];
|
||||
|
||||
/* Declare a free list to manage the H5FS_hdr_t struct */
|
||||
H5FL_EXTERN(H5FS_hdr_t);
|
||||
/* H5FS section info inherits cache-like properties from H5AC */
|
||||
H5_DLLVAR const H5AC_class_t H5AC_FSPACE_SINFO[1];
|
||||
|
||||
/* Declare a free list to manage the H5FS_node_t struct */
|
||||
H5FL_EXTERN(H5FS_node_t);
|
||||
|
||||
/* Declare a free list to manage the H5FS_bin_t sequence information */
|
||||
H5FL_SEQ_EXTERN(H5FS_bin_t);
|
||||
|
||||
/* Declare a free list to manage the H5FS_sinfo_t struct */
|
||||
H5FL_EXTERN(H5FS_sinfo_t);
|
||||
|
||||
/* Declare a free list to manage the H5FS_t struct */
|
||||
H5FL_EXTERN(H5FS_t);
|
||||
|
||||
|
||||
/******************************/
|
||||
/* Package Private Prototypes */
|
||||
/******************************/
|
||||
|
||||
/* Free space manager header routines */
|
||||
H5_DLL H5FS_t *H5FS_new(size_t nclasses, const H5FS_section_class_t *classes[],
|
||||
void *cls_init_udata);
|
||||
|
||||
/* Free space section routines */
|
||||
H5_DLL H5FS_sinfo_t *H5FS_sinfo_new(H5F_t *f, H5FS_t *fspace);
|
||||
|
||||
/* Debugging routines for dumping file structures */
|
||||
H5_DLL herr_t H5FS_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
|
||||
H5_DLL herr_t H5FS_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
|
||||
FILE *stream, int indent, int fwidth);
|
||||
H5_DLL herr_t H5FS_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr,
|
||||
FILE *stream, int indent, int fwidth, haddr_t fs_addr, haddr_t client_addr);
|
||||
|
||||
/* Metadata cache callbacks */
|
||||
H5_DLL herr_t H5FS_cache_hdr_dest(H5F_t *f, H5FS_hdr_t *hdr);
|
||||
H5_DLL herr_t H5FS_cache_hdr_dest(H5F_t *f, H5FS_t *hdr);
|
||||
H5_DLL herr_t H5FS_cache_sinfo_dest(H5F_t *f, H5FS_sinfo_t *sinfo);
|
||||
|
||||
/* Sanity check routines */
|
||||
H5_DLL herr_t H5FS_sect_assert(const H5FS_t *fspace);
|
||||
|
||||
#endif /* _H5FSpkg_H */
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
/* Private headers needed by this file */
|
||||
#include "H5Fprivate.h" /* File access */
|
||||
#include "H5FLprivate.h" /* Free Lists */
|
||||
#include "H5SLprivate.h" /* Skip lists */
|
||||
|
||||
/**************************/
|
||||
/* Library Private Macros */
|
||||
@ -151,29 +150,31 @@ H5FL_SEQ_EXTERN(H5FS_section_class_t);
|
||||
/***************************************/
|
||||
/* Library-private Function Prototypes */
|
||||
/***************************************/
|
||||
|
||||
/* Free space manager routines */
|
||||
H5_DLL H5FS_t *H5FS_create(H5F_t *f, hid_t dxpl_id, haddr_t *fs_addr,
|
||||
const H5FS_create_t *fs_create, size_t nclasses,
|
||||
const H5FS_section_class_t *classes[], void *cls_init_udata);
|
||||
H5_DLL H5FS_t *H5FS_open(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr,
|
||||
size_t nclasses, const H5FS_section_class_t *classes[], void *cls_init_udata);
|
||||
H5_DLL herr_t H5FS_add(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
|
||||
H5FS_section_info_t *node, unsigned flags, void *op_data);
|
||||
H5_DLL herr_t H5FS_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
|
||||
H5FS_section_info_t *node);
|
||||
H5_DLL htri_t H5FS_find(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
|
||||
hsize_t request, H5FS_section_info_t **node);
|
||||
H5_DLL herr_t H5FS_iterate(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_operator_t op, void *op_data);
|
||||
H5_DLL herr_t H5FS_get_sect_count(const H5FS_t *fspace, hsize_t *nsects);
|
||||
H5_DLL herr_t H5FS_sect_change_class(H5FS_t *fspace, H5FS_section_info_t *sect,
|
||||
unsigned new_class);
|
||||
H5_DLL herr_t H5FS_flush(H5F_t *f, hid_t dxpl_id, unsigned flags);
|
||||
H5_DLL herr_t H5FS_delete(H5F_t *f, hid_t dxpl_id, haddr_t fs_addr);
|
||||
H5_DLL herr_t H5FS_close(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace);
|
||||
|
||||
/* Free space section routines */
|
||||
H5_DLL herr_t H5FS_sect_add(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
|
||||
H5FS_section_info_t *node, unsigned flags, void *op_data);
|
||||
H5_DLL herr_t H5FS_sect_remove(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
|
||||
H5FS_section_info_t *node);
|
||||
H5_DLL htri_t H5FS_sect_find(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
|
||||
hsize_t request, H5FS_section_info_t **node);
|
||||
H5_DLL herr_t H5FS_sect_iterate(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace, H5FS_operator_t op, void *op_data);
|
||||
H5_DLL herr_t H5FS_get_sect_count(const H5FS_t *fspace, hsize_t *nsects);
|
||||
H5_DLL herr_t H5FS_sect_change_class(H5F_t *f, hid_t dxpl_id, H5FS_t *fspace,
|
||||
H5FS_section_info_t *sect, unsigned new_class);
|
||||
|
||||
/* Debugging routines for dumping file structures */
|
||||
H5_DLL herr_t H5FS_sect_debug(const H5FS_t *fspace, const H5FS_section_info_t *sect,
|
||||
FILE *stream, int indent, int fwidth);
|
||||
|
||||
H5_DLL herr_t H5FS_debug_test(const H5FS_t *fspace);
|
||||
#endif /* _H5FSprivate_H */
|
||||
|
||||
|
1899
src/H5FSsection.c
Normal file
1899
src/H5FSsection.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -435,7 +435,7 @@ H5HF_dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
|
||||
HDfprintf(stream, "%*sFree Blocks (offset, size):\n", indent, "");
|
||||
|
||||
/* Iterate over the free space sections, to detect overlaps with this block */
|
||||
if(H5FS_iterate(f, dxpl_id, hdr->fspace, H5HF_dblock_debug_cb, &udata) < 0)
|
||||
if(H5FS_sect_iterate(f, dxpl_id, hdr->fspace, H5HF_dblock_debug_cb, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
|
||||
|
||||
/* Close the free space information */
|
||||
@ -697,7 +697,7 @@ H5HF_sects_debug(H5F_t *f, hid_t dxpl_id, haddr_t fh_addr,
|
||||
udata.fwidth = fwidth;
|
||||
|
||||
/* Iterate over all the free space sections */
|
||||
if(H5FS_iterate(f, dxpl_id, hdr->fspace, H5HF_sects_debug_cb, &udata) < 0)
|
||||
if(H5FS_sect_iterate(f, dxpl_id, hdr->fspace, H5HF_sects_debug_cb, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_BADITER, FAIL, "can't iterate over heap's free space")
|
||||
|
||||
/* Close the free space information */
|
||||
|
@ -364,9 +364,6 @@ H5HF_hdr_incr(H5HF_hdr_t *hdr)
|
||||
/* Sanity check */
|
||||
HDassert(hdr);
|
||||
|
||||
/* XXX: When "un-evictable" feature is finished, mark the header as
|
||||
* unevictable on the first block to share it. - QAK
|
||||
*/
|
||||
/* Mark header as un-evictable when a block is depending on it */
|
||||
if(hdr->rc == 0)
|
||||
if(H5AC_pin_protected_entry(hdr->f, hdr) < 0)
|
||||
|
@ -509,7 +509,7 @@ HDfprintf(stderr, "%s: new_addr = %a\n", FUNC, new_addr);
|
||||
/* Move object in cache, if it actually was relocated */
|
||||
if(H5F_addr_ne(iblock->addr, new_addr)) {
|
||||
if(H5AC_rename(hdr->f, H5AC_FHEAP_IBLOCK, iblock->addr, new_addr) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTSPLIT, FAIL, "unable to move fractal heap root indirect block")
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTRENAME, FAIL, "unable to move fractal heap root indirect block")
|
||||
iblock->addr = new_addr;
|
||||
} /* end if */
|
||||
|
||||
|
@ -530,8 +530,8 @@ H5_DLL herr_t H5HF_space_remove(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *node);
|
||||
H5_DLL herr_t H5HF_space_close(H5HF_hdr_t *hdr, hid_t dxpl_id);
|
||||
H5_DLL herr_t H5HF_space_delete(H5HF_hdr_t *hdr, hid_t dxpl_id);
|
||||
H5_DLL herr_t H5HF_space_sect_change_class(H5HF_hdr_t *hdr, H5HF_free_section_t *sect,
|
||||
unsigned new_class);
|
||||
H5_DLL herr_t H5HF_space_sect_change_class(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *sect, unsigned new_class);
|
||||
|
||||
/* Free space section routines */
|
||||
H5_DLL H5HF_free_section_t *H5HF_sect_single_new(hsize_t sect_off,
|
||||
@ -559,7 +559,6 @@ H5_DLL unsigned H5HF_get_iblock_max_drows_test(const H5HF_t *fh, unsigned pos);
|
||||
H5_DLL hsize_t H5HF_get_dblock_size_test(const H5HF_t *fh, unsigned row);
|
||||
H5_DLL hsize_t H5HF_get_dblock_free_test(const H5HF_t *fh, unsigned row);
|
||||
H5_DLL herr_t H5HF_get_id_off_test(const H5HF_t *fh, const void *id, hsize_t *obj_off);
|
||||
H5_DLL herr_t H5HF_debug_test(const H5HF_t *fh);
|
||||
#endif /* H5HF_TESTING */
|
||||
|
||||
#endif /* _H5HFpkg_H */
|
||||
|
@ -102,7 +102,8 @@ static herr_t H5HF_sect_single_valid(const H5FS_section_class_t *cls,
|
||||
static H5HF_free_section_t *H5HF_sect_row_create(haddr_t sect_off,
|
||||
hsize_t sect_size, hbool_t is_first, unsigned row, unsigned col,
|
||||
unsigned nentries, H5HF_free_section_t *under_sect);
|
||||
static herr_t H5HF_sect_row_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect);
|
||||
static herr_t H5HF_sect_row_first(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *sect);
|
||||
static herr_t H5HF_sect_row_from_single(H5HF_hdr_t *hdr,
|
||||
H5HF_free_section_t *sect, H5HF_direct_t *dblock);
|
||||
static herr_t H5HF_sect_row_free_real(H5HF_free_section_t *sect);
|
||||
@ -145,11 +146,12 @@ static herr_t H5HF_sect_indirect_revive_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *sect);
|
||||
static herr_t H5HF_sect_indirect_revive(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *sect, H5HF_indirect_t *sect_iblock);
|
||||
static herr_t H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr,
|
||||
static herr_t H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *row_sect, hbool_t *alloc_from_start);
|
||||
static herr_t H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr,
|
||||
static herr_t H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *sect, unsigned child_entry);
|
||||
static herr_t H5HF_sect_indirect_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect);
|
||||
static herr_t H5HF_sect_indirect_first(H5HF_hdr_t *hdr, hid_t dxpl_id,
|
||||
H5HF_free_section_t *sect);
|
||||
static hbool_t H5HF_sect_indirect_is_first(H5HF_free_section_t *sect);
|
||||
static H5HF_indirect_t * H5HF_sect_indirect_get_iblock(H5HF_free_section_t *sect);
|
||||
static hsize_t H5HF_sect_indirect_iblock_off(const H5HF_free_section_t *sect);
|
||||
@ -333,6 +335,10 @@ H5HF_sect_init_cls(H5FS_section_class_t *cls, H5HF_hdr_t *hdr)
|
||||
cls_prvt->hdr = hdr;
|
||||
cls->cls_private = cls_prvt;
|
||||
|
||||
/* Increment reference count on heap header */
|
||||
if(H5HF_hdr_incr(hdr) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, FAIL, "can't increment reference count on shared heap header")
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5HF_sect_init_cls() */
|
||||
@ -354,15 +360,26 @@ done:
|
||||
static herr_t
|
||||
H5HF_sect_term_cls(H5FS_section_class_t *cls)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HF_sect_term_cls)
|
||||
H5HF_sect_private_t *cls_prvt; /* Pointer to class private info */
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5HF_sect_term_cls)
|
||||
|
||||
/* Check arguments. */
|
||||
HDassert(cls);
|
||||
|
||||
/* Free the class private information */
|
||||
cls->cls_private = H5MM_xfree(cls->cls_private);
|
||||
/* Get pointer to class private info */
|
||||
cls_prvt = cls->cls_private;
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
/* Decrement reference count on heap header */
|
||||
if(H5HF_hdr_decr(cls_prvt->hdr) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTDEC, FAIL, "can't decrement reference count on shared heap header")
|
||||
|
||||
/* Free the class private information */
|
||||
cls->cls_private = H5MM_xfree(cls_prvt);
|
||||
|
||||
done:
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* H5HF_sect_term_cls() */
|
||||
|
||||
|
||||
@ -1372,7 +1389,7 @@ HDfprintf(stderr, "%s: sect->u.row = {%p, %u, %u, %u, %t}\n", FUNC, sect->u.row.
|
||||
|
||||
/* Forward row section to indirect routines, to handle reducing underlying indirect section */
|
||||
alloc_from_start = FALSE;
|
||||
if(H5HF_sect_indirect_reduce_row(hdr, sect, &alloc_from_start) < 0)
|
||||
if(H5HF_sect_indirect_reduce_row(hdr, dxpl_id, sect, &alloc_from_start) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't reduce underlying section")
|
||||
|
||||
/* Determine entry allocated */
|
||||
@ -1427,7 +1444,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5HF_sect_row_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
|
||||
H5HF_sect_row_first(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@ -1446,7 +1463,7 @@ H5HF_sect_row_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
|
||||
sect->sect_info.type = H5HF_FSPACE_SECT_FIRST_ROW;
|
||||
else {
|
||||
/* Change row section to be the "first row" */
|
||||
if(H5HF_space_sect_change_class(hdr, sect, H5HF_FSPACE_SECT_FIRST_ROW) < 0)
|
||||
if(H5HF_space_sect_change_class(hdr, dxpl_id, sect, H5HF_FSPACE_SECT_FIRST_ROW) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, FAIL, "can't set row section to be first row")
|
||||
} /* end else */
|
||||
|
||||
@ -2602,6 +2619,7 @@ HDfprintf(stderr, "%s: child_iblock_addr = %a\n", FUNC, child_iblock_addr);
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize indirect section")
|
||||
|
||||
/* If we have a valid child indirect block, release it now */
|
||||
/* (will be pinned, if rows reference it) */
|
||||
if(child_iblock)
|
||||
if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FHEAP_IBLOCK, child_iblock->addr, child_iblock, H5AC__NO_FLAGS_SET) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTUNPROTECT, FAIL, "unable to release fractal heap indirect block")
|
||||
@ -2934,7 +2952,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, H5HF_free_section_t *row_sect,
|
||||
H5HF_sect_indirect_reduce_row(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *row_sect,
|
||||
hbool_t *alloc_from_start)
|
||||
{
|
||||
H5HF_free_section_t *sect; /* Indirect section underlying row section */
|
||||
@ -3015,14 +3033,14 @@ HDfprintf(stderr, "%s: row_entry = %u\n", FUNC, row_entry);
|
||||
is_first = H5HF_sect_indirect_is_first(sect);
|
||||
|
||||
/* Remove this indirect section from parent indirect section */
|
||||
if(H5HF_sect_indirect_reduce(hdr, sect->u.indirect.parent, sect->u.indirect.par_entry) < 0)
|
||||
if(H5HF_sect_indirect_reduce(hdr, dxpl_id, sect->u.indirect.parent, sect->u.indirect.par_entry) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't reduce parent indirect section")
|
||||
sect->u.indirect.parent = NULL;
|
||||
sect->u.indirect.par_entry = 0;
|
||||
|
||||
/* If we weren't the first section, set "first row" for this indirect section */
|
||||
if(!is_first)
|
||||
if(H5HF_sect_indirect_first(hdr, sect) < 0)
|
||||
if(H5HF_sect_indirect_first(hdr, dxpl_id, sect) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for indirect section")
|
||||
} /* end if */
|
||||
|
||||
@ -3063,7 +3081,7 @@ HDfprintf(stderr, "%s: sect->u.indirect.dir_nrows = %u\n", FUNC, sect->u.indirec
|
||||
|
||||
/* Make new "first row" in indirect section */
|
||||
if(row_sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW)
|
||||
if(H5HF_sect_row_first(hdr, sect->u.indirect.dir_rows[0]) < 0)
|
||||
if(H5HF_sect_row_first(hdr, dxpl_id, sect->u.indirect.dir_rows[0]) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for indirect section")
|
||||
} /* end if */
|
||||
else {
|
||||
@ -3076,7 +3094,7 @@ HDfprintf(stderr, "%s: sect->u.indirect.dir_nrows = %u\n", FUNC, sect->u.indirec
|
||||
|
||||
/* Make new "first row" in indirect section */
|
||||
if(row_sect->sect_info.type == H5HF_FSPACE_SECT_FIRST_ROW)
|
||||
if(H5HF_sect_indirect_first(hdr, sect->u.indirect.indir_ents[0]) < 0)
|
||||
if(H5HF_sect_indirect_first(hdr, dxpl_id, sect->u.indirect.indir_ents[0]) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for child indirect section")
|
||||
} /* end else */
|
||||
} /* end if */
|
||||
@ -3233,7 +3251,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, H5HF_free_section_t *sect,
|
||||
H5HF_sect_indirect_reduce(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect,
|
||||
unsigned child_entry)
|
||||
{
|
||||
unsigned start_entry; /* Entry for first block covered */
|
||||
@ -3281,14 +3299,14 @@ HDfprintf(stderr, "%s: end_entry = %u, end_row = %u, end_col = %u\n", FUNC, end_
|
||||
is_first = H5HF_sect_indirect_is_first(sect);
|
||||
|
||||
/* Reduce parent indirect section */
|
||||
if(H5HF_sect_indirect_reduce(hdr, sect->u.indirect.parent, sect->u.indirect.par_entry) < 0)
|
||||
if(H5HF_sect_indirect_reduce(hdr, dxpl_id, sect->u.indirect.parent, sect->u.indirect.par_entry) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTSHRINK, FAIL, "can't reduce parent indirect section")
|
||||
sect->u.indirect.parent = NULL;
|
||||
sect->u.indirect.par_entry = 0;
|
||||
|
||||
/* If we weren't the first section, set "first row" for this indirect section */
|
||||
if(!is_first)
|
||||
if(H5HF_sect_indirect_first(hdr, sect) < 0)
|
||||
if(H5HF_sect_indirect_first(hdr, dxpl_id, sect) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for indirect section")
|
||||
} /* end if */
|
||||
|
||||
@ -3323,7 +3341,7 @@ HDfprintf(stderr, "%s: Child is at start of indirect section\n", FUNC);
|
||||
HDassert(sect->u.indirect.indir_ents[0]);
|
||||
|
||||
/* Make new "first row" in new first indirect child section */
|
||||
if(H5HF_sect_indirect_first(hdr, sect->u.indirect.indir_ents[0]) < 0)
|
||||
if(H5HF_sect_indirect_first(hdr, dxpl_id, sect->u.indirect.indir_ents[0]) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for child indirect section")
|
||||
} /* end if */
|
||||
else if(child_entry == end_entry) {
|
||||
@ -3436,7 +3454,7 @@ HDfprintf(stderr, "%s: sect->u.indirect.indir_nents = %u\n", FUNC, sect->u.indir
|
||||
peer_sect->u.indirect.indir_ents[u]->u.indirect.parent = peer_sect;
|
||||
|
||||
/* Make new "first row" in peer section */
|
||||
if(H5HF_sect_indirect_first(hdr, peer_sect->u.indirect.indir_ents[0]) < 0)
|
||||
if(H5HF_sect_indirect_first(hdr, dxpl_id, peer_sect->u.indirect.indir_ents[0]) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't make new 'first row' for peer indirect section")
|
||||
|
||||
/* Adjust reference counts for current & peer sections */
|
||||
@ -3512,7 +3530,7 @@ H5HF_sect_indirect_is_first(H5HF_free_section_t *sect)
|
||||
ret_value = TRUE;
|
||||
|
||||
FUNC_LEAVE_NOAPI(ret_value)
|
||||
} /* end H5HF_sect_indirect_first() */
|
||||
} /* end H5HF_sect_indirect_is_first() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -3529,7 +3547,7 @@ H5HF_sect_indirect_is_first(H5HF_free_section_t *sect)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5HF_sect_indirect_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
|
||||
H5HF_sect_indirect_first(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@ -3548,7 +3566,7 @@ H5HF_sect_indirect_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
|
||||
HDassert(sect->u.indirect.dir_rows[0]);
|
||||
|
||||
/* Change first row section in indirect section to be the "first row" */
|
||||
if(H5HF_sect_row_first(hdr, sect->u.indirect.dir_rows[0]) < 0)
|
||||
if(H5HF_sect_row_first(hdr, dxpl_id, sect->u.indirect.dir_rows[0]) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, FAIL, "can't set row section to be first row")
|
||||
} /* end if */
|
||||
else {
|
||||
@ -3558,7 +3576,7 @@ H5HF_sect_indirect_first(H5HF_hdr_t *hdr, H5HF_free_section_t *sect)
|
||||
HDassert(sect->u.indirect.indir_ents[0]);
|
||||
|
||||
/* Forward to first child indirect section */
|
||||
if(H5HF_sect_indirect_first(hdr, sect->u.indirect.indir_ents[0]) < 0)
|
||||
if(H5HF_sect_indirect_first(hdr, dxpl_id, sect->u.indirect.indir_ents[0]) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTSET, FAIL, "can't set child indirect section to be first row")
|
||||
} /* end else */
|
||||
|
||||
|
@ -177,7 +177,7 @@ H5HF_space_add(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node,
|
||||
udata.dxpl_id = dxpl_id;
|
||||
|
||||
/* Add to the free space for the heap */
|
||||
if(H5FS_add(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata) < 0)
|
||||
if(H5FS_sect_add(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node, flags, &udata) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINSERT, FAIL, "can't add section to heap free space")
|
||||
|
||||
done:
|
||||
@ -221,7 +221,7 @@ H5HF_space_find(H5HF_hdr_t *hdr, hid_t dxpl_id, hsize_t request, H5HF_free_secti
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "can't initialize heap free space")
|
||||
|
||||
/* Search for free space in the heap */
|
||||
if((node_found = H5FS_find(hdr->f, dxpl_id, hdr->fspace, request, (H5FS_section_info_t **)node)) < 0)
|
||||
if((node_found = H5FS_sect_find(hdr->f, dxpl_id, hdr->fspace, request, (H5FS_section_info_t **)node)) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, FAIL, "can't locate free space in fractal heap")
|
||||
|
||||
/* Set return value */
|
||||
@ -261,7 +261,7 @@ H5HF_space_remove(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *node)
|
||||
HDassert(node);
|
||||
|
||||
/* Remove from the free space for the heap */
|
||||
if(H5FS_remove(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node) < 0)
|
||||
if(H5FS_sect_remove(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)node) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTREMOVE, FAIL, "can't remove section from heap free space")
|
||||
|
||||
done:
|
||||
@ -341,7 +341,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5HF_space_sect_change_class(H5HF_hdr_t *hdr, H5HF_free_section_t *sect, unsigned new_class)
|
||||
H5HF_space_sect_change_class(H5HF_hdr_t *hdr, hid_t dxpl_id, H5HF_free_section_t *sect, unsigned new_class)
|
||||
{
|
||||
herr_t ret_value = SUCCEED; /* Return value */
|
||||
|
||||
@ -358,7 +358,7 @@ HDfprintf(stderr, "%s: Called\n", FUNC);
|
||||
HDassert(sect);
|
||||
|
||||
/* Notify the free space manager that a section has changed class */
|
||||
if(H5FS_sect_change_class(hdr->fspace, (H5FS_section_info_t *)sect, new_class) < 0)
|
||||
if(H5FS_sect_change_class(hdr->f, dxpl_id, hdr->fspace, (H5FS_section_info_t *)sect, new_class) < 0)
|
||||
HGOTO_ERROR(H5E_HEAP, H5E_CANTMODIFY, FAIL, "can't modify class of free space section")
|
||||
|
||||
done:
|
||||
|
@ -327,35 +327,3 @@ H5HF_get_id_off_test(const H5HF_t *fh, const void *_id, hsize_t *obj_off)
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* H5HF_get_id_off_test() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5HF_debug_test
|
||||
*
|
||||
* Purpose: Debugging routine for testing
|
||||
*
|
||||
* Return: Success: non-negative
|
||||
*
|
||||
* Failure: negative
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
* Tuesday, June 20, 2006
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5HF_debug_test(const H5HF_t *fh)
|
||||
{
|
||||
FUNC_ENTER_NOAPI_NOINIT(H5HF_debug_test)
|
||||
|
||||
/* Check arguments. */
|
||||
HDassert(fh);
|
||||
HDassert(fh->hdr);
|
||||
|
||||
HDfprintf(stderr, "%s: fh->hdr->man_iter_off = %Hu\n", FUNC, fh->hdr->man_iter_off);
|
||||
HDfprintf(stderr, "%s: fh->hdr->fspace = %p\n", FUNC, fh->hdr->fspace);
|
||||
if(fh->hdr->fspace)
|
||||
H5FS_debug_test(fh->hdr->fspace);
|
||||
|
||||
FUNC_LEAVE_NOAPI(SUCCEED)
|
||||
} /* H5HF_debug_test() */
|
||||
|
||||
|
@ -48,7 +48,7 @@ libhdf5_la_SOURCES= H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \
|
||||
H5Fdbg.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \
|
||||
H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
|
||||
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \
|
||||
H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c \
|
||||
H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \
|
||||
H5G.c H5Gdeprec.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c \
|
||||
H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c H5Gtraverse.c \
|
||||
H5HF.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \
|
||||
|
@ -90,7 +90,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5dbg.lo H5A.lo H5AC.lo H5B.lo \
|
||||
H5Fmount.lo H5Fsfile.lo H5Fsuper.lo H5FD.lo H5FDcore.lo \
|
||||
H5FDfamily.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \
|
||||
H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDstdio.lo \
|
||||
H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \
|
||||
H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo H5FSsection.lo \
|
||||
H5G.lo H5Gdeprec.lo H5Gent.lo H5Glink.lo H5Gloc.lo H5Gname.lo \
|
||||
H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \
|
||||
H5Gtraverse.lo H5HF.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \
|
||||
@ -395,7 +395,7 @@ libhdf5_la_SOURCES = H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \
|
||||
H5Fdbg.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \
|
||||
H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
|
||||
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \
|
||||
H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c \
|
||||
H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c H5FSsection.c \
|
||||
H5G.c H5Gdeprec.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c \
|
||||
H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c H5Gtraverse.c \
|
||||
H5HF.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \
|
||||
@ -591,6 +591,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FScache.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSdbg.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FSsection.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsfile.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsuper.Plo@am__quote@
|
||||
|
@ -312,9 +312,9 @@ main(int argc, char *argv[])
|
||||
* Debug a free space header.
|
||||
*/
|
||||
|
||||
status = H5FS_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL);
|
||||
status = H5FS_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL);
|
||||
|
||||
} else if(!HDmemcmp(sig, H5FS_SECTS_MAGIC, H5FS_SIZEOF_MAGIC)) {
|
||||
} else if(!HDmemcmp(sig, H5FS_SINFO_MAGIC, H5FS_SIZEOF_MAGIC)) {
|
||||
/*
|
||||
* Debug free space serialized sections.
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user