From 41220f091117888c29a80949cd32fb99e7d877ea Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Thu, 2 Jul 2009 22:36:44 -0500 Subject: [svn-r17154] Description: Add fixed array data structure. (For initial use as a chunk index) Tested on: Mac OS X/32 10.5.7 (amazon) (h5committest not required on this branch) --- MANIFEST | 10 + src/H5AC.c | 3 + src/H5ACprivate.h | 3 + src/H5Cpkg.h | 2 +- src/H5Edefin.h | 23 +- src/H5Einit.h | 107 ++--- src/H5Epubgen.h | 46 ++- src/H5Eterm.h | 23 +- src/H5FA.c | 704 ++++++++++++++++++++++++++++++++ src/H5FAcache.c | 1107 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/H5FAdbg.c | 321 +++++++++++++++ src/H5FAdblkpage.c | 312 ++++++++++++++ src/H5FAdblock.c | 442 ++++++++++++++++++++ src/H5FAhdr.c | 454 +++++++++++++++++++++ src/H5FApkg.h | 286 +++++++++++++ src/H5FAprivate.h | 132 ++++++ src/H5FAstat.c | 113 ++++++ src/H5FAtest.c | 391 ++++++++++++++++++ src/H5FDpublic.h | 12 + src/H5Fprivate.h | 4 + src/H5err.txt | 1 + src/Makefile.am | 2 + src/Makefile.in | 24 +- tools/misc/h5debug.c | 72 ++++ 24 files changed, 4492 insertions(+), 102 deletions(-) create mode 100644 src/H5FA.c create mode 100644 src/H5FAcache.c create mode 100644 src/H5FAdbg.c create mode 100644 src/H5FAdblkpage.c create mode 100644 src/H5FAdblock.c create mode 100644 src/H5FAhdr.c create mode 100644 src/H5FApkg.h create mode 100644 src/H5FAprivate.h create mode 100644 src/H5FAstat.c create mode 100644 src/H5FAtest.c diff --git a/MANIFEST b/MANIFEST index 5b2437b..188766f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -529,6 +529,16 @@ ./src/H5Fprivate.h ./src/H5Fpublic.h ./src/H5Ftest.c +./src/H5FA.c +./src/H5FAcache.c +./src/H5FAdbg.c +./src/H5FAdblkpage.c +./src/H5FAdblock.c +./src/H5FAhdr.c +./src/H5FApkg.h +./src/H5FAprivate.h +./src/H5FAstat.c +./src/H5FAtest.c ./src/H5FD.c ./src/H5FDcore.c ./src/H5FDcore.h diff --git a/src/H5AC.c b/src/H5AC.c index a8c0f07..4e505ae 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -497,6 +497,9 @@ static const char * H5AC_entry_type_names[H5AC_NTYPES] = "extensible array data blocks", "extensible array data block pages", "chunk proxy", + "fixed array headers", + "fixed array data block", + "fixed array data block pages", "test entry" /* for testing only -- not used for actual files */ }; diff --git a/src/H5ACprivate.h b/src/H5ACprivate.h index 8122567..b58d24f 100644 --- a/src/H5ACprivate.h +++ b/src/H5ACprivate.h @@ -68,6 +68,9 @@ typedef enum { H5AC_EARRAY_DBLOCK_ID, /*extensible array data block */ H5AC_EARRAY_DBLK_PAGE_ID, /*extensible array data block page */ H5AC_CHUNK_PROXY_ID, /*chunk proxy */ + H5AC_FARRAY_HDR_ID, /*fixed array header */ + H5AC_FARRAY_DBLOCK_ID, /*fixed array data block */ + H5AC_FARRAY_DBLK_PAGE_ID, /*fixed array data block page */ H5AC_TEST_ID, /*test entry -- not used for actual files */ H5AC_NTYPES /* Number of types, must be last */ } H5AC_type_t; diff --git a/src/H5Cpkg.h b/src/H5Cpkg.h index de1e87a..4bc105d 100644 --- a/src/H5Cpkg.h +++ b/src/H5Cpkg.h @@ -857,7 +857,7 @@ ****************************************************************************/ #define H5C__H5C_T_MAGIC 0x005CAC0E -#define H5C__MAX_NUM_TYPE_IDS 22 +#define H5C__MAX_NUM_TYPE_IDS 25 #define H5C__PREFIX_LEN 32 struct H5C_t diff --git a/src/H5Edefin.h b/src/H5Edefin.h index adaaa3a..16e922a 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -21,9 +21,7 @@ #define _H5Edefin_H /* Major error IDs */ -hid_t H5E_DATASET_g = FAIL; /* Dataset */ hid_t H5E_FUNC_g = FAIL; /* Function entry/exit */ -hid_t H5E_STORAGE_g = FAIL; /* Data storage */ hid_t H5E_FILE_g = FAIL; /* File accessability */ hid_t H5E_SOHM_g = FAIL; /* Shared Object Header Messages */ hid_t H5E_SYM_g = FAIL; /* Symbol table */ @@ -33,24 +31,27 @@ hid_t H5E_BTREE_g = FAIL; /* B-Tree node */ hid_t H5E_REFERENCE_g = FAIL; /* References */ hid_t H5E_DATASPACE_g = FAIL; /* Dataspace */ hid_t H5E_RESOURCE_g = FAIL; /* Resource unavailable */ -hid_t H5E_PLIST_g = FAIL; /* Property lists */ -hid_t H5E_LINK_g = FAIL; /* Links */ -hid_t H5E_DATATYPE_g = FAIL; /* Datatype */ hid_t H5E_RS_g = FAIL; /* Reference Counted Strings */ +hid_t H5E_FARRAY_g = FAIL; /* Fixed Array */ hid_t H5E_HEAP_g = FAIL; /* Heap */ -hid_t H5E_OHDR_g = FAIL; /* Object header */ -hid_t H5E_ATOM_g = FAIL; /* Object atom */ hid_t H5E_ATTR_g = FAIL; /* Attribute */ -hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */ hid_t H5E_IO_g = FAIL; /* Low-level I/O */ -hid_t H5E_SLIST_g = FAIL; /* Skip Lists */ hid_t H5E_EFL_g = FAIL; /* External file list */ hid_t H5E_TST_g = FAIL; /* Ternary Search Trees */ +hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */ +hid_t H5E_DATASET_g = FAIL; /* Dataset */ +hid_t H5E_STORAGE_g = FAIL; /* Data storage */ +hid_t H5E_LINK_g = FAIL; /* Links */ +hid_t H5E_PLIST_g = FAIL; /* Property lists */ +hid_t H5E_DATATYPE_g = FAIL; /* Datatype */ +hid_t H5E_OHDR_g = FAIL; /* Object header */ +hid_t H5E_ATOM_g = FAIL; /* Object atom */ +hid_t H5E_NONE_MAJOR_g = FAIL; /* No error */ +hid_t H5E_SLIST_g = FAIL; /* Skip Lists */ hid_t H5E_ARGS_g = FAIL; /* Invalid arguments to routine */ hid_t H5E_EARRAY_g = FAIL; /* Extensible Array */ -hid_t H5E_ERROR_g = FAIL; /* Error API */ hid_t H5E_PLINE_g = FAIL; /* Data filters */ -hid_t H5E_FSPACE_g = FAIL; /* Free Space Manager */ +hid_t H5E_ERROR_g = FAIL; /* Error API */ hid_t H5E_CACHE_g = FAIL; /* Object cache */ /* Minor error IDs */ diff --git a/src/H5Einit.h b/src/H5Einit.h index a9f95b7..cea2888 100644 --- a/src/H5Einit.h +++ b/src/H5Einit.h @@ -24,21 +24,11 @@ /* Major error codes */ /*********************/ -assert(H5E_DATASET_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_FUNC_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Function entry/exit"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_FUNC_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_STORAGE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data storage"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_STORAGE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_FILE_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "File accessability"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") @@ -84,31 +74,71 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Resource unavailable"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_RESOURCE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_PLIST_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Property lists"))==NULL) +assert(H5E_RS_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_PLIST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) +if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_FARRAY_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Fixed Array"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_FARRAY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_HEAP_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Heap"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_HEAP_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_ATTR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_IO_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Low-level I/O"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_IO_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_EFL_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "External file list"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_EFL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_TST_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_FSPACE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_DATASET_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Dataset"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_DATASET_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_STORAGE_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data storage"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_STORAGE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_LINK_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Links"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") +assert(H5E_PLIST_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Property lists"))==NULL) + HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") +if((H5E_PLIST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) + HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_DATATYPE_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Datatype"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_DATATYPE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_RS_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Reference Counted Strings"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_RS_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_HEAP_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Heap"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_HEAP_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_OHDR_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object header"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") @@ -119,36 +149,16 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object atom"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_ATOM_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ATTR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Attribute"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ATTR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_NONE_MAJOR_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "No error"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_NONE_MAJOR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_IO_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Low-level I/O"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_IO_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_SLIST_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Skip Lists"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_SLIST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_EFL_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "External file list"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_EFL_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_TST_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Ternary Search Trees"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_TST_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_ARGS_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Invalid arguments to routine"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") @@ -159,20 +169,15 @@ if((msg = H5E_create_msg(cls, H5E_MAJOR, "Extensible Array"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_EARRAY_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_ERROR_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL) - HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) - HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_PLINE_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Data filters"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_PLINE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") -assert(H5E_FSPACE_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MAJOR, "Free Space Manager"))==NULL) +assert(H5E_ERROR_g==(-1)); +if((msg = H5E_create_msg(cls, H5E_MAJOR, "Error API"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") -if((H5E_FSPACE_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) +if((H5E_ERROR_g = H5I_register(H5I_ERROR_MSG, msg, FALSE))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_CACHE_g==(-1)); if((msg = H5E_create_msg(cls, H5E_MAJOR, "Object cache"))==NULL) diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h index 3debf20..999ea61 100644 --- a/src/H5Epubgen.h +++ b/src/H5Epubgen.h @@ -24,9 +24,7 @@ /* Major error codes */ /*********************/ -#define H5E_DATASET (H5OPEN H5E_DATASET_g) #define H5E_FUNC (H5OPEN H5E_FUNC_g) -#define H5E_STORAGE (H5OPEN H5E_STORAGE_g) #define H5E_FILE (H5OPEN H5E_FILE_g) #define H5E_SOHM (H5OPEN H5E_SOHM_g) #define H5E_SYM (H5OPEN H5E_SYM_g) @@ -36,28 +34,29 @@ #define H5E_REFERENCE (H5OPEN H5E_REFERENCE_g) #define H5E_DATASPACE (H5OPEN H5E_DATASPACE_g) #define H5E_RESOURCE (H5OPEN H5E_RESOURCE_g) -#define H5E_PLIST (H5OPEN H5E_PLIST_g) -#define H5E_LINK (H5OPEN H5E_LINK_g) -#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g) #define H5E_RS (H5OPEN H5E_RS_g) +#define H5E_FARRAY (H5OPEN H5E_FARRAY_g) #define H5E_HEAP (H5OPEN H5E_HEAP_g) -#define H5E_OHDR (H5OPEN H5E_OHDR_g) -#define H5E_ATOM (H5OPEN H5E_ATOM_g) #define H5E_ATTR (H5OPEN H5E_ATTR_g) -#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g) #define H5E_IO (H5OPEN H5E_IO_g) -#define H5E_SLIST (H5OPEN H5E_SLIST_g) #define H5E_EFL (H5OPEN H5E_EFL_g) #define H5E_TST (H5OPEN H5E_TST_g) +#define H5E_FSPACE (H5OPEN H5E_FSPACE_g) +#define H5E_DATASET (H5OPEN H5E_DATASET_g) +#define H5E_STORAGE (H5OPEN H5E_STORAGE_g) +#define H5E_LINK (H5OPEN H5E_LINK_g) +#define H5E_PLIST (H5OPEN H5E_PLIST_g) +#define H5E_DATATYPE (H5OPEN H5E_DATATYPE_g) +#define H5E_OHDR (H5OPEN H5E_OHDR_g) +#define H5E_ATOM (H5OPEN H5E_ATOM_g) +#define H5E_NONE_MAJOR (H5OPEN H5E_NONE_MAJOR_g) +#define H5E_SLIST (H5OPEN H5E_SLIST_g) #define H5E_ARGS (H5OPEN H5E_ARGS_g) #define H5E_EARRAY (H5OPEN H5E_EARRAY_g) -#define H5E_ERROR (H5OPEN H5E_ERROR_g) #define H5E_PLINE (H5OPEN H5E_PLINE_g) -#define H5E_FSPACE (H5OPEN H5E_FSPACE_g) +#define H5E_ERROR (H5OPEN H5E_ERROR_g) #define H5E_CACHE (H5OPEN H5E_CACHE_g) -H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */ H5_DLLVAR hid_t H5E_FUNC_g; /* Function entry/exit */ -H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */ H5_DLLVAR hid_t H5E_FILE_g; /* File accessability */ H5_DLLVAR hid_t H5E_SOHM_g; /* Shared Object Header Messages */ H5_DLLVAR hid_t H5E_SYM_g; /* Symbol table */ @@ -67,24 +66,27 @@ H5_DLLVAR hid_t H5E_BTREE_g; /* B-Tree node */ H5_DLLVAR hid_t H5E_REFERENCE_g; /* References */ H5_DLLVAR hid_t H5E_DATASPACE_g; /* Dataspace */ H5_DLLVAR hid_t H5E_RESOURCE_g; /* Resource unavailable */ -H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */ -H5_DLLVAR hid_t H5E_LINK_g; /* Links */ -H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */ H5_DLLVAR hid_t H5E_RS_g; /* Reference Counted Strings */ +H5_DLLVAR hid_t H5E_FARRAY_g; /* Fixed Array */ H5_DLLVAR hid_t H5E_HEAP_g; /* Heap */ -H5_DLLVAR hid_t H5E_OHDR_g; /* Object header */ -H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */ H5_DLLVAR hid_t H5E_ATTR_g; /* Attribute */ -H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */ H5_DLLVAR hid_t H5E_IO_g; /* Low-level I/O */ -H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */ H5_DLLVAR hid_t H5E_EFL_g; /* External file list */ H5_DLLVAR hid_t H5E_TST_g; /* Ternary Search Trees */ +H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */ +H5_DLLVAR hid_t H5E_DATASET_g; /* Dataset */ +H5_DLLVAR hid_t H5E_STORAGE_g; /* Data storage */ +H5_DLLVAR hid_t H5E_LINK_g; /* Links */ +H5_DLLVAR hid_t H5E_PLIST_g; /* Property lists */ +H5_DLLVAR hid_t H5E_DATATYPE_g; /* Datatype */ +H5_DLLVAR hid_t H5E_OHDR_g; /* Object header */ +H5_DLLVAR hid_t H5E_ATOM_g; /* Object atom */ +H5_DLLVAR hid_t H5E_NONE_MAJOR_g; /* No error */ +H5_DLLVAR hid_t H5E_SLIST_g; /* Skip Lists */ H5_DLLVAR hid_t H5E_ARGS_g; /* Invalid arguments to routine */ H5_DLLVAR hid_t H5E_EARRAY_g; /* Extensible Array */ -H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */ H5_DLLVAR hid_t H5E_PLINE_g; /* Data filters */ -H5_DLLVAR hid_t H5E_FSPACE_g; /* Free Space Manager */ +H5_DLLVAR hid_t H5E_ERROR_g; /* Error API */ H5_DLLVAR hid_t H5E_CACHE_g; /* Object cache */ /*********************/ diff --git a/src/H5Eterm.h b/src/H5Eterm.h index ecad437..0997990 100644 --- a/src/H5Eterm.h +++ b/src/H5Eterm.h @@ -22,9 +22,7 @@ /* Reset major error IDs */ -H5E_DATASET_g= H5E_FUNC_g= -H5E_STORAGE_g= H5E_FILE_g= H5E_SOHM_g= H5E_SYM_g= @@ -34,24 +32,27 @@ H5E_BTREE_g= H5E_REFERENCE_g= H5E_DATASPACE_g= H5E_RESOURCE_g= -H5E_PLIST_g= -H5E_LINK_g= -H5E_DATATYPE_g= H5E_RS_g= +H5E_FARRAY_g= H5E_HEAP_g= -H5E_OHDR_g= -H5E_ATOM_g= H5E_ATTR_g= -H5E_NONE_MAJOR_g= H5E_IO_g= -H5E_SLIST_g= H5E_EFL_g= H5E_TST_g= +H5E_FSPACE_g= +H5E_DATASET_g= +H5E_STORAGE_g= +H5E_LINK_g= +H5E_PLIST_g= +H5E_DATATYPE_g= +H5E_OHDR_g= +H5E_ATOM_g= +H5E_NONE_MAJOR_g= +H5E_SLIST_g= H5E_ARGS_g= H5E_EARRAY_g= -H5E_ERROR_g= H5E_PLINE_g= -H5E_FSPACE_g= +H5E_ERROR_g= H5E_CACHE_g= (-1); /* Reset minor error IDs */ diff --git a/src/H5FA.c b/src/H5FA.c new file mode 100644 index 0000000..a8cd36b --- /dev/null +++ b/src/H5FA.c @@ -0,0 +1,704 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FA.c + * April 2009 + * Vailin Choi + * + * Purpose: Implements a Fixed Array for storing elements + * of datasets with fixed dimensions + * + *------------------------------------------------------------------------- + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Vprivate.h" /* Vector functions */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5FA_t struct */ +H5FL_DEFINE_STATIC(H5FA_t); + +/* Declare a PQ free list to manage the element */ +H5FL_BLK_DEFINE(native_elmt); + + + +/*------------------------------------------------------------------------- + * Function: H5FA_create + * + * Purpose: Creates a new fixed array (header) in the file. + * + * Return: Pointer to fixed array wrapper on success + * NULL on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +H5FA_t *, NULL, NULL, +H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata)) + + /* Local variables */ + H5FA_t *fa = NULL; /* Pointer to new fixed array */ + H5FA_hdr_t *hdr = NULL; /* The fixed array header information */ + haddr_t fa_addr; /* Fixed Array header address */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* + * Check arguments. + */ + HDassert(f); + HDassert(cparam); + + /* Create fixed array header */ + if(HADDR_UNDEF == (fa_addr = H5FA__hdr_create(f, dxpl_id, cparam, ctx_udata))) + H5E_THROW(H5E_CANTINIT, "can't create fixed array header") + + /* Allocate fixed array wrapper */ + if(NULL == (fa = H5FL_MALLOC(H5FA_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info") + + /* Lock the array header into memory */ + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cparam->cls, NULL, H5AC_WRITE))) + H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header") + + /* Point fixed array wrapper at header and bump it's ref count */ + fa->hdr = hdr; + if(H5FA__hdr_incr(fa->hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + + /* Increment # of files using this array header */ + if(H5FA__hdr_fuse_incr(fa->hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header") + + /* Set file pointer for this array open context */ + fa->f = f; + + /* Set the return value */ + ret_value = fa; + +CATCH + + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") + if(!ret_value) + if(fa && H5FA_close(fa, dxpl_id) < 0) + H5E_THROW(H5E_CLOSEERROR, "unable to close fixed array") + +END_FUNC(PRIV) /* end H5FA_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_open + * + * Purpose: Opens an existing fixed array in the file. + * + * Return: Pointer to array wrapper on success + * NULL on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +H5FA_t *, NULL, NULL, +H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr, const H5FA_class_t *cls, + void *ctx_udata)) + + /* Local variables */ + H5FA_t *fa = NULL; /* Pointer to new fixed array wrapper */ + H5FA_hdr_t *hdr = NULL; /* The fixed array header information */ + + /* + * Check arguments. + */ + HDassert(f); + HDassert(H5F_addr_defined(fa_addr)); + HDassert(cls); + + /* Load the array header into memory */ +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr); +#endif /* H5FA_DEBUG */ + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, cls, ctx_udata, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header, address = %llu", (unsigned long long)fa_addr) + + /* Check for pending array deletion */ + if(hdr->pending_delete) + H5E_THROW(H5E_CANTOPENOBJ, "can't open fixed array pending deletion") + + /* Create fixed array info */ + if(NULL == (fa = H5FL_MALLOC(H5FA_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array info") + + /* Point fixed array wrapper at header */ + fa->hdr = hdr; + if(H5FA__hdr_incr(fa->hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + + /* Increment # of files using this array header */ + if(H5FA__hdr_fuse_incr(fa->hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment file reference count on shared array header") + + /* Set file pointer for this array open context */ + fa->f = f; + + /* Set the return value */ + ret_value = fa; + +CATCH + + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") + if(!ret_value) + if(fa && H5FA_close(fa, dxpl_id) < 0) + H5E_THROW(H5E_CLOSEERROR, "unable to close fixed array") + +END_FUNC(PRIV) /* end H5FA_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_get_nelmts + * + * Purpose: Query the current number of elements in array + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, NOERR, +herr_t, SUCCEED, -, +H5FA_get_nelmts(const H5FA_t *fa, hsize_t *nelmts)) + + /* Local variables */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* + * Check arguments. + */ + HDassert(fa); + HDassert(nelmts); + + /* Retrieve the current number of elements in the fixed array */ + *nelmts = fa->hdr->stats.nelmts; + +END_FUNC(PRIV) /* end H5FA_get_nelmts() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_get_addr + * + * Purpose: Query the address of the array + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, NOERR, +herr_t, SUCCEED, -, +H5FA_get_addr(const H5FA_t *fa, haddr_t *addr)) + + /* Local variables */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* + * Check arguments. + */ + HDassert(fa); + HDassert(fa->hdr); + HDassert(addr); + + /* Retrieve the address of the fixed array's header */ + *addr = fa->hdr->addr; + +END_FUNC(PRIV) /* end H5FA_get_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_set + * + * Purpose: Set an element of a fixed array + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5FA_set(const H5FA_t *fa, hid_t dxpl_id, hsize_t idx, const void *elmt)) + + /* Local variables */ + H5FA_hdr_t *hdr = fa->hdr; /* Header for fixed array */ + H5FA_dblock_t *dblock = NULL; /* Pointer to fixed array Data block */ + H5FA_dblk_page_t *dblk_page = NULL; /* Pointer to fixed array Data block page */ + unsigned dblock_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting fixed array Data block */ + unsigned dblk_page_cache_flags = H5AC__NO_FLAGS_SET; /* Flags to unprotecting FIxed Array Data block page */ + hbool_t hdr_dirty = FALSE; /* Whether header information changed */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx); +#endif /* H5FA_DEBUG */ + + /* + * Check arguments. + */ + HDassert(fa); + HDassert(fa->hdr); + + /* Set the shared array header's file context for this operation */ + hdr->f = fa->f; + + /* Check if we need to create the fixed array data block */ + if(!H5F_addr_defined(hdr->dblk_addr)) { +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: fixed array data block address not defined!\n", FUNC, idx); +#endif /* H5FA_DEBUG */ + /* Create the data block */ + hdr->dblk_addr = H5FA__dblock_create(hdr, dxpl_id, &hdr_dirty, hdr->cparam.nelmts); + if(!H5F_addr_defined(hdr->dblk_addr)) + H5E_THROW(H5E_CANTCREATE, "unable to create fixed array data block") + } /* end if */ + + HDassert(idx < hdr->cparam.nelmts); + + /* Protect data block */ + if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, hdr->dblk_addr, hdr->stats.nelmts, H5AC_WRITE))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)hdr->dblk_addr) + + /* Check for paging data block */ + if(!dblock->npages) { + /* Set element in data block */ + HDmemcpy(((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), elmt, hdr->cparam.cls->nat_elmt_size); + dblock_cache_flags |= H5AC__DIRTIED_FLAG; + } /* end if */ + else { /* paging */ + size_t page_idx; /* Index of page within data block */ + size_t dblk_page_nelmts; /* # of elements in a data block page */ + hsize_t elmt_idx; /* Element index within the page */ + haddr_t dblk_page_addr; /* Address of data block page */ + + /* Compute the page & element index */ + page_idx = (size_t)idx / dblock->dblk_page_nelmts; + elmt_idx = (size_t)idx % dblock->dblk_page_nelmts; + + /* Get the address of the data block page */ + dblk_page_addr = dblock->addr + H5FA_DBLOCK_PREFIX_SIZE(dblock) + + (page_idx * dblock->dblk_page_size); + + /* Check for using last page, to set the number of elements on the page */ + if((page_idx + 1) == dblock->npages) + dblk_page_nelmts = dblock->last_page_nelmts; + else + dblk_page_nelmts = dblock->dblk_page_nelmts; + + /* Check if the page has been create yet */ + if(!H5V_bit_get(dblock->dblk_page_init, page_idx)) { + /* Create the data block page */ + if(H5FA__dblk_page_create(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts) < 0) + H5E_THROW(H5E_CANTCREATE, "unable to create data block page") + + /* Mark data block page as initialized in data block */ + H5V_bit_set(dblock->dblk_page_init, page_idx, TRUE); + dblock_cache_flags |= H5AC__DIRTIED_FLAG; + } /* end if */ + + /* Protect the data block page */ + if(NULL == (dblk_page = H5FA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts, H5AC_WRITE))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr) + + /* Set the element in the data block page */ + HDmemcpy(((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), elmt, hdr->cparam.cls->nat_elmt_size); + dblk_page_cache_flags |= H5AC__DIRTIED_FLAG; + } /* end else */ + +CATCH + /* Check for header modified */ + if(hdr_dirty) + if(H5FA__hdr_modified(hdr) < 0) + H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark fixed array header as modified") + + /* Release resources */ + if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, dblock_cache_flags) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block") + if(dblk_page && H5FA__dblk_page_unprotect(dblk_page, dxpl_id, dblk_page_cache_flags) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block page") + +END_FUNC(PRIV) /* end H5FA_set() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_get + * + * Purpose: Get an element of a fixed array + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5FA_get(const H5FA_t *fa, hid_t dxpl_id, hsize_t idx, void *elmt)) + + /* Local variables */ + H5FA_hdr_t *hdr = fa->hdr; /* Header for FA */ + H5FA_dblock_t *dblock = NULL; /* Pointer to data block for FA */ + H5FA_dblk_page_t *dblk_page = NULL; /* Pointer to data block page for FA */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +HDfprintf(stderr, "%s: Index %Hu\n", FUNC, idx); +#endif /* H5FA_DEBUG */ + + /* + * Check arguments. + */ + HDassert(fa); + HDassert(fa->hdr); + + /* Set the shared array header's file context for this operation */ + hdr->f = fa->f; + + /* Check if the fixed array data block has been allocated on disk yet */ + if(!H5F_addr_defined(hdr->dblk_addr)) { + /* Call the class's 'fill' callback */ + if((hdr->cparam.cls->fill)(elmt, (size_t)1) < 0) + H5E_THROW(H5E_CANTSET, "can't set element to class's fill value") + } /* end if */ + else { + /* Get the data block */ + HDassert(H5F_addr_defined(hdr->dblk_addr)); + if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, hdr->dblk_addr, hdr->stats.nelmts, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)hdr->dblk_addr) + + /* Check for paged data block */ + if(!dblock->npages) + /* Retrieve element from data block */ + HDmemcpy(elmt, ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * idx), hdr->cparam.cls->nat_elmt_size); + else { /* paging */ + size_t page_idx; /* Index of page within data block */ + + /* Compute the page index */ + page_idx = (size_t)idx / dblock->dblk_page_nelmts; + + /* Check if the page is defined yet */ + if(!H5V_bit_get(dblock->dblk_page_init, page_idx)) { + /* Call the class's 'fill' callback */ + if((hdr->cparam.cls->fill)(elmt, (size_t)1) < 0) + H5E_THROW(H5E_CANTSET, "can't set element to class's fill value") + + /* We've retrieved the value, leave now */ + H5_LEAVE(SUCCEED) + } /* end if */ + else { /* get the page */ + hsize_t elmt_idx; /* Element index within the page */ + haddr_t dblk_page_addr; /* Address of data block page */ + size_t dblk_page_nelmts; /* # of elements in a data block page */ + + /* Compute the element index */ + elmt_idx = (size_t)idx % dblock->dblk_page_nelmts; + + /* Compute the address of the data block */ + dblk_page_addr = dblock->addr + H5FA_DBLOCK_PREFIX_SIZE(dblock) + (page_idx * dblock->dblk_page_size); + + /* Check for using last page, to set the number of elements on the page */ + if((page_idx + 1) == dblock->npages) + dblk_page_nelmts = dblock->last_page_nelmts; + else + dblk_page_nelmts = dblock->dblk_page_nelmts; + + /* Protect the data block page */ + if(NULL == (dblk_page = H5FA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr) + + /* Retrieve element from data block */ + HDmemcpy(elmt, ((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * elmt_idx), hdr->cparam.cls->nat_elmt_size); + } /* end else */ + } /* end else */ + } /* end else */ + +CATCH + if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block") + if(dblk_page && H5FA__dblk_page_unprotect(dblk_page, dxpl_id, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block page") + +END_FUNC(PRIV) /* end H5FA_get() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_close + * + * Purpose: Close a fixed array + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5FA_close(H5FA_t *fa, hid_t dxpl_id)) + + /* Local variables */ + hbool_t pending_delete = FALSE; /* Whether the array is pending deletion */ + haddr_t fa_addr = HADDR_UNDEF; /* Address of array (for deletion) */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* + * Check arguments. + */ + HDassert(fa); + + /* Decrement file reference & check if this is the last open fixed array using the shared array header */ + if(0 == H5FA__hdr_fuse_decr(fa->hdr)) { + /* Set the shared array header's file context for this operation */ + fa->hdr->f = fa->f; + + /* Shut down anything that can't be put in the header's 'flush' callback */ + + /* Check for pending array deletion */ + if(fa->hdr->pending_delete) { + /* Set local info, so array deletion can occur after decrementing the + * header's ref count + */ + pending_delete = TRUE; + fa_addr = fa->hdr->addr; + } /* end if */ + } /* end if */ + + /* Decrement the reference count on the array header */ + /* (don't put in H5FA_hdr_fuse_decr() as the array header may be evicted + * immediately -QAK) + */ + if(H5FA__hdr_decr(fa->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + + /* Check for pending array deletion */ + if(pending_delete) { + H5FA_hdr_t *hdr; /* Another pointer to fixed array header */ + + /* Lock the array header into memory */ + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(fa->f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE))) + H5E_THROW(H5E_CANTLOAD, "unable to load fixed array header") + + /* Set the shared array header's file context for this operation */ + hdr->f = fa->f; + + /* Delete array, starting with header (unprotects header) */ + if(H5FA__hdr_delete(hdr, dxpl_id) < 0) + H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array") + } /* end if */ + + /* Release the fixed array wrapper */ + fa = H5FL_FREE(H5FA_t, fa); + +CATCH + +END_FUNC(PRIV) /* end H5FA_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_delete + * + * Purpose: Delete a fixed array + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t fa_addr)) + + /* Local variables */ + H5FA_hdr_t *hdr = NULL; /* The fixed array header information */ + + /* + * Check arguments. + */ + HDassert(f); + HDassert(H5F_addr_defined(fa_addr)); + + /* Lock the array header into memory */ +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: fa_addr = %a\n", FUNC, fa_addr); +#endif /* H5FA_DEBUG */ + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, NULL, NULL, H5AC_WRITE))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array header, address = %llu", (unsigned long long)fa_addr) + + /* Check for files using shared array header */ + if(hdr->file_rc) + hdr->pending_delete = TRUE; + else { + /* Set the shared array header's file context for this operation */ + hdr->f = f; + + /* Delete array now, starting with header (unprotects header) */ + if(H5FA__hdr_delete(hdr, dxpl_id) < 0) + H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array") + hdr = NULL; + } /* end if */ + +CATCH + + /* Unprotect the header, if an error occurred */ + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, fa_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") + +END_FUNC(PRIV) /* end H5FA_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_iterate + * + * Purpose: Iterate over the elements of a fixed array + * + * Note: This is not very efficient, we should be iterating directly + * over the fixed array's direct block [pages]. + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERR, +herr_t, SUCCEED, FAIL, +H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata)) + + /* Local variables */ + uint8_t *elmt = NULL; + hsize_t u; + + /* + * Check arguments. + */ + HDassert(fa); + HDassert(op); + HDassert(udata); + + /* Allocate space for a native array element */ + if(NULL == (elmt = H5FL_BLK_MALLOC(native_elmt, fa->hdr->cparam.cls->nat_elmt_size))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array element") + + /* Iterate over all elements in array */ + for(u = 0; u < fa->hdr->stats.nelmts; u++) { + int cb_ret; /* Return value from callback */ + + /* Get array element */ + if(H5FA_get(fa, dxpl_id, u, elmt) < 0) + H5E_THROW(H5E_CANTGET, "unable to delete fixed array") + + /* Make callback */ + if((cb_ret = (*op)(u, elmt, udata)) < 0) { + H5E_PRINTF(H5E_BADITER, "iterator function failed"); + H5_LEAVE(cb_ret) + } /* end if */ + } /* end for */ + +CATCH + + if(elmt) + (void)H5FL_BLK_FREE(native_elmt, elmt); + +END_FUNC(PRIV) /* end H5FA_iterate() */ + diff --git a/src/H5FAcache.c b/src/H5FAcache.c new file mode 100644 index 0000000..7a7e867 --- /dev/null +++ b/src/H5FAcache.c @@ -0,0 +1,1107 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FAcache.c + * + * Purpose: Implement fixed array metadata cache methods. + * + *------------------------------------------------------------------------- + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE + + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ +#include "H5MFprivate.h" /* File memory management */ +#include "H5Vprivate.h" /* Vectors and arrays */ +#include "H5WBprivate.h" /* Wrapped Buffers */ + + +/****************/ +/* Local Macros */ +/****************/ + +/* Fixed Array format version #'s */ +#define H5FA_HDR_VERSION 0 /* Header */ +#define H5FA_DBLOCK_VERSION 0 /* Data block */ + +/* Size of stack buffer for serialization buffers */ +#define H5FA_HDR_BUF_SIZE 512 +#define H5FA_DBLOCK_BUF_SIZE 512 +#define H5FA_DBLK_PAGE_BUF_SIZE 512 + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +/* Metadata cache (H5AC) callbacks */ +static H5FA_hdr_t *H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); +static herr_t H5FA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FA_hdr_t *hdr, unsigned * flags_ptr); +static herr_t H5FA__cache_hdr_clear(H5F_t *f, H5FA_hdr_t *hdr, hbool_t destroy); +static herr_t H5FA__cache_hdr_size(const H5F_t *f, const H5FA_hdr_t *hdr, size_t *size_ptr); +static herr_t H5FA__cache_hdr_dest(H5F_t *f, H5FA_hdr_t *hdr); + +static H5FA_dblock_t *H5FA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); +static herr_t H5FA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FA_dblock_t *dblock, unsigned * flags_ptr); +static herr_t H5FA__cache_dblock_clear(H5F_t *f, H5FA_dblock_t *dblock, hbool_t destroy); +static herr_t H5FA__cache_dblock_size(const H5F_t *f, const H5FA_dblock_t *dblock, size_t *size_ptr); +static herr_t H5FA__cache_dblock_dest(H5F_t *f, H5FA_dblock_t *dblock); + +static H5FA_dblk_page_t *H5FA__cache_dblk_page_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *udata, void *udata2); +static herr_t H5FA__cache_dblk_page_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5FA_dblk_page_t *dblk_page, unsigned * flags_ptr); +static herr_t H5FA__cache_dblk_page_clear(H5F_t *f, H5FA_dblk_page_t *dblk_page, hbool_t destroy); +static herr_t H5FA__cache_dblk_page_size(const H5F_t *f, const H5FA_dblk_page_t *dblk_page, size_t *size_ptr); +static herr_t H5FA__cache_dblk_page_dest(H5F_t *f, H5FA_dblk_page_t *dblk_page); + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* H5FA header inherits cache-like properties from H5AC */ +const H5AC_class_t H5AC_FARRAY_HDR[1] = {{ + H5AC_FARRAY_HDR_ID, + (H5AC_load_func_t)H5FA__cache_hdr_load, + (H5AC_flush_func_t)H5FA__cache_hdr_flush, + (H5AC_dest_func_t)H5FA__cache_hdr_dest, + (H5AC_clear_func_t)H5FA__cache_hdr_clear, + (H5AC_notify_func_t)NULL, + (H5AC_size_func_t)H5FA__cache_hdr_size, +}}; + + +/* H5FA data block inherits cache-like properties from H5AC */ +const H5AC_class_t H5AC_FARRAY_DBLOCK[1] = {{ + H5AC_FARRAY_DBLOCK_ID, + (H5AC_load_func_t)H5FA__cache_dblock_load, + (H5AC_flush_func_t)H5FA__cache_dblock_flush, + (H5AC_dest_func_t)H5FA__cache_dblock_dest, + (H5AC_clear_func_t)H5FA__cache_dblock_clear, + (H5AC_notify_func_t)NULL, + (H5AC_size_func_t)H5FA__cache_dblock_size, +}}; + +/* H5FA data block page inherits cache-like properties from H5AC */ +const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1] = {{ + H5AC_FARRAY_DBLK_PAGE_ID, + (H5AC_load_func_t)H5FA__cache_dblk_page_load, + (H5AC_flush_func_t)H5FA__cache_dblk_page_flush, + (H5AC_dest_func_t)H5FA__cache_dblk_page_dest, + (H5AC_clear_func_t)H5FA__cache_dblk_page_clear, + (H5AC_notify_func_t)NULL, + (H5AC_size_func_t)H5FA__cache_dblk_page_size, +}}; + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_hdr_load + * + * Purpose: Loads a fixed array header from the disk. + * + * Return: Success: Pointer to a new fixed array + * Failure: NULL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +H5FA_hdr_t *, NULL, NULL, +H5FA__cache_hdr_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_cls, + void *ctx_udata)) + + /* Local variables */ + const H5FA_class_t *cls = (const H5FA_class_t *)_cls; /* Fixed array class */ + H5FA_hdr_t *hdr = NULL; /* Fixed array info */ + size_t size; /* Header size */ + H5WB_t *wb = NULL; /* Wrapped buffer for header data */ + uint8_t hdr_buf[H5FA_HDR_BUF_SIZE]; /* Buffer for header */ + uint8_t *buf; /* Pointer to header buffer */ + const uint8_t *p; /* Pointer into raw data buffer */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + + /* Check arguments */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + + /* Allocate space for the fixed array data structure */ + if(NULL == (hdr = H5FA__hdr_alloc(f, cls, ctx_udata))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array shared header") + + /* Set the fixed array header's address */ + hdr->addr = addr; + + /* Wrap the local buffer for serialized info */ + if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf)))) + H5E_THROW(H5E_CANTINIT, "can't wrap buffer") + + /* Compute the 'base' size of the fixed array header on disk */ + size = H5FA_HEADER_SIZE(hdr); + + /* Get a pointer to a buffer that's large enough for serialized header */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) + H5E_THROW(H5E_CANTGET, "can't get actual buffer") + + /* Read header from disk */ + if(H5F_block_read(f, H5FD_MEM_FARRAY_HDR, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_READERROR, "can't read fixed array header") + + /* Get temporary pointer to serialized header */ + p = buf; + + /* Magic number */ + if(HDmemcmp(p, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + H5E_THROW(H5E_BADVALUE, "wrong fixed array header signature") + p += H5_SIZEOF_MAGIC; + + /* Version */ + if(*p++ != H5FA_HDR_VERSION) + H5E_THROW(H5E_VERSION, "wrong fixed array header version") + + /* Fixed array type */ + if(*p++ != (uint8_t)cls->id) + H5E_THROW(H5E_BADTYPE, "incorrect fixed array class") + + /* General array creation/configuration information */ + hdr->cparam.raw_elmt_size = *p++; /* Element size in file (in bytes) */ + hdr->cparam.max_dblk_page_nelmts_bits = *p++; /* Log2(Max. # of elements in data block page) - + i.e. # of bits needed to store max. # of + elements in data block page. */ + + /* Array statistics */ + H5F_DECODE_LENGTH(f, p, hdr->cparam.nelmts); /* Number of elements */ + + /* Internal information */ + H5F_addr_decode(f, &p, &hdr->dblk_addr); /* Address of index block */ + + /* Initializations of header info */ + hdr->stats.nelmts = hdr->cparam.nelmts; + hdr->stats.hdr_size = hdr->size = size; /* Size of header in file */ + + /* Sanity check */ + /* (allow for checksum not decoded yet) */ + HDassert((size_t)(p - buf) == (size - H5FA_SIZEOF_CHKSUM)); + + /* Compute checksum on entire header */ + /* (including the filter information, if present) */ + computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + + /* Metadata checksum */ + UINT32DECODE(p, stored_chksum); + + /* Sanity check */ + HDassert((size_t)(p - buf) == size); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array header") + + /* Set return value */ + ret_value = hdr; + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + if(!ret_value) + if(hdr && H5FA__cache_hdr_dest(f, hdr) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header") + +END_FUNC(STATIC) /* end H5FA__cache_hdr_load() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_hdr_flush + * + * Purpose: Flushes a dirty fixed array header to disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_hdr_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, + H5FA_hdr_t *hdr, unsigned UNUSED * flags_ptr)) + + H5WB_t *wb = NULL; /* Wrapped buffer for header data */ + uint8_t hdr_buf[H5FA_HDR_BUF_SIZE]; /* Buffer for header */ + + /* check arguments */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(hdr); + + if(hdr->cache_info.is_dirty) { + uint8_t *buf; /* Temporary raw data buffer */ + uint8_t *p; /* Pointer into raw data buffer */ + size_t size; /* Header size on disk */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ + + /* Wrap the local buffer for serialized header info */ + if(NULL == (wb = H5WB_wrap(hdr_buf, sizeof(hdr_buf)))) + H5E_THROW(H5E_CANTINIT, "can't wrap buffer") + + /* Compute the size of the array header on disk */ + size = hdr->size; + + /* Get a pointer to a buffer that's large enough for serialized header */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) + H5E_THROW(H5E_CANTGET, "can't get actual buffer") + + /* Get temporary pointer to serialized header */ + p = buf; + + /* Magic number */ + HDmemcpy(p, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC); + p += H5_SIZEOF_MAGIC; + + /* Version # */ + *p++ = H5FA_HDR_VERSION; + + /* Fixed array type */ + *p++ = hdr->cparam.cls->id; + + /* General array creation/configuration information */ + *p++ = hdr->cparam.raw_elmt_size; /* Element size in file (in bytes) */ + *p++ = hdr->cparam.max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */ + + /* Array statistics */ + H5F_ENCODE_LENGTH(f, p, hdr->stats.nelmts); /* Number of elements for the fixed array */ + + /* Internal information */ + H5F_addr_encode(f, &p, hdr->dblk_addr); /* Address of fixed array data block */ + + /* Compute metadata checksum */ + metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); + + /* Write the array header. */ + HDassert((size_t)(p - buf) == size); + if(H5F_block_write(f, H5FD_MEM_FARRAY_HDR, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_WRITEERROR, "unable to save fixed array header to disk") + + hdr->cache_info.is_dirty = FALSE; + } /* end if */ + + if(destroy) + if(H5FA__cache_hdr_dest(f, hdr) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header") + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + +END_FUNC(STATIC) /* end H5FA__cache_hdr_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_hdr_clear + * + * Purpose: Mark a fixed array header in memory as non-dirty. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_hdr_clear(H5F_t *f, H5FA_hdr_t *hdr, hbool_t destroy)) + + /* Sanity check */ + HDassert(hdr); + + /* Reset the dirty flag. */ + hdr->cache_info.is_dirty = FALSE; + + if(destroy) + if(H5FA__cache_hdr_dest(f, hdr) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header") + +CATCH + +END_FUNC(STATIC) /* end H5FA__cache_hdr_clear() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_hdr_size + * + * Purpose: Compute the size in bytes of a fixed array header + * 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: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__cache_hdr_size(const H5F_t UNUSED *f, const H5FA_hdr_t *hdr, + size_t *size_ptr)) + + /* Sanity check */ + HDassert(f); + HDassert(hdr); + HDassert(size_ptr); + + /* Set size value */ + *size_ptr = hdr->size; + +END_FUNC(STATIC) /* end H5FA__cache_hdr_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_hdr_dest + * + * Purpose: Destroys a fixed array header in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_hdr_dest(H5F_t *f, H5FA_hdr_t *hdr)) + + /* Check arguments */ + HDassert(f); + HDassert(hdr); + + /* Verify that header is clean */ + HDassert(hdr->cache_info.is_dirty == FALSE); + + /* If we're going to free the space on disk, the address must be valid */ + HDassert(!hdr->cache_info.free_file_space_on_destroy || H5F_addr_defined(hdr->cache_info.addr)); + + /* Check for freeing file space for fixed array header */ + if(hdr->cache_info.free_file_space_on_destroy) { + /* Sanity check address */ + HDassert(H5F_addr_eq(hdr->addr, hdr->cache_info.addr)); + + /* Release the space on disk */ + /* (XXX: Nasty usage of internal DXPL value! -QAK) */ + if(H5MF_xfree(f, H5FD_MEM_FARRAY_HDR, H5AC_dxpl_id, hdr->cache_info.addr, (hsize_t)hdr->size) < 0) + H5E_THROW(H5E_CANTFREE, "unable to free fixed array header") + } /* end if */ + + /* Release the fixed array header */ + if(H5FA__hdr_dest(hdr) < 0) + H5E_THROW(H5E_CANTFREE, "can't free fixed array header") + +CATCH + +END_FUNC(STATIC) /* end H5FA__cache_hdr_dest() */ + + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblock_load + * + * Purpose: Loads a fixed array data block from the disk. + * + * Return: Success: Pointer to a new fixed array data block + * Failure: NULL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +H5FA_dblock_t *, NULL, NULL, +H5FA__cache_dblock_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *_nelmts, void *_hdr)) + + /* Local variables */ + H5FA_hdr_t *hdr = (H5FA_hdr_t *)_hdr; /* Shared fixed array information */ + const hsize_t *nelmts = (const hsize_t *)_nelmts; /* Number of elements in data block */ + H5FA_dblock_t *dblock = NULL; /* Data block info */ + size_t size; /* Data block size */ + H5WB_t *wb = NULL; /* Wrapped buffer for data block data */ + uint8_t dblock_buf[H5FA_DBLOCK_BUF_SIZE]; /* Buffer for data block */ + uint8_t *buf; /* Pointer to data block buffer */ + const uint8_t *p; /* Pointer into raw data buffer */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + haddr_t arr_addr; /* Address of array header in the file */ + + /* Sanity check */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(nelmts && *nelmts > 0); + HDassert(hdr); + + /* Allocate the fixed array data block */ + if(NULL == (dblock = H5FA__dblock_alloc(hdr, *nelmts))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block") + + /* Set the fixed array data block's information */ + dblock->addr = addr; + + /* Wrap the local buffer for serialized info */ + if(NULL == (wb = H5WB_wrap(dblock_buf, sizeof(dblock_buf)))) + H5E_THROW(H5E_CANTINIT, "can't wrap buffer") + + /* Compute the size of the fixed array data block on disk */ + if(!dblock->npages) + size = (size_t)H5FA_DBLOCK_SIZE(dblock); + else + size = H5FA_DBLOCK_PREFIX_SIZE(dblock); + + /* Get a pointer to a buffer that's large enough for serialized info */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) + H5E_THROW(H5E_CANTGET, "can't get actual buffer") + + /* Read data block from disk */ + if(H5F_block_read(f, H5FD_MEM_FARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_READERROR, "can't read fixed array data block") + + /* Get temporary pointer to serialized header */ + p = buf; + + /* Magic number */ + if(HDmemcmp(p, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) + H5E_THROW(H5E_BADVALUE, "wrong fixed array data block signature") + p += H5_SIZEOF_MAGIC; + + /* Version */ + if(*p++ != H5FA_DBLOCK_VERSION) + H5E_THROW(H5E_VERSION, "wrong fixed array data block version") + + /* Address of header for array that owns this block (just for file integrity checks) */ + H5F_addr_decode(f, &p, &arr_addr); + if(H5F_addr_ne(arr_addr, hdr->addr)) + H5E_THROW(H5E_BADVALUE, "wrong fixed array header address") + + /* Fixed array type */ + if(*p++ != (uint8_t)hdr->cparam.cls->id) + H5E_THROW(H5E_BADTYPE, "incorrect fixed array class") + + /* Page initialization flags */ + if(dblock->npages > 0) { + HDmemcpy(dblock->dblk_page_init, p, dblock->dblk_page_init_size); + p += dblock->dblk_page_init_size; + } /* end if */ + + /* Only decode elements if the data block is not paged */ + if(!dblock->npages) { + /* Decode elements in data block */ + /* Convert from raw elements on disk into native elements in memory */ + if((hdr->cparam.cls->decode)(p, dblock->elmts, (size_t)*nelmts, hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTDECODE, "can't decode fixed array data elements") + p += (*nelmts * hdr->cparam.raw_elmt_size); + } /* end if */ + + /* Sanity check */ + /* (allow for checksum not decoded yet) */ + HDassert((size_t)(p - buf) == (size - H5FA_SIZEOF_CHKSUM)); + + /* Set the data block's size */ + dblock->size = H5FA_DBLOCK_SIZE(dblock); + + /* Compute checksum on data block */ + computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + + /* Metadata checksum */ + UINT32DECODE(p, stored_chksum); + + /* Sanity check */ + HDassert((size_t)(p - buf) == size); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array data block") + + /* Set return value */ + ret_value = dblock; + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + if(!ret_value) + if(dblock && H5FA__cache_dblock_dest(f, dblock) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block") + +END_FUNC(STATIC) /* end H5FA__cache_dblock_load() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblock_flush + * + * Purpose: Flushes a dirty fixed array data block to disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_dblock_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, + H5FA_dblock_t *dblock, unsigned UNUSED * flags_ptr)) + + /* Local variables */ + H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */ + uint8_t ser_buf[H5FA_DBLOCK_BUF_SIZE]; /* Serialization buffer */ + + /* Sanity check */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(dblock); + HDassert(dblock->hdr); + + if(dblock->cache_info.is_dirty) { + uint8_t *buf; /* Temporary raw data buffer */ + uint8_t *p; /* Pointer into raw data buffer */ + size_t size; /* Index block size on disk */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ + + /* Wrap the local buffer for serialized info */ + if(NULL == (wb = H5WB_wrap(ser_buf, sizeof(ser_buf)))) + H5E_THROW(H5E_CANTINIT, "can't wrap buffer") + + /* Compute the size of the data block on disk */ + if(!dblock->npages) + size = (size_t)dblock->size; + else + size = H5FA_DBLOCK_PREFIX_SIZE(dblock); + + /* Get a pointer to a buffer that's large enough for serialized info */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) + H5E_THROW(H5E_CANTGET, "can't get actual buffer") + + /* Get temporary pointer to serialized info */ + p = buf; + + /* Magic number */ + HDmemcpy(p, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC); + p += H5_SIZEOF_MAGIC; + + /* Version # */ + *p++ = H5FA_DBLOCK_VERSION; + + /* Address of array header for array which owns this block */ + H5F_addr_encode(f, &p, dblock->hdr->addr); + + /* Fixed array type */ + *p++ = dblock->hdr->cparam.cls->id; + + /* Page init flags */ + if(dblock->npages > 0) { + /* Store the 'page init' bitmasks */ + HDmemcpy(p, dblock->dblk_page_init, dblock->dblk_page_init_size); + p += dblock->dblk_page_init_size; + } /* end if */ + + /* Only encode elements if the data block is not paged */ + if(!dblock->npages) { + /* Encode elements in data block */ + + /* Convert from native elements in memory into raw elements on disk */ + H5_CHECK_OVERFLOW(dblock->hdr->cparam.nelmts, /* From: */hsize_t, /* To: */size_t); + if((dblock->hdr->cparam.cls->encode)(p, dblock->elmts, (size_t)dblock->hdr->cparam.nelmts, dblock->hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTENCODE, "can't encode fixed array data elements") + p += (dblock->hdr->cparam.nelmts * dblock->hdr->cparam.raw_elmt_size); + } /* end if */ + + /* Compute metadata checksum */ + metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); + + /* Write the data block */ + HDassert((size_t)(p - buf) == size); + if(H5F_block_write(f, H5FD_MEM_FARRAY_DBLOCK, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_WRITEERROR, "unable to save fixed array data block to disk") + + dblock->cache_info.is_dirty = FALSE; + } /* end if */ + + if(destroy) + if(H5FA__cache_dblock_dest(f, dblock) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block") + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + +END_FUNC(STATIC) /* end H5FA__cache_dblock_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblock_clear + * + * Purpose: Mark a fixed array data block in memory as non-dirty. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_dblock_clear(H5F_t *f, H5FA_dblock_t *dblock, hbool_t destroy)) + + /* Sanity check */ + HDassert(dblock); + + /* Reset the dirty flag */ + dblock->cache_info.is_dirty = FALSE; + + if(destroy) + if(H5FA__cache_dblock_dest(f, dblock) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block") + +CATCH + +END_FUNC(STATIC) /* end H5FA__cache_dblock_clear() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblock_size + * + * Purpose: Compute the size in bytes of a fixed array data block + * 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: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__cache_dblock_size(const H5F_t UNUSED *f, const H5FA_dblock_t *dblock, + size_t *size_ptr)) + + /* Sanity check */ + HDassert(f); + HDassert(dblock); + HDassert(size_ptr); + + /* Set size value */ + if(!dblock->npages) + *size_ptr = (size_t)dblock->size; + else + *size_ptr = H5FA_DBLOCK_PREFIX_SIZE(dblock); + +END_FUNC(STATIC) /* end H5FA__cache_dblock_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblock_dest + * + * Purpose: Destroys a fixed array data block in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_dblock_dest(H5F_t *f, H5FA_dblock_t *dblock)) + + /* Sanity check */ + HDassert(f); + HDassert(dblock); + + /* Verify that data block is clean */ + HDassert(dblock->cache_info.is_dirty == FALSE); + + /* If we're going to free the space on disk, the address must be valid */ + HDassert(!dblock->cache_info.free_file_space_on_destroy || H5F_addr_defined(dblock->cache_info.addr)); + + /* Check for freeing file space for fixed array data block */ + if(dblock->cache_info.free_file_space_on_destroy) { + /* Sanity check address */ + HDassert(H5F_addr_eq(dblock->addr, dblock->cache_info.addr)); + + /* Release the space on disk */ + /* (Includes space for pages!) */ + /* (XXX: Nasty usage of internal DXPL value! -QAK) */ + if(H5MF_xfree(f, H5FD_MEM_FARRAY_DBLOCK, H5AC_dxpl_id, dblock->cache_info.addr, (hsize_t)dblock->size) < 0) + H5E_THROW(H5E_CANTFREE, "unable to free fixed array data block") + } /* end if */ + + /* Release the data block */ + if(H5FA__dblock_dest(f, dblock) < 0) + H5E_THROW(H5E_CANTFREE, "can't free fixed array data block") + +CATCH + +END_FUNC(STATIC) /* end H5FA__cache_dblock_dest() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblk_page_load + * + * Purpose: Loads a fixed array data block page from the disk. + * + * Return: Success: Pointer to a new fixed array data block page + * Failure: NULL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +H5FA_dblk_page_t *, NULL, NULL, +H5FA__cache_dblk_page_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, + const void *_udata1, void *_hdr)) + + /* Local variables */ + H5FA_hdr_t *hdr = (H5FA_hdr_t *)_hdr; /* Shared fixed array information */ + const H5FA_dblk_page_load_ud_t *ud_load = (const H5FA_dblk_page_load_ud_t *)_udata1; /* User data for loading data block page */ + H5FA_dblk_page_t *dblk_page = NULL; /* Data block page info */ + size_t size; /* Data block page size */ + H5WB_t *wb = NULL; /* Wrapped buffer for data block page data */ + uint8_t dblk_page_buf[H5FA_DBLK_PAGE_BUF_SIZE]; /* Buffer for data block page */ + uint8_t *buf; /* Pointer to data block page buffer */ + const uint8_t *p; /* Pointer into raw data buffer */ + uint32_t stored_chksum; /* Stored metadata checksum value */ + uint32_t computed_chksum; /* Computed metadata checksum value */ + + /* Sanity check */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(hdr); +#ifdef QAK +HDfprintf(stderr, "%s: addr = %a\n", FUNC, addr); +#endif /* QAK */ + + /* Allocate the fixed array data block page */ + if(NULL == (dblk_page = H5FA__dblk_page_alloc(hdr, ud_load->nelmts))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block page") + + /* Set the fixed array data block's information */ + dblk_page->addr = addr; + + /* Wrap the local buffer for serialized info */ + if(NULL == (wb = H5WB_wrap(dblk_page_buf, sizeof(dblk_page_buf)))) + H5E_THROW(H5E_CANTINIT, "can't wrap buffer") + + /* Compute the size of the fixed array data block page on disk */ + size = H5FA_DBLK_PAGE_SIZE(dblk_page, ud_load->nelmts); + + /* Get a pointer to a buffer that's large enough for serialized info */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) + H5E_THROW(H5E_CANTGET, "can't get actual buffer") + + /* Read data block page from disk */ + if(H5F_block_read(f, H5FD_MEM_FARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_READERROR, "can't read fixed array data block page") + + /* Get temporary pointer to serialized header */ + p = buf; + + /* Internal information */ + + /* Decode elements in data block page */ + /* Convert from raw elements on disk into native elements in memory */ + if((hdr->cparam.cls->decode)(p, dblk_page->elmts, ud_load->nelmts, hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTDECODE, "can't decode fixed array data elements") + p += (ud_load->nelmts * hdr->cparam.raw_elmt_size); + + /* Sanity check */ + /* (allow for checksum not decoded yet) */ + HDassert((size_t)(p - buf) == (size - H5FA_SIZEOF_CHKSUM)); + + /* Set the data block page's size */ + dblk_page->size = size; + + /* Compute checksum on data block */ + computed_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + + /* Metadata checksum */ + UINT32DECODE(p, stored_chksum); + + /* Sanity check */ + HDassert((size_t)(p - buf) == dblk_page->size); + + /* Verify checksum */ + if(stored_chksum != computed_chksum) + H5E_THROW(H5E_BADVALUE, "incorrect metadata checksum for fixed array data block page") + + /* Set return value */ + ret_value = dblk_page; + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + if(!ret_value) + if(dblk_page && H5FA__cache_dblk_page_dest(f, dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page") + +END_FUNC(STATIC) /* end H5FA__cache_dblk_page_load() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblk_page_flush + * + * Purpose: Flushes a dirty fixed array data block page to disk. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_dblk_page_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, + H5FA_dblk_page_t *dblk_page, unsigned UNUSED * flags_ptr)) + + /* Local variables */ + H5WB_t *wb = NULL; /* Wrapped buffer for serializing data */ + uint8_t ser_buf[H5FA_DBLK_PAGE_BUF_SIZE]; /* Serialization buffer */ + + /* Sanity check */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(dblk_page); + HDassert(dblk_page->hdr); + + if(dblk_page->cache_info.is_dirty) { + uint8_t *buf; /* Temporary raw data buffer */ + uint8_t *p; /* Pointer into raw data buffer */ + size_t size; /* Index block size on disk */ + uint32_t metadata_chksum; /* Computed metadata checksum value */ + + /* Wrap the local buffer for serialized info */ + if(NULL == (wb = H5WB_wrap(ser_buf, sizeof(ser_buf)))) + H5E_THROW(H5E_CANTINIT, "can't wrap buffer") + + /* Compute the size of the data block on disk */ + size = dblk_page->size; + + /* Get a pointer to a buffer that's large enough for serialized info */ + if(NULL == (buf = (uint8_t *)H5WB_actual(wb, size))) + H5E_THROW(H5E_CANTGET, "can't get actual buffer") + + /* Get temporary pointer to serialized info */ + p = buf; + + /* Internal information */ + + /* Encode elements in data block page */ + + /* Convert from native elements in memory into raw elements on disk */ + if((dblk_page->hdr->cparam.cls->encode)(p, dblk_page->elmts, dblk_page->nelmts, dblk_page->hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTENCODE, "can't encode fixed array data elements") + p += (dblk_page->nelmts * dblk_page->hdr->cparam.raw_elmt_size); + + /* Compute metadata checksum */ + metadata_chksum = H5_checksum_metadata(buf, (size_t)(p - buf), 0); + + /* Metadata checksum */ + UINT32ENCODE(p, metadata_chksum); + + /* Write the data block */ + HDassert((size_t)(p - buf) == size); + if(H5F_block_write(f, H5FD_MEM_FARRAY_DBLK_PAGE, addr, size, dxpl_id, buf) < 0) + H5E_THROW(H5E_WRITEERROR, "unable to save fixed array data block page to disk") + + dblk_page->cache_info.is_dirty = FALSE; + } /* end if */ + + if(destroy) + if(H5FA__cache_dblk_page_dest(f, dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page") + +CATCH + + /* Release resources */ + if(wb && H5WB_unwrap(wb) < 0) + H5E_THROW(H5E_CLOSEERROR, "can't close wrapped buffer") + +END_FUNC(STATIC) /* end H5FA__cache_dblk_page_flush() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblk_page_clear + * + * Purpose: Mark a fixed array data block page in memory as non-dirty. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_dblk_page_clear(H5F_t *f, H5FA_dblk_page_t *dblk_page, hbool_t destroy)) + + /* Sanity check */ + HDassert(dblk_page); + + /* Reset the dirty flag */ + dblk_page->cache_info.is_dirty = FALSE; + + if(destroy) + if(H5FA__cache_dblk_page_dest(f, dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page") + +CATCH + +END_FUNC(STATIC) /* end H5FA__cache_dblk_page_clear() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblk_page_size + * + * Purpose: Compute the size in bytes of a fixed array data block page + * 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: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__cache_dblk_page_size(const H5F_t UNUSED *f, const H5FA_dblk_page_t *dblk_page, + size_t *size_ptr)) + + /* Sanity check */ + HDassert(f); + HDassert(dblk_page); + HDassert(size_ptr); + + /* Set size value */ + *size_ptr = dblk_page->size; + +END_FUNC(STATIC) /* end H5FA__cache_dblk_page_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__cache_dblk_page_dest + * + * Purpose: Destroys a fixed array data block page in memory. + * + * Note: Does _not_ free the space for the page on disk, that is + * handled through the data block that "owns" the page. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(STATIC, ERR, +herr_t, SUCCEED, FAIL, +H5FA__cache_dblk_page_dest(H5F_t UNUSED *f, H5FA_dblk_page_t *dblk_page)) + + /* Sanity check */ + HDassert(f); + HDassert(dblk_page); + + /* Verify that data block page is clean */ + HDassert(dblk_page->cache_info.is_dirty == FALSE); + + /* Release the data block page */ + if(H5FA__dblk_page_dest(dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "can't free fixed array data block page") + +CATCH + +END_FUNC(STATIC) /* end H5FA__cache_dblk_page_dest() */ + diff --git a/src/H5FAdbg.c b/src/H5FAdbg.c new file mode 100644 index 0000000..b882c04 --- /dev/null +++ b/src/H5FAdbg.c @@ -0,0 +1,321 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FAdbg.c + * + * Purpose: Dump debugging information about a fixed array. + * + *------------------------------------------------------------------------- + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE + + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ +#include "H5Oprivate.h" /* Object Header */ +#include "H5Vprivate.h" /* Vector functions */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Fixed array create/open user data */ +typedef struct ctx_ud_t { + const H5F_t *f; /* Pointer to file info */ + const H5O_layout_t *layout; /* Pointer to layout info */ +} ctx_ud_t; + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_debug + * + * Purpose: Prints debugging info about a fixed array header. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, + int fwidth, const H5FA_class_t *cls, haddr_t obj_addr)) + + /* Local variables */ + H5FA_hdr_t *hdr = NULL; /* Shared fixed array header */ + H5O_loc_t obj_loc; /* Pointer to an object's location */ + H5O_layout_t layout; /* Layout message */ + ctx_ud_t udata; /* User data */ + + /* Check arguments */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(H5F_addr_defined(obj_addr)); + HDassert(stream); + HDassert(indent >= 0); + HDassert(fwidth >= 0); + HDassert(cls); + + H5O_loc_reset(&obj_loc); + obj_loc.file = f; + obj_loc.addr = obj_addr; + + /* Open the object header where the layout message resides */ + if(H5O_open(&obj_loc) < 0) + H5E_THROW(H5E_CANTPROTECT, "unable to open object header") + + /* Read the layout message */ + if(NULL == H5O_msg_read(&obj_loc, H5O_LAYOUT_ID, &layout, dxpl_id)) + H5E_THROW(H5E_CANTPROTECT, "unable to read layout message") + + /* close the object header */ + if(H5O_close(&obj_loc) < 0) + H5E_THROW(H5E_CANTPROTECT, "unable to close object header") + + /* Create user data */ + udata.f = f; + udata.layout = &layout; + + /* Load the fixed array header */ + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, addr, cls, &udata, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header") + + /* Print opening message */ + HDfprintf(stream, "%*sFixed Array Header...\n", indent, ""); + + /* Print the values */ + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Array class ID:", hdr->cparam.cls->name); + HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, + "Header size:", + hdr->size); + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Raw Element Size:", + (unsigned)hdr->cparam.raw_elmt_size); + HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, + "Native Element Size (on this platform):", + hdr->cparam.cls->nat_elmt_size); + + + HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth, + "Max. # of elements in data block page:", + (unsigned)((size_t)1 << hdr->cparam.max_dblk_page_nelmts_bits)); + + HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, + "Number of elements in Fixed Array:", hdr->stats.nelmts); + + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, + "Fixed Array Data Block Address:", hdr->dblk_addr); + +CATCH + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, addr, hdr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") + +END_FUNC(PKG) /* end H5FA__hdr_debug() */ + + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblock_debug + * + * Purpose: Prints debugging info about a fixed array data block. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, + int fwidth, const H5FA_class_t *cls, haddr_t hdr_addr, haddr_t obj_addr)) + + /* Local variables */ + H5FA_hdr_t *hdr = NULL; /* Shared fixed array header */ + H5FA_dblock_t *dblock = NULL; /* Fixed array data block */ + size_t u; /* Local index variable */ + H5O_loc_t obj_loc; /* Pointer to an object's location */ + H5O_layout_t layout; /* Layout message */ + ctx_ud_t udata; /* User data */ + + /* Check arguments */ + HDassert(f); + HDassert(H5F_addr_defined(addr)); + HDassert(stream); + HDassert(indent >= 0); + HDassert(fwidth >= 0); + HDassert(cls); + HDassert(H5F_addr_defined(hdr_addr)); + HDassert(H5F_addr_defined(obj_addr)); + + H5O_loc_reset(&obj_loc); + obj_loc.file = f; + obj_loc.addr = obj_addr; + + /* Open the object header where the layout message resides */ + if(H5O_open(&obj_loc) < 0) + H5E_THROW(H5E_CANTPROTECT, "unable to open object header") + + /* Read the layout message */ + if(NULL == H5O_msg_read(&obj_loc, H5O_LAYOUT_ID, &layout, dxpl_id)) + H5E_THROW(H5E_CANTPROTECT, "unable to read layout message") + + /* close the object header */ + if(H5O_close(&obj_loc) < 0) + H5E_THROW(H5E_CANTPROTECT, "unable to close object header") + + /* Create user data */ + udata.f = f; + udata.layout = &layout; + + /* Load the fixed array header */ + if(NULL == (hdr = (H5FA_hdr_t *)H5AC_protect(f, dxpl_id, H5AC_FARRAY_HDR, hdr_addr, cls, &udata, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to load fixed array header") + + /* Protect data block */ + if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, addr, hdr->cparam.nelmts, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)addr) + + /* Print opening message */ + HDfprintf(stream, "%*sFixed Array data Block...\n", indent, ""); + + + /* Print the values */ + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Array class ID:", hdr->cparam.cls->name); + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Address of Data Block:", dblock->addr); + HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth, "Data Block size:", dblock->size); + HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, + "Number of elements in Data Block:", hdr->cparam.nelmts); + HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, + "Number of pages in Data Block:", dblock->npages); + HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth, + "Number of elements per Data Block page:", dblock->dblk_page_nelmts); + + if(dblock->npages) { /* paging */ + size_t dblk_page_nelmts; /* # of elements in a data block page */ + haddr_t dblk_page_addr; /* Address of a data block page */ + size_t page_idx; /* Page index within data block */ + + HDfprintf(stream, "%*sPaging:\n", indent, ""); + + /* Iterate over the pages */ + dblk_page_addr = dblock->addr + H5FA_DBLOCK_PREFIX_SIZE(dblock); + dblk_page_nelmts = dblock->dblk_page_nelmts; + + /* Read and print each page's elements in the data block */ + for(page_idx = 0; page_idx < dblock->npages; page_idx++) { + if(!H5V_bit_get(dblock->dblk_page_init, page_idx)) { + HDfprintf(stream, "%*s%-*s %Hu %s\n", indent, "", fwidth, + "Page %Zu:", page_idx, "empty"); + + } /* end if */ + else { /* get the page */ + H5FA_dblk_page_t *dblk_page; /* Pointer to a data block page */ + hsize_t nelmts_left; /* Remaining elements in the last data block page */ + + /* Check for last page */ + if(((page_idx + 1) == dblock->npages) && (nelmts_left = hdr->cparam.nelmts % dblock->dblk_page_nelmts)) + dblk_page_nelmts = (size_t)nelmts_left; + + if(NULL == (dblk_page = H5FA__dblk_page_protect(hdr, dxpl_id, dblk_page_addr, dblk_page_nelmts, H5AC_READ))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr) + + HDfprintf(stream, "%*sElements in page %Zu:\n", indent, "", page_idx); + for(u = 0; u < dblk_page_nelmts; u++) { + /* Call the class's 'debug' callback */ + if((hdr->cparam.cls->debug)(stream, (indent + 3), MAX(0, (fwidth - 3)), (hsize_t)u, + ((uint8_t *)dblk_page->elmts) + (hdr->cparam.cls->nat_elmt_size * u)) < 0) + H5E_THROW(H5E_CANTGET, "can't get element for debugging") + } /* end for */ + if(H5FA__dblk_page_unprotect(dblk_page, dxpl_id, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block page") + + /* Advance to next page address */ + dblk_page_addr += dblock->dblk_page_size; + } /* paging */ + } /* end for npages */ + } /* end if */ + else { /* not paging */ + /* Print the elements in the data block */ + HDfprintf(stream, "%*sElements:\n", indent, ""); + for(u = 0; u < hdr->cparam.nelmts; u++) { + /* Call the class's 'debug' callback */ + if((hdr->cparam.cls->debug)(stream, (indent + 3), MAX(0, (fwidth - 3)), (hsize_t)u, + ((uint8_t *)dblock->elmts) + (hdr->cparam.cls->nat_elmt_size * u)) < 0) + H5E_THROW(H5E_CANTGET, "can't get element for debugging") + } /* end for */ + } /* end else */ + +CATCH + if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block") + if(hdr && H5AC_unprotect(f, dxpl_id, H5AC_FARRAY_HDR, hdr_addr, hdr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") + +END_FUNC(PKG) /* end H5FA__dblock_debug() */ + diff --git a/src/H5FAdblkpage.c b/src/H5FAdblkpage.c new file mode 100644 index 0000000..dde299f --- /dev/null +++ b/src/H5FAdblkpage.c @@ -0,0 +1,312 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FAdblkpage.c + * + * Purpose: Data block page routines for fixed array. + * + *------------------------------------------------------------------------- + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE + + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ +#include "H5FLprivate.h" /* Free Lists */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5FA_dblk_page_t struct */ +H5FL_DEFINE_STATIC(H5FA_dblk_page_t); + +/* Declare a free list to manage the page elements */ +H5FL_BLK_DEFINE(page_elmts); + + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblk_page_alloc + * + * Purpose: Allocate fixed array data block page + * + * Return: Non-NULL pointer to data block on success/NULL on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5FA_dblk_page_t *, NULL, NULL, +H5FA__dblk_page_alloc(H5FA_hdr_t *hdr, size_t nelmts)) + + /* Local variables */ + H5FA_dblk_page_t *dblk_page = NULL; /* Fixed array data block page */ + + /* Check arguments */ + HDassert(hdr); + + /* Allocate memory for the data block */ + if(NULL == (dblk_page = H5FL_CALLOC(H5FA_dblk_page_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block page") + + /* Share common array information */ + if(H5FA__hdr_incr(hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + dblk_page->hdr = hdr; + + /* Set non-zero internal fields */ + dblk_page->nelmts = nelmts; + + /* Allocate buffer for elements in data block page */ + if(NULL == (dblk_page->elmts = H5FL_BLK_MALLOC(page_elmts, nelmts * hdr->cparam.cls->nat_elmt_size))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block page element buffer") + + /* Set the return value */ + ret_value = dblk_page; + +CATCH + + if(!ret_value) + if(dblk_page && H5FA__dblk_page_dest(dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page") + +END_FUNC(PKG) /* end H5FA__dblk_page_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblk_page_create + * + * Purpose: Creates a new fixed array data block page in the file + * + * Return: Valid file address on success/HADDR_UNDEF on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__dblk_page_create(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t addr, size_t nelmts)) + + /* Local variables */ + H5FA_dblk_page_t *dblk_page = NULL; /* Fixed array data block page */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called, addr = %a\n", FUNC, addr); +#endif /* H5FA_DEBUG */ + + /* Sanity check */ + HDassert(hdr); + + /* Allocate the data block page */ + if(NULL == (dblk_page = H5FA__dblk_page_alloc(hdr, nelmts))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block page") + + /* Set info about data block page on disk */ + dblk_page->addr = addr; + dblk_page->size = H5FA_DBLK_PAGE_SIZE(dblk_page, nelmts); +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: dblk_page->size = %Zu\n", FUNC, dblk_page->size); +#endif /* H5FA_DEBUG */ + + /* Clear any elements in data block page to fill value */ + if((hdr->cparam.cls->fill)(dblk_page->elmts, nelmts) < 0) + H5E_THROW(H5E_CANTSET, "can't set fixed array data block page elements to class's fill value") + + /* Cache the new fixed array data block page */ + if(H5AC_set(hdr->f, dxpl_id, H5AC_FARRAY_DBLK_PAGE, dblk_page->addr, dblk_page, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTINSERT, "can't add fixed array data block page to cache") + +CATCH + if(ret_value < 0) + if(dblk_page) { + /* Destroy data block page */ + if(H5FA__dblk_page_dest(dblk_page) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block page") + } /* end if */ + +END_FUNC(PKG) /* end H5FA__dblk_page_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblk_page_protect + * + * Purpose: Convenience wrapper around protecting fixed array data + * block page + * + * Return: Non-NULL pointer to data block page on success/NULL on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5FA_dblk_page_t *, NULL, NULL, +H5FA__dblk_page_protect(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_page_addr, + size_t dblk_page_nelmts, H5AC_protect_t rw)) + + /* Local variables */ + H5FA_dblk_page_load_ud_t load_ud; /* Information needed for loading data block page */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* Sanity check */ + HDassert(hdr); + HDassert(H5F_addr_defined(dblk_page_addr)); + + /* Set up user data */ + load_ud.nelmts = dblk_page_nelmts; + + /* Protect the data block page */ + if(NULL == (ret_value = (H5FA_dblk_page_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_FARRAY_DBLK_PAGE, dblk_page_addr, &load_ud, hdr, rw))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block page, address = %llu", (unsigned long long)dblk_page_addr) + +CATCH + +END_FUNC(PKG) /* end H5FA__dblk_page_protect() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblk_page_unprotect + * + * Purpose: Convenience wrapper around unprotecting fixed array + * data block page + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__dblk_page_unprotect(H5FA_dblk_page_t *dblk_page, hid_t dxpl_id, + unsigned cache_flags)) + + /* Local variables */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* Sanity check */ + HDassert(dblk_page); + + /* Unprotect the data block page */ + if(H5AC_unprotect(dblk_page->hdr->f, dxpl_id, H5AC_FARRAY_DBLK_PAGE, dblk_page->addr, dblk_page, cache_flags) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect fixed array data block page, address = %llu", (unsigned long long)dblk_page->addr) + +CATCH + +END_FUNC(PKG) /* end H5FA__dblk_page_unprotect() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblk_page_dest + * + * Purpose: Destroys a fixed array data block page in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__dblk_page_dest(H5FA_dblk_page_t *dblk_page)) + + /* Sanity check */ + HDassert(dblk_page); + + /* Check if header field has been initialized */ + if(dblk_page->hdr) { + /* Check if buffer for data block page elements has been initialized */ + if(dblk_page->elmts) { + /* Free buffer for data block page elements */ + (void) H5FL_BLK_FREE(page_elmts, dblk_page->elmts); + dblk_page->elmts = NULL; + } /* end if */ + + /* Decrement reference count on shared info */ + if(H5FA__hdr_decr(dblk_page->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + dblk_page->hdr = NULL; + } /* end if */ + + /* Free the data block page itself */ + (void)H5FL_FREE(H5FA_dblk_page_t, dblk_page); + +CATCH + +END_FUNC(PKG) /* end H5FA__dblk_page_dest() */ + diff --git a/src/H5FAdblock.c b/src/H5FAdblock.c new file mode 100644 index 0000000..f564fee --- /dev/null +++ b/src/H5FAdblock.c @@ -0,0 +1,442 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FAdblock.c + * + * Purpose: Data block routines for fixed arrays. + * + *------------------------------------------------------------------------- + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE + + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5MFprivate.h" /* File memory management */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5FA_dblock_t struct */ +H5FL_DEFINE_STATIC(H5FA_dblock_t); + +/* Declare a free list to manage the chunk elements */ +H5FL_BLK_DEFINE(chunk_elmts); + +/* Declare a free list to manage blocks of 'page init' bitmasks */ +H5FL_BLK_DEFINE(fa_page_init); + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblock_alloc + * + * Purpose: Allocate fixed array data block + * + * Return: Non-NULL pointer to data block on success/NULL on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5FA_dblock_t *, NULL, NULL, +H5FA__dblock_alloc(H5FA_hdr_t *hdr, hsize_t nelmts)) + + /* Local variables */ + H5FA_dblock_t *dblock = NULL; /* fixed array data block */ + + /* Check arguments */ + HDassert(hdr); + HDassert(nelmts > 0); + + /* Allocate memory for the data block */ + if(NULL == (dblock = H5FL_CALLOC(H5FA_dblock_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block") + + /* Share common array information */ + if(H5FA__hdr_incr(hdr) < 0) + H5E_THROW(H5E_CANTINC, "can't increment reference count on shared array header") + dblock->hdr = hdr; + + /* Set non-zero internal fields */ + dblock->dblk_page_nelmts = (size_t)1 << hdr->cparam.max_dblk_page_nelmts_bits; + + /* Check if this data block should be paged */ + if(nelmts > dblock->dblk_page_nelmts) { + /* Compute number of pages */ + hsize_t npages = ((nelmts + dblock->dblk_page_nelmts) - 1) / dblock->dblk_page_nelmts; + + /* Safely assign the number of pages */ + H5_ASSIGN_OVERFLOW(/* To: */ dblock->npages, /* From: */ npages, /* From: */ hsize_t, /* To: */ size_t); + + /* Sanity check that we have at least 1 page */ + HDassert(dblock->npages > 0); + + /* Compute size of 'page init' flag array, in bytes */ + dblock->dblk_page_init_size = (dblock->npages + 7) / 8; + HDassert(dblock->dblk_page_init_size > 0); + + /* Allocate space for 'page init' flags */ + if(NULL == (dblock->dblk_page_init = H5FL_BLK_CALLOC(fa_page_init, dblock->dblk_page_init_size))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for page init bitmask") + + /* Compute data block page size */ + dblock->dblk_page_size = (dblock->dblk_page_nelmts * hdr->cparam.raw_elmt_size) + H5FA_SIZEOF_CHKSUM; + + /* Compute the # of elements on last page */ + if(0 == nelmts % dblock->dblk_page_nelmts) + dblock->last_page_nelmts = dblock->dblk_page_nelmts; + else + dblock->last_page_nelmts = (size_t)(nelmts % dblock->dblk_page_nelmts); + } /* end if */ + else { + hsize_t dblk_size = hdr->cparam.nelmts * hdr->cparam.cls->nat_elmt_size; + + /* Allocate buffer for elements in data block */ + H5_CHECK_OVERFLOW(dblk_size, /* From: */hsize_t, /* To: */size_t); + if(NULL == (dblock->elmts = H5FL_BLK_MALLOC(chunk_elmts, (size_t)dblk_size))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for data block element buffer") + } /* end else */ + + /* Set the return value */ + ret_value = dblock; + +CATCH + + if(!ret_value) + if(dblock && H5FA__dblock_dest(hdr->f, dblock) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block") + +END_FUNC(PKG) /* end H5FA__dblock_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblock_create + * + * Purpose: Creates a fixed array data block in the file + * + * Return: Valid file address on success/HADDR_UNDEF on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +haddr_t, HADDR_UNDEF, HADDR_UNDEF, +H5FA__dblock_create(H5FA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty, + hsize_t nelmts)) + + /* Local variables */ + H5FA_dblock_t *dblock = NULL; /* fixed array data block */ + haddr_t dblock_addr; /* fixed array data block address */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called, hdr->stats.nelmts = %Zu, nelmts = %Zu\n", FUNC, hdr->stats.nelmts, nelmts); +#endif /* H5FA_DEBUG */ + + /* Sanity check */ + HDassert(hdr); + HDassert(hdr_dirty); + HDassert(nelmts > 0); + + /* Allocate the data block */ + if(NULL == (dblock = H5FA__dblock_alloc(hdr, nelmts))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for fixed array data block") + + /* Set size of data block on disk */ + hdr->stats.dblk_size = dblock->size = H5FA_DBLOCK_SIZE(dblock); +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: dblock->size = %Zu\n", FUNC, dblock->size); +#endif /* H5FA_DEBUG */ + + + /* Allocate space for the data block on disk */ + if(HADDR_UNDEF == (dblock_addr = H5MF_alloc(hdr->f, H5FD_MEM_FARRAY_DBLOCK, dxpl_id, (hsize_t)dblock->size))) + H5E_THROW(H5E_CANTALLOC, "file allocation failed for fixed array data block") + dblock->addr = dblock_addr; + + /* Don't initialize elements if paged */ + if(!dblock->npages) + /* Clear any elements in data block to fill value */ + if((hdr->cparam.cls->fill)(dblock->elmts, (size_t)hdr->cparam.nelmts) < 0) + H5E_THROW(H5E_CANTSET, "can't set fixed array data block elements to class's fill value") + + /* Cache the new fixed array data block */ + if(H5AC_set(hdr->f, dxpl_id, H5AC_FARRAY_DBLOCK, dblock_addr, dblock, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTINSERT, "can't add fixed array data block to cache") + + /* Mark the header dirty (for updating statistics) */ + *hdr_dirty = TRUE; + + /* Set address of data block to return */ + ret_value = dblock_addr; + +CATCH + + if(!H5F_addr_defined(ret_value)) + if(dblock) { + /* Release data block's disk space */ + if(H5F_addr_defined(dblock->addr) && H5MF_xfree(hdr->f, H5FD_MEM_FARRAY_DBLOCK, dxpl_id, dblock->addr, (hsize_t)dblock->size) < 0) + H5E_THROW(H5E_CANTFREE, "unable to release fixed array data block") + + /* Destroy data block */ + if(H5FA__dblock_dest(hdr->f, dblock) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array data block") + } /* end if */ + +END_FUNC(PKG) /* end H5FA__dblock_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblock_protect + * + * Purpose: Convenience wrapper around protecting fixed array data block + * + * Return: Non-NULL pointer to data block on success/NULL on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5FA_dblock_t *, NULL, NULL, +H5FA__dblock_protect(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_addr, + hsize_t dblk_nelmts, H5AC_protect_t rw)) + + /* Local variables */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* Sanity check */ + HDassert(hdr); + HDassert(H5F_addr_defined(dblk_addr)); + HDassert(dblk_nelmts); + + /* Protect the data block */ + if(NULL == (ret_value = (H5FA_dblock_t *)H5AC_protect(hdr->f, dxpl_id, H5AC_FARRAY_DBLOCK, dblk_addr, &dblk_nelmts, hdr, rw))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)dblk_addr) + +CATCH + +END_FUNC(PKG) /* end H5FA__dblock_protect() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblock_unprotect + * + * Purpose: Convenience wrapper around unprotecting fixed array data block + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__dblock_unprotect(H5FA_dblock_t *dblock, hid_t dxpl_id, unsigned cache_flags)) + + /* Local variables */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* Sanity check */ + HDassert(dblock); + + /* Unprotect the data block */ + if(H5AC_unprotect(dblock->hdr->f, dxpl_id, H5AC_FARRAY_DBLOCK, dblock->addr, dblock, cache_flags) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to unprotect fixed array data block, address = %llu", (unsigned long long)dblock->addr) + +CATCH + +END_FUNC(PKG) /* end H5FA__dblock_unprotect() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblock_delete + * + * Purpose: Delete a data block + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__dblock_delete(H5FA_hdr_t *hdr, hid_t dxpl_id, haddr_t dblk_addr, + hsize_t dblk_nelmts)) + + /* Local variables */ + H5FA_dblock_t *dblock = NULL; /* Pointer to data block */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* Sanity check */ + HDassert(hdr); + HDassert(H5F_addr_defined(dblk_addr)); + HDassert(dblk_nelmts > 0); + + /* Protect data block */ + if(NULL == (dblock = H5FA__dblock_protect(hdr, dxpl_id, dblk_addr, dblk_nelmts, H5AC_WRITE))) + H5E_THROW(H5E_CANTPROTECT, "unable to protect fixed array data block, address = %llu", (unsigned long long)dblk_addr) + + /* Check if data block is paged */ + if(dblock->npages) { + haddr_t dblk_page_addr; /* Address of each data block page */ + size_t u; /* Local index variable */ + + /* Set up initial state */ + dblk_page_addr = dblk_addr + H5FA_DBLOCK_PREFIX_SIZE(dblock); + + /* Iterate over pages in data block */ + for(u = 0; u < dblock->npages; u++) { +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Expunging data block page from cache\n", FUNC); +#endif /* H5FA_DEBUG */ + /* Evict the data block page from the metadata cache */ + /* (OK to call if it doesn't exist in the cache) */ + if(H5AC_expunge_entry(hdr->f, dxpl_id, H5AC_FARRAY_DBLK_PAGE, dblk_page_addr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTEXPUNGE, "unable to remove array data block page from metadata cache") +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Done expunging data block page from cache\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* Advance to next page address */ + dblk_page_addr += dblock->dblk_page_size; + } /* end for */ + } /* end if */ + +CATCH + + /* Finished deleting data block in metadata cache */ + if(dblock && H5FA__dblock_unprotect(dblock, dxpl_id, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array data block") + +END_FUNC(PKG) /* end H5FA__dblock_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__dblock_dest + * + * Purpose: Destroys a fixed array data block in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__dblock_dest(H5F_t UNUSED *f, H5FA_dblock_t *dblock)) + + /* Sanity check */ + HDassert(dblock); + + /* Check if shared header field has been initialized */ + if(dblock->hdr) { + /* Check if we've got elements in the data block */ + if(dblock->elmts && !dblock->npages) { + /* Free buffer for data block elements */ + HDassert(dblock->hdr->cparam.nelmts > 0); + (void) H5FL_BLK_FREE(chunk_elmts, dblock->elmts); + dblock->elmts = NULL; + } /* end if */ + + /* Check if data block is paged */ + if(dblock->npages) { + /* Free buffer for 'page init' bitmask, if there is one */ + HDassert(dblock->dblk_page_init_size > 0); + if(dblock->dblk_page_init) + dblock->dblk_page_init = H5FL_BLK_FREE(fa_page_init, dblock->dblk_page_init); + } /* end if */ + + /* Decrement reference count on shared info */ + if(H5FA__hdr_decr(dblock->hdr) < 0) + H5E_THROW(H5E_CANTDEC, "can't decrement reference count on shared array header") + dblock->hdr = NULL; + } /* end if */ + + /* Free the data block itself */ + (void)H5FL_FREE(H5FA_dblock_t, dblock); + +CATCH + +END_FUNC(PKG) /* end H5FA__dblock_dest() */ + diff --git a/src/H5FAhdr.c b/src/H5FAhdr.c new file mode 100644 index 0000000..150742d --- /dev/null +++ b/src/H5FAhdr.c @@ -0,0 +1,454 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FAhdr.c + * + * Purpose: Array header routines for Fixed Array. + * + *------------------------------------------------------------------------- + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE + + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ +#include "H5MFprivate.h" /* File memory management */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5FA_hdr_t struct */ +H5FL_DEFINE_STATIC(H5FA_hdr_t); + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_alloc + * + * Purpose: Allocate shared Fixed Array header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +H5FA_hdr_t *, NULL, NULL, +H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *udata)) + + /* Local variables */ + H5FA_hdr_t *hdr = NULL; /* Shared Fixed Array header */ + + /* Check arguments */ + HDassert(f); + HDassert(cls); + + /* Allocate space for the shared information */ + if(NULL == (hdr = H5FL_CALLOC(H5FA_hdr_t))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for Fixed Array shared header") + + /* Set non-zero internal fields */ + hdr->addr = HADDR_UNDEF; + + /* Set the internal parameters for the array */ + hdr->f = f; + hdr->sizeof_addr = H5F_SIZEOF_ADDR(f); + hdr->sizeof_size = H5F_SIZEOF_SIZE(f); + + /* Set the class of the array */ + hdr->cparam.cls = cls; + + /* Create the callback context */ + if(NULL == (hdr->cb_ctx = (*cls->crt_context)(udata))) + H5E_THROW(H5E_CANTCREATE, "unable to create fixed array client callback context") + + /* Set the return value */ + ret_value = hdr; + +CATCH + if(!ret_value) + if(hdr && H5FA__hdr_dest(hdr) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy fixed array header") + +END_FUNC(PKG) /* end H5FA__hdr_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_create + * + * Purpose: Creates a new Fixed Array header in the file + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +haddr_t, HADDR_UNDEF, HADDR_UNDEF, +H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, + void *ctx_udata)) + + /* Local variables */ + H5FA_hdr_t *hdr = NULL; /* Fixed array header */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* Check arguments */ + HDassert(f); + HDassert(cparam); + +#ifndef NDEBUG +{ + /* Check for valid parameters */ + if(cparam->raw_elmt_size == 0) + H5E_THROW(H5E_BADVALUE, "element size must be greater than zero") +} +#endif /* NDEBUG */ + + /* Allocate space for the shared information */ + if(NULL == (hdr = H5FA__hdr_alloc(f, cparam->cls, ctx_udata))) + H5E_THROW(H5E_CANTALLOC, "memory allocation failed for Fixed Array shared header") + + hdr->dblk_addr = HADDR_UNDEF; + + /* Set the creation parameters for the array */ + HDmemcpy(&hdr->cparam, cparam, sizeof(hdr->cparam)); + + /* Set size of header on disk (locally and in statistics) */ + hdr->stats.hdr_size = hdr->size = H5FA_HEADER_SIZE(hdr); + + /* Set number of elements for Fixed Array in statistics */ + hdr->stats.nelmts = hdr->cparam.nelmts; + + /* Allocate space for the header on disk */ + if(HADDR_UNDEF == (hdr->addr = H5MF_alloc(f, H5FD_MEM_FARRAY_HDR, dxpl_id, (hsize_t)hdr->size))) + H5E_THROW(H5E_CANTALLOC, "file allocation failed for Fixed Array header") + + /* Cache the new Fixed Array header */ + if(H5AC_set(f, dxpl_id, H5AC_FARRAY_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTINSERT, "can't add fixed array header to cache") + + /* Set address of array header to return */ + ret_value = hdr->addr; + +CATCH + if(!H5F_addr_defined(ret_value)) + if(hdr) { + /* Release header's disk space */ + if(H5F_addr_defined(hdr->addr) && H5MF_xfree(f, H5FD_MEM_FARRAY_HDR, dxpl_id, hdr->addr, (hsize_t)hdr->size) < 0) + H5E_THROW(H5E_CANTFREE, "unable to free Fixed Array header") + + /* Destroy header */ + if(H5FA__hdr_dest(hdr) < 0) + H5E_THROW(H5E_CANTFREE, "unable to destroy Fixed Array header") + } /* end if */ + +END_FUNC(PKG) /* end H5FA__hdr_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_incr + * + * Purpose: Increment component reference count on shared array header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_incr(H5FA_hdr_t *hdr)) + + /* Sanity check */ + HDassert(hdr); + + /* Mark header as un-evictable when something is depending on it */ + if(hdr->rc == 0) + if(H5AC_pin_protected_entry(hdr->f, hdr) < 0) + H5E_THROW(H5E_CANTPIN, "unable to pin fixed array header") + + /* Increment reference count on shared header */ + hdr->rc++; + +CATCH + +END_FUNC(PKG) /* end H5FA__hdr_incr() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_decr + * + * Purpose: Decrement component reference count on shared array header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_decr(H5FA_hdr_t *hdr)) + + /* Sanity check */ + HDassert(hdr); + HDassert(hdr->rc); + + /* Decrement reference count on shared header */ + hdr->rc--; + + /* Mark header as evictable again when nothing depend on it */ + if(hdr->rc == 0) { + HDassert(hdr->file_rc == 0); + if(H5AC_unpin_entry(hdr->f, hdr) < 0) + H5E_THROW(H5E_CANTUNPIN, "unable to unpin fixed array header") + } /* end if */ + +CATCH + +END_FUNC(PKG) /* end H5FA__hdr_decr() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_fuse_incr + * + * Purpose: Increment file reference count on shared array header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, NOERR, +herr_t, SUCCEED, -, +H5FA__hdr_fuse_incr(H5FA_hdr_t *hdr)) + + /* Sanity check */ + HDassert(hdr); + + /* Increment file reference count on shared header */ + hdr->file_rc++; + +END_FUNC(PKG) /* end H5FA__hdr_fuse_incr() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_fuse_decr + * + * Purpose: Decrement file reference count on shared array header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, NOERR, +size_t, 0, -, +H5FA__hdr_fuse_decr(H5FA_hdr_t *hdr)) + + /* Sanity check */ + HDassert(hdr); + HDassert(hdr->file_rc); + + /* Decrement file reference count on shared header */ + hdr->file_rc--; + + /* Set return value */ + ret_value = hdr->file_rc; + +END_FUNC(PKG) /* end H5FA__hdr_fuse_decr() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_modified + * + * Purpose: Mark a fixed array as modified + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_modified(H5FA_hdr_t *hdr)) + + /* Sanity check */ + HDassert(hdr); + HDassert(hdr->f); + + /* Mark header as dirty in cache */ + if(H5AC_mark_pinned_or_protected_entry_dirty(hdr->f, hdr) < 0) + H5E_THROW(H5E_CANTMARKDIRTY, "unable to mark fixed array header as dirty") + +CATCH + +END_FUNC(PKG) /* end H5FA__hdr_modified() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_delete + * + * Purpose: Delete a fixed array, starting with the header + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_delete(H5FA_hdr_t *hdr, hid_t dxpl_id)) + + /* Sanity check */ + HDassert(hdr); + HDassert(!hdr->file_rc); + +#ifndef NDEBUG +{ + unsigned hdr_status = 0; /* Array header's status in the metadata cache */ + + /* Check the array header's status in the metadata cache */ + if(H5AC_get_entry_status(hdr->f, hdr->addr, &hdr_status) < 0) + H5E_THROW(H5E_CANTGET, "unable to check metadata cache status for array header") + + /* Sanity checks on array header */ + HDassert(hdr_status & H5AC_ES__IN_CACHE); + HDassert(hdr_status & H5AC_ES__IS_PROTECTED); +} /* end block */ +#endif /* NDEBUG */ + + /* Check for Fixed Array Data block */ + if(H5F_addr_defined(hdr->dblk_addr)) { +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: hdr->dblk_addr = %a\n", FUNC, hdr->dblk_addr); +#endif /* H5FA_DEBUG */ + + /* Delete Fixed Array Data block */ + if(H5FA__dblock_delete(hdr, dxpl_id, hdr->dblk_addr, hdr->cparam.nelmts) < 0) + H5E_THROW(H5E_CANTDELETE, "unable to delete fixed array data block") + } /* end if */ + + /* Finished deleting header */ + if(H5AC_unprotect(hdr->f, dxpl_id, H5AC_FARRAY_HDR, hdr->addr, hdr, H5AC__DIRTIED_FLAG | H5AC__DELETED_FLAG | H5AC__FREE_FILE_SPACE_FLAG) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") + hdr = NULL; + +CATCH + + /* Unprotect the header, if an error occurred */ + if(hdr && H5AC_unprotect(hdr->f, dxpl_id, H5AC_FARRAY_HDR, hdr->addr, hdr, H5AC__NO_FLAGS_SET) < 0) + H5E_THROW(H5E_CANTUNPROTECT, "unable to release fixed array header") + +END_FUNC(PKG) /* end H5FA__hdr_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__hdr_dest + * + * Purpose: Destroys a fixed array header in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PKG, ERR, +herr_t, SUCCEED, FAIL, +H5FA__hdr_dest(H5FA_hdr_t *hdr)) + + /* Check arguments */ + HDassert(hdr); + HDassert(hdr->rc == 0); + + /* Destroy the callback context */ + if((*hdr->cparam.cls->dst_context)(hdr->cb_ctx) < 0) + H5E_THROW(H5E_CANTRELEASE, "unable to destroy fixed array client callback context") + hdr->cb_ctx = NULL; + + /* Free the shared info itself */ + hdr = H5FL_FREE(H5FA_hdr_t, hdr); + +CATCH + +END_FUNC(PKG) /* end H5FA__hdr_dest() */ + diff --git a/src/H5FApkg.h b/src/H5FApkg.h new file mode 100644 index 0000000..16d2518 --- /dev/null +++ b/src/H5FApkg.h @@ -0,0 +1,286 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: + * + * Purpose: This file contains declarations which are visible only within + * the H5FA package. Source files outside the H5FA package should + * include H5FAprivate.h instead. + */ +#if !(defined(H5FA_PACKAGE) | defined(H5FA_MODULE)) +#error "Do not include this file outside the H5FA package!" +#endif + +#ifndef _H5FApkg_H +#define _H5FApkg_H + +/* Get package's private header */ +#include "H5FAprivate.h" + +/* Other private headers needed by this file */ +#include "H5ACprivate.h" /* Metadata cache */ +#include "H5FLprivate.h" /* Free Lists */ + + +/**************************/ +/* Package Private Macros */ +/**************************/ + +/* Define this to display debugging information for the Fixed Array layer */ +/* #define H5FA_DEBUG */ + + +/* If this package header is being included in one of the H5FA modules, define + * the proper control macros for the generic FUNC_ENTER/LEAVE and error + * reporting macros. + */ +#ifdef H5FA_MODULE +#define H5_MY_PKG H5FA +#define H5_MY_PKG_ERR H5E_FARRAY +#define H5_MY_PKG_INIT NO +#endif /* H5FA_MODULE */ + +/* Fill value for fixed array test class */ +#ifdef H5FA_TESTING +#define H5FA_TEST_FILL ((uint64_t)ULLONG_MAX) +#endif /* H5FA_TESTING */ + +/* Size of checksum information (on disk) */ +#define H5FA_SIZEOF_CHKSUM 4 + +/* "Standard" size of prefix information for fixed array metadata */ +#define H5FA_METADATA_PREFIX_SIZE(c) ( \ + H5_SIZEOF_MAGIC /* Signature */ \ + + 1 /* Version */ \ + + ((c) ? H5FA_SIZEOF_CHKSUM : 0) /* Metadata checksum */ \ + ) + +/* Size of the Fixed Array header on disk */ +#define H5FA_HEADER_SIZE(h) ( \ + /* General metadata fields */ \ + H5FA_METADATA_PREFIX_SIZE(TRUE) \ + \ + /* General array information */ \ + + 1 /* Array type */ \ + + 1 /* Element Size */ \ + + 1 /* Log2(Max. # of elements in data block page) - i.e. # of bits needed to store max. # of elements in data block page */ \ + \ + /* Fixed Array statistics fields */ \ + + (h)->sizeof_size /* # of elements in the fixed array */ \ + \ + /* Fixed Array Header specific fields */ \ + + (h)->sizeof_addr /* File address of Fixed Array data block */ \ + ) + +/* Size of the Fixed Array data block prefix on disk */ +#define H5FA_DBLOCK_PREFIX_SIZE(d) ( \ + /* General metadata fields */ \ + H5FA_METADATA_PREFIX_SIZE(TRUE) \ + \ + /* Sanity-checking fields */ \ + + (d)->hdr->sizeof_addr /* File address of Fixed Array header owning the data block */ \ + + 1 /* Array type */ \ + \ + /* Fixed Array Data Block specific fields */ \ + + (d)->dblk_page_init_size /* Fixed array data block 'page init' bitmasks (can be 0 if no pages) */ \ + ) + +/* Size of the Fixed Array data block on disk */ +#define H5FA_DBLOCK_SIZE(d) ( \ + /* Data block prefix size */ \ + H5FA_DBLOCK_PREFIX_SIZE(d) \ + \ + /* Fixed Array Elements|Pages of Elements*/ \ + + ((d)->hdr->cparam.nelmts * (size_t)(d)->hdr->cparam.raw_elmt_size) \ + + ((d)->npages * H5FA_SIZEOF_CHKSUM) /* Checksum */ \ + ) + +/* Size of the Fixed Array data block page on disk */ +#define H5FA_DBLK_PAGE_SIZE(d, nelmts) ( \ + /* Fixed Array Data Block Page */ \ + + (nelmts * (size_t)(d)->hdr->cparam.raw_elmt_size) /* Elements in data block page */ \ + + H5FA_SIZEOF_CHKSUM /* Checksum for each page */ \ + ) + +/****************************/ +/* Package Private Typedefs */ +/****************************/ + +/* The Fixed Array header information */ +typedef struct H5FA_hdr_t { + /* Information for H5AC cache functions, _must_ be first field in structure */ + H5AC_info_t cache_info; + + /* Fixed array configuration/creation parameters (stored in header) */ + H5FA_create_t cparam; /* Creation parameters for Fixed Array */ + + /* Fixed Array data block information (stored in header) */ + haddr_t dblk_addr; /* Address of Fixed Array Data block */ + + /* Statistics for Fixed Array (stored in header) */ + H5FA_stat_t stats; /* Statistcs for Fixed Array */ + + /* Computed/cached values (not stored in header) */ + size_t rc; /* Reference count of the header */ + haddr_t addr; /* Address of header in file */ + size_t size; /* Size of header in file */ + H5F_t *f; /* Pointer to file for fixed array */ + size_t file_rc; /* Reference count of files using array header */ + hbool_t pending_delete; /* Array is pending deletion */ + size_t sizeof_addr; /* Size of file addresses */ + size_t sizeof_size; /* Size of file sizes */ + + /* Client information (not stored) */ + void *cb_ctx; /* Callback context */ +} H5FA_hdr_t; + +/* The fixed array data block information */ +typedef struct H5FA_dblock_t { + /* Information for H5AC cache functions, _must_ be first field in structure */ + H5AC_info_t cache_info; + + /* Fixed array information (stored) */ + uint8_t *dblk_page_init;/* Bitmap of whether a data block page is initialized */ + void *elmts; /* Buffer for elements stored in data block */ + + /* Internal array information (not stored) */ + H5FA_hdr_t *hdr; /* Shared array header info */ + + /* Computed/cached values (not stored) */ + haddr_t addr; /* Address of this data block on disk */ + hsize_t size; /* Size of data block on disk */ + size_t npages; /* Nummber of pages in data block (zero if not paged) */ + size_t last_page_nelmts; /* Nummber of elements in last page, if paged */ + + /* Fixed Array data block information (not stored) */ + size_t dblk_page_nelmts; /* # of elements per data block page */ + size_t dblk_page_size; /* Size of a data block page */ + size_t dblk_page_init_size; /* Size of 'page init' bitmask */ +} H5FA_dblock_t; + +/* The fixed array data block page information */ +typedef struct H5FA_dbk_page_t { + /* Information for H5AC cache functions, _must_ be first field in structure */ + H5AC_info_t cache_info; + + /* Fixed array information (stored) */ + void *elmts; /* Buffer for elements stored in data block page */ + + /* Internal array information (not stored) */ + H5FA_hdr_t *hdr; /* Shared array header info */ + + /* Computed/cached values (not stored) */ + haddr_t addr; /* Address of this data block page on disk */ + size_t size; /* Size of data block page on disk */ + size_t nelmts; /* Number of elements in data block page */ +} H5FA_dblk_page_t; + +/* Fixed array */ +struct H5FA_t { + H5FA_hdr_t *hdr; /* Pointer to internal fixed array header info */ + H5F_t *f; /* Pointer to file for fixed array */ +}; + + +/* Metadata cache callback user data types */ + +/* Info needed for loading data block page */ +typedef struct H5FA_dblk_page_load_ud_t { + size_t nelmts; /* Number of elements in data block page */ +} H5FA_dblk_page_load_ud_t; + + + +/*****************************/ +/* Package Private Variables */ +/*****************************/ + +/* H5FA header inherits cache-like properties from H5AC */ +H5_DLLVAR const H5AC_class_t H5AC_FARRAY_HDR[1]; + +/* H5FA data block inherits cache-like properties from H5AC */ +H5_DLLVAR const H5AC_class_t H5AC_FARRAY_DBLOCK[1]; + +/* H5FA data block page inherits cache-like properties from H5AC */ +H5_DLLVAR const H5AC_class_t H5AC_FARRAY_DBLK_PAGE[1]; + + +/* The Fixed Array class for dataset chunks w/o filters*/ +H5_DLLVAR const H5FA_class_t H5FA_CLS_CHUNK[1]; + +/* The Fixed Array class for dataset chunks w/ filters*/ +H5_DLLVAR const H5FA_class_t H5FA_CLS_FILT_CHUNK[1]; + +/* Internal fixed array testing class */ +#ifdef H5FA_TESTING +H5_DLLVAR const H5FA_class_t H5FA_CLS_TEST[1]; +#endif /* H5FA_TESTING */ + + +/******************************/ +/* Package Private Prototypes */ +/******************************/ + +/* Header routines */ +H5_DLL H5FA_hdr_t *H5FA__hdr_alloc(H5F_t *f, const H5FA_class_t *cls, void *ctx_udata); +H5_DLL haddr_t H5FA__hdr_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, void *ctx_udata); +H5_DLL void *H5FA__hdr_alloc_elmts(H5FA_hdr_t *hdr, size_t nelmts); +H5_DLL herr_t H5FA__hdr_free_elmts(H5FA_hdr_t *hdr, size_t nelmts, void *elmts); +H5_DLL herr_t H5FA__hdr_incr(H5FA_hdr_t *hdr); +H5_DLL herr_t H5FA__hdr_decr(H5FA_hdr_t *hdr); +H5_DLL herr_t H5FA__hdr_fuse_incr(H5FA_hdr_t *hdr); +H5_DLL size_t H5FA__hdr_fuse_decr(H5FA_hdr_t *hdr); +H5_DLL herr_t H5FA__hdr_modified(H5FA_hdr_t *hdr); +H5_DLL herr_t H5FA__hdr_delete(H5FA_hdr_t *hdr, hid_t dxpl_id); +H5_DLL herr_t H5FA__hdr_dest(H5FA_hdr_t *hdr); + +/* Data block routines */ +H5_DLL H5FA_dblock_t *H5FA__dblock_alloc(H5FA_hdr_t *hdr, hsize_t nelmts); +H5_DLL haddr_t H5FA__dblock_create(H5FA_hdr_t *hdr, hid_t dxpl_id, hbool_t *hdr_dirty, hsize_t nelmts); +H5_DLL unsigned H5FA__dblock_sblk_idx(const H5FA_hdr_t *hdr, hsize_t idx); +H5_DLL H5FA_dblock_t *H5FA__dblock_protect(H5FA_hdr_t *hdr, hid_t dxpl_id, + haddr_t dblk_addr, hsize_t dblk_nelmts, H5AC_protect_t rw); +H5_DLL herr_t H5FA__dblock_unprotect(H5FA_dblock_t *dblock, hid_t dxpl_id, + unsigned cache_flags); +H5_DLL herr_t H5FA__dblock_delete(H5FA_hdr_t *hdr, hid_t dxpl_id, + haddr_t dblk_addr, hsize_t dblk_nelmts); +H5_DLL herr_t H5FA__dblock_dest(H5F_t *f, H5FA_dblock_t *dblock); + +/* Data block page routines */ +H5_DLL herr_t H5FA__dblk_page_create(H5FA_hdr_t *hdr, hid_t dxpl_id, + haddr_t addr, size_t nelmts); +H5_DLL H5FA_dblk_page_t *H5FA__dblk_page_alloc(H5FA_hdr_t *hdr, size_t nelmts); +H5_DLL H5FA_dblk_page_t *H5FA__dblk_page_protect(H5FA_hdr_t *hdr, hid_t dxpl_id, + haddr_t dblk_page_addr, size_t dblk_page_nelmts, H5AC_protect_t rw); +H5_DLL herr_t H5FA__dblk_page_unprotect(H5FA_dblk_page_t *dblk_page, + hid_t dxpl_id, unsigned cache_flags); +H5_DLL herr_t H5FA__dblk_page_dest(H5FA_dblk_page_t *dblk_page); + +/* Debugging routines for dumping file structures */ +H5_DLL herr_t H5FA__hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, + FILE *stream, int indent, int fwidth, const H5FA_class_t *cls, haddr_t obj_addr); +H5_DLL herr_t H5FA__dblock_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, + FILE *stream, int indent, int fwidth, const H5FA_class_t *cls, + haddr_t hdr_addr, haddr_t obj_addr); + +/* Testing routines */ +#ifdef H5FA_TESTING +H5_DLL herr_t H5FA_get_cparam_test(const H5FA_t *ea, H5FA_create_t *cparam); +H5_DLL int H5FA_cmp_cparam_test(const H5FA_create_t *cparam1, const H5FA_create_t *cparam2); +#endif /* H5FA_TESTING */ + +#endif /* _H5FApkg_H */ + diff --git a/src/H5FAprivate.h b/src/H5FAprivate.h new file mode 100644 index 0000000..2450218 --- /dev/null +++ b/src/H5FAprivate.h @@ -0,0 +1,132 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FAprivate.h + * + * Purpose: Private header for library accessible Fixed + * Array routines. + * + *------------------------------------------------------------------------- + */ + +#ifndef _H5FAprivate_H +#define _H5FAprivate_H + +/* Include package's public header */ +#ifdef NOT_YET +#include "H5FApublic.h" +#endif /* NOT_YET */ + +/* Private headers needed by this file */ +#include "H5Fprivate.h" /* File access */ + + +/**************************/ +/* Library Private Macros */ +/**************************/ + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/* Fixed Array class IDs */ +typedef enum H5FA_cls_id_t { + H5FA_CLS_CHUNK_ID = 0, /* Fixed array is for indexing dataset chunks w/o filters */ + H5FA_CLS_FILT_CHUNK_ID, /* Fixed array is for indexing dataset chunks w/filters */ + + /* (keep these last) */ + H5FA_CLS_TEST_ID, /* Fixed array is for testing (do not use for actual data) */ + H5FA_NUM_CLS_ID /* Number of Fixed Array class IDs (must be last) */ +} H5FA_cls_id_t; + +/* + * Each type of element that can be stored in a Fixed Array has a + * variable of this type that contains class variables and methods. + */ +typedef struct H5FA_class_t { + H5FA_cls_id_t id; /* ID of Fixed Array class, as found in file */ + const char *name; /* Name of class (for debugging) */ + size_t nat_elmt_size; /* Size of native (memory) element */ + + /* Fixed array client callback methods */ + void *(*crt_context)(void *udata); /* Create context for other callbacks */ + herr_t (*dst_context)(void *ctx); /* Destroy context */ + herr_t (*fill)(void *nat_blk, size_t nelmts); /* Fill array of elements with encoded form of "missing element" value */ + herr_t (*encode)(void *raw, const void *elmt, size_t nelmts, void *ctx); /* Encode elements from native form to disk storage form */ + herr_t (*decode)(const void *raw, void *elmt, size_t nelmts, void *ctx); /* Decode elements from disk storage form to native form */ + herr_t (*debug)(FILE *stream, int indent, int fwidth, hsize_t idx, const void *elmt); /* Print an element for debugging */ +} H5FA_class_t; + +/* Fixed array creation parameters */ +typedef struct H5FA_create_t { + const H5FA_class_t *cls; /* Class of Fixed Array to create */ + uint8_t raw_elmt_size; /* Element size in file (in bytes) */ + uint8_t max_dblk_page_nelmts_bits; /* Log2(Max. # of elements in a data block page) - + i.e. # of bits needed to store max. # of elements + in a data block page */ + hsize_t nelmts; /* # of elements in array */ +} H5FA_create_t; + +/* Fixed array metadata statistics info */ +typedef struct H5FA_stat_t { + /* Non-stored (i.e. computed) fields */ + hsize_t hdr_size; /* Size of header */ + hsize_t dblk_size; /* Size of data block */ + + /* Stored fields */ + hsize_t nelmts; /* # of elements */ +} H5FA_stat_t; + +/* Fixed Array info (forward decl - defined in H5FApkg.h) */ +typedef struct H5FA_t H5FA_t; + +/* Define the operator callback function pointer for H5FA_iterate() */ +typedef int (*H5FA_operator_t)(hsize_t idx, const void *_elmt, void *_udata); + + +/*****************************/ +/* Library-private Variables */ +/*****************************/ + + +/***************************************/ +/* Library-private Function Prototypes */ +/***************************************/ + +/* General routines */ +H5_DLL H5FA_t *H5FA_create(H5F_t *f, hid_t dxpl_id, const H5FA_create_t *cparam, + void *ctx_udata); +H5_DLL H5FA_t *H5FA_open(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr, const H5FA_class_t *cls, + void *ctx_udata); +H5_DLL herr_t H5FA_get_nelmts(const H5FA_t *ea, hsize_t *nelmts); +H5_DLL herr_t H5FA_get_addr(const H5FA_t *ea, haddr_t *addr); +H5_DLL herr_t H5FA_set(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, const void *elmt); +H5_DLL herr_t H5FA_get(const H5FA_t *ea, hid_t dxpl_id, hsize_t idx, void *elmt); +H5_DLL herr_t H5FA_close(H5FA_t *ea, hid_t dxpl_id); +H5_DLL herr_t H5FA_delete(H5F_t *f, hid_t dxpl_id, haddr_t ea_addr); +H5_DLL herr_t H5FA_iterate(H5FA_t *fa, hid_t dxpl_id, H5FA_operator_t op, void *udata); + +/* Statistics routines */ +H5_DLL herr_t H5FA_get_stats(const H5FA_t *ea, H5FA_stat_t *stats); + +/* Debugging routines */ +#ifdef H5FA_DEBUGGING +#endif /* H5FA_DEBUGGING */ + +#endif /* _H5FAprivate_H */ + diff --git a/src/H5FAstat.c b/src/H5FAstat.c new file mode 100644 index 0000000..bed6c6e --- /dev/null +++ b/src/H5FAstat.c @@ -0,0 +1,113 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5FAstat.c + * + * Purpose: Fixed array metadata statistics functions. + * + *------------------------------------------------------------------------- + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE + + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ + + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + + +/*********************/ +/* Package Variables */ +/*********************/ + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5FA_get_stats + * + * Purpose: Query the metadata stats of an array + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, NOERR, +herr_t, SUCCEED, -, +H5FA_get_stats(const H5FA_t *fa, H5FA_stat_t *stats)) + + /* Local variables */ + +#ifdef H5FA_DEBUG +HDfprintf(stderr, "%s: Called\n", FUNC); +#endif /* H5FA_DEBUG */ + + /* + * Check arguments. + */ + HDassert(fa); + HDassert(stats); + + /* Copy fixed array statistics */ + HDmemcpy(stats, &fa->hdr->stats, sizeof(fa->hdr->stats)); + +END_FUNC(PRIV) /* end H5FA_get_stats() */ + diff --git a/src/H5FAtest.c b/src/H5FAtest.c new file mode 100644 index 0000000..c76c80b --- /dev/null +++ b/src/H5FAtest.c @@ -0,0 +1,391 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: + * + * Purpose: Fixed array testing functions. + * + */ + +/**********************/ +/* Module Declaration */ +/**********************/ + +#define H5FA_MODULE +#define H5FA_TESTING + + +/***********************/ +/* Other Packages Used */ +/***********************/ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FApkg.h" /* Fixed Arrays */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5Vprivate.h" /* Vector functions */ + + +/****************/ +/* Local Macros */ +/****************/ + +/* Sanity checking value for callback contexts */ +#define H5FA__TEST_BOGUS_VAL 42 + + +/******************/ +/* Local Typedefs */ +/******************/ + +/* Callback context */ +typedef struct H5FA__test_ctx_t { + uint32_t bogus; /* Placeholder field to verify that context is working */ +} H5FA__test_ctx_t; + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +/* Fixed array class callbacks */ +static void *H5FA__test_crt_context(void *udata); +static herr_t H5FA__test_dst_context(void *ctx); +static herr_t H5FA__test_fill(void *nat_blk, size_t nelmts); +static herr_t H5FA__test_encode(void *raw, const void *elmt, size_t nelmts, + void *ctx); +static herr_t H5FA__test_decode(const void *raw, void *elmt, size_t nelmts, + void *ctx); +static herr_t H5FA__test_debug(FILE *stream, int indent, int fwidth, + hsize_t idx, const void *elmt); + + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Fixed array testing class information */ +const H5FA_class_t H5FA_CLS_TEST[1]={{ + H5FA_CLS_TEST_ID, /* Type of Fixed array */ + "Testing", /* Name of fixed array class */ + sizeof(uint64_t), /* Size of native element */ + H5FA__test_crt_context, /* Create context */ + H5FA__test_dst_context, /* Destroy context */ + H5FA__test_fill, /* Fill block of missing elements callback */ + H5FA__test_encode, /* Element encoding callback */ + H5FA__test_decode, /* Element decoding callback */ + H5FA__test_debug /* Element debugging callback */ +}}; + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + +/* Declare a free list to manage the H5FA__test_ctx_t struct */ +H5FL_DEFINE_STATIC(H5FA__test_ctx_t); + + + +/*------------------------------------------------------------------------- + * Function: H5FA__test_crt_context + * + * Purpose: Create context for callbacks + * + * Return: Success: non-NULL + * Failure: NULL + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, ERR, +void *, NULL, NULL, +H5FA__test_crt_context(void UNUSED *udata)) + + /* Local variables */ + H5FA__test_ctx_t *ctx; /* Context for callbacks */ + + /* Sanity checks */ + HDassert(udata); + + /* Allocate new context structure */ + if(NULL == (ctx = H5FL_MALLOC(H5FA__test_ctx_t))) + H5E_THROW(H5E_CANTALLOC, "can't allocate fixed array client callback context") + + /* Initialize the context */ + ctx->bogus = H5FA__TEST_BOGUS_VAL; + + /* Set return value */ + ret_value = ctx; + +CATCH + +END_FUNC(STATIC) /* end H5FA__test_crt_context() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__test_dst_context + * + * Purpose: Destroy context for callbacks + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__test_dst_context(void *_ctx)) + + /* Local variables */ + H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */ + + /* Sanity checks */ + HDassert(H5FA__TEST_BOGUS_VAL == ctx->bogus); + + /* Release context structure */ + ctx = H5FL_FREE(H5FA__test_ctx_t, ctx); + +END_FUNC(STATIC) /* end H5FA__test_dst_context() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__test_fill + * + * Purpose: Fill "missing elements" in block of elements + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__test_fill(void *nat_blk, size_t nelmts)) + + /* Local variables */ + uint64_t fill_val = H5FA_TEST_FILL; /* Value to fill elements with */ + + /* Sanity checks */ + HDassert(nat_blk); + HDassert(nelmts); + + H5V_array_fill(nat_blk, &fill_val, sizeof(uint64_t), nelmts); + +END_FUNC(STATIC) /* end H5FA__test_fill() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__test_encode + * + * Purpose: Encode an element from "native" to "raw" form + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__test_encode(void *raw, const void *_elmt, size_t nelmts, void *_ctx)) + + /* Local variables */ + H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */ + const uint64_t *elmt = (const uint64_t *)_elmt; /* Convenience pointer to native elements */ + + /* Sanity checks */ + HDassert(raw); + HDassert(elmt); + HDassert(nelmts); + HDassert(H5FA__TEST_BOGUS_VAL == ctx->bogus); + + /* Encode native elements into raw elements */ + while(nelmts) { + /* Encode element */ + /* (advances 'raw' pointer) */ + UINT64ENCODE(raw, *elmt); + + /* Advance native element pointer */ + elmt++; + + /* Decrement # of elements to encode */ + nelmts--; + } /* end while */ + +END_FUNC(STATIC) /* end H5FA__test_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__test_decode + * + * Purpose: Decode an element from "raw" to "native" form + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__test_decode(const void *_raw, void *_elmt, size_t nelmts, void *_ctx)) + + /* Local variables */ + H5FA__test_ctx_t *ctx = (H5FA__test_ctx_t *)_ctx; /* Callback context to destroy */ + uint64_t *elmt = (uint64_t *)_elmt; /* Convenience pointer to native elements */ + const uint8_t *raw = (const uint8_t *)_raw; /* Convenience pointer to raw elements */ + + /* Sanity checks */ + HDassert(raw); + HDassert(elmt); + HDassert(nelmts); + HDassert(H5FA__TEST_BOGUS_VAL == ctx->bogus); + + /* Decode raw elements into native elements */ + while(nelmts) { + /* Decode element */ + /* (advances 'raw' pointer) */ + UINT64DECODE(raw, *elmt); + + /* Advance native element pointer */ + elmt++; + + /* Decrement # of elements to decode */ + nelmts--; + } /* end while */ + +END_FUNC(STATIC) /* end H5FA__test_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA__test_debug + * + * Purpose: Display an element for debugging + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(STATIC, NOERR, +herr_t, SUCCEED, -, +H5FA__test_debug(FILE *stream, int indent, int fwidth, hsize_t idx, + const void *elmt)) + + /* Local variables */ + char temp_str[128]; /* Temporary string, for formatting */ + + /* Sanity checks */ + HDassert(stream); + HDassert(elmt); + + /* Print element */ + sprintf(temp_str, "Element #%llu:", (unsigned long long)idx); + HDfprintf(stream, "%*s%-*s %llu\n", indent, "", fwidth, temp_str, + (unsigned long long)*(const uint64_t *)elmt); + +END_FUNC(STATIC) /* end H5FA__test_debug() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_get_cparam_test + * + * Purpose: Retrieve the parameters used to create the fixed array + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, NOERR, +herr_t, SUCCEED, -, +H5FA_get_cparam_test(const H5FA_t *fa, H5FA_create_t *cparam)) + + /* Check arguments. */ + HDassert(fa); + HDassert(cparam); + + /* Get fixed array creation parameters */ + cparam->raw_elmt_size = fa->hdr->cparam.raw_elmt_size; + cparam->nelmts = fa->hdr->cparam.nelmts; + +END_FUNC(PRIV) /* end H5FA_get_cparam_test() */ + + +/*------------------------------------------------------------------------- + * Function: H5FA_cmp_cparam_test + * + * Purpose: Compare the parameters used to create the fixed array + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi + * Thursday, April 30, 2009 + * + *------------------------------------------------------------------------- + */ +BEGIN_FUNC(PRIV, ERRCATCH, +int, 0, -, +H5FA_cmp_cparam_test(const H5FA_create_t *cparam1, const H5FA_create_t *cparam2)) + + /* Check arguments. */ + HDassert(cparam1); + HDassert(cparam2); + + /* Compare creation parameters for array */ + if(cparam1->raw_elmt_size < cparam2->raw_elmt_size) + H5_LEAVE(-1) + else if(cparam1->raw_elmt_size > cparam2->raw_elmt_size) + H5_LEAVE(1) + +CATCH + +END_FUNC(PRIV) /* end H5FA_cmp_cparam_test() */ + diff --git a/src/H5FDpublic.h b/src/H5FDpublic.h index b1e1482..52d7eb9 100644 --- a/src/H5FDpublic.h +++ b/src/H5FDpublic.h @@ -110,6 +110,18 @@ typedef enum H5FD_mem_t { #define H5FD_MEM_EARRAY_DBLOCK H5FD_MEM_LHEAP #define H5FD_MEM_EARRAY_DBLK_PAGE H5FD_MEM_LHEAP +/* Map "fixed array" header blocks to 'ohdr' type file memory, since its + * a fair amount of work to add a new kind of file memory and they are similar + * enough to object headers and probably too minor to deserve their own type. + * + * Map "fixed array" data blocks & pages to 'lheap' type file memory, since + * they are similar enough to local heap info. + * + */ +#define H5FD_MEM_FARRAY_HDR H5FD_MEM_OHDR +#define H5FD_MEM_FARRAY_DBLOCK H5FD_MEM_LHEAP +#define H5FD_MEM_FARRAY_DBLK_PAGE H5FD_MEM_LHEAP + /* * A free-list map which maps all types of allocation requests to a single * free list. This is useful for drivers that don't really care about diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 8e69d35..3550a4a 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -430,6 +430,10 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5EA_SBLOCK_MAGIC "EASB" /* Super block */ #define H5EA_DBLOCK_MAGIC "EADB" /* Data block */ +/* Fixed array signatures */ +#define H5FA_HDR_MAGIC "FAHD" /* Header */ +#define H5FA_DBLOCK_MAGIC "FADB" /* Data block */ + /* Free space signatures */ #define H5FS_HDR_MAGIC "FSHD" /* Header */ #define H5FS_SINFO_MAGIC "FSSE" /* Serialized sections */ diff --git a/src/H5err.txt b/src/H5err.txt index 2c5ca04..67b6448 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -75,6 +75,7 @@ MAJOR, H5E_SLIST, Skip Lists MAJOR, H5E_FSPACE, Free Space Manager MAJOR, H5E_SOHM, Shared Object Header Messages MAJOR, H5E_EARRAY, Extensible Array +MAJOR, H5E_FARRAY, Fixed Array MAJOR, H5E_NONE_MAJOR, No error # Sections (for grouping minor errors) diff --git a/src/Makefile.am b/src/Makefile.am index 5614e9e..8678e8b 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,6 +54,8 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Ftest.c \ + H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ + H5FAstat.c H5FAtest.c \ H5FD.c H5FDcore.c \ H5FDdirect.c H5FDfamily.c H5FDint.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDspace.c H5FDstdio.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 2fa92f9..727902c 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -84,15 +84,17 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Bdbg.lo H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2int.lo \ H5B2stat.lo H5B2test.lo H5C.lo H5CS.lo H5D.lo H5Dbtree.lo \ H5Dchunk.lo H5Dcompact.lo H5Dcontig.lo H5Ddbg.lo H5Ddeprec.lo \ - H5Dearray.lo H5Defl.lo H5Dfill.lo H5Dint.lo H5Dio.lo \ - H5Dmpio.lo H5Doh.lo H5Dproxy.lo H5Dscatgath.lo H5Dselect.lo \ + H5Dearray.lo H5Defl.lo H5Dfill.lo H5Dint.lo \ + H5Dio.lo H5Dmpio.lo H5Doh.lo H5Dproxy.lo H5Dscatgath.lo H5Dselect.lo \ H5Dtest.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo \ H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo \ H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo \ - H5F.lo H5Faccum.lo H5Fdbg.lo H5Ffake.lo H5Fio.lo H5Fmount.lo \ - H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Ftest.lo \ - H5FD.lo H5FDcore.lo H5FDdirect.lo H5FDfamily.lo H5FDint.lo \ - H5FDlog.lo H5FDmpi.lo H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo \ + H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo H5FAdblkpage.lo \ + H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5F.lo H5Faccum.lo \ + H5Fdbg.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ + H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Ftest.lo H5FD.lo \ + H5FDcore.lo H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo \ + H5FDmpi.lo H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo \ H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo \ H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \ H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ @@ -436,6 +438,8 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ + H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ + H5FAstat.c H5FAtest.c \ H5F.c H5Faccum.c H5Fdbg.c H5Ffake.c H5Fio.c H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Ftest.c \ H5FD.c H5FDcore.c \ @@ -667,6 +671,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Edeprec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Eint.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5F.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FA.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAcache.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAdbg.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAdblkpage.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAdblock.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAhdr.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAstat.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FAtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FD.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDcore.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5FDdirect.Plo@am__quote@ diff --git a/tools/misc/h5debug.c b/tools/misc/h5debug.c index 77cd9b2..9eabe5a 100644 --- a/tools/misc/h5debug.c +++ b/tools/misc/h5debug.c @@ -30,6 +30,8 @@ #define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/ #define H5EA_PACKAGE /*suppress error about including H5EApkg */ #define H5EA_TESTING /*suppress warning about H5EA testing funcs*/ +#define H5FA_PACKAGE /*suppress error about including H5FApkg */ +#define H5FA_TESTING /*suppress warning about H5FA testing funcs*/ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ #define H5G_PACKAGE /*suppress error about including H5Gpkg */ #define H5HF_PACKAGE /*suppress error about including H5HFpkg */ @@ -42,6 +44,7 @@ #include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5EApkg.h" /* Extensible Arrays */ +#include "H5FApkg.h" /* Fixed Arrays */ #include "H5Fpkg.h" /* File access */ #include "H5FSprivate.h" /* Free space manager */ #include "H5Gpkg.h" /* Groups */ @@ -164,6 +167,41 @@ get_H5EA_class(const uint8_t *sig) /*------------------------------------------------------------------------- + * Function: get_H5FA_class + * + * Purpose: Determine the fixed array class from the buffer read in. + * Extensible arrays are debugged through the array subclass. + * The subclass identifier is two bytes after the signature. + * + * Return: Non-NULL on success/NULL on failure + * + * Programmer: Quincey Koziol + * koziol@hdfgroup.org + * Sep 11 2008 + * + *------------------------------------------------------------------------- + */ +static const H5FA_class_t * +get_H5FA_class(const uint8_t *sig) +{ + H5FA_cls_id_t clsid = (H5FA_cls_id_t)sig[H5_SIZEOF_MAGIC + 1]; + const H5FA_class_t *cls; + + switch(clsid) { + case H5FA_CLS_TEST_ID: + cls = H5FA_CLS_TEST; + break; + + default: + fprintf(stderr, "Unknown array class %u\n", (unsigned)(clsid)); + HDexit(4); + } /* end switch */ + + return(cls); +} /* end get_H5FA_class() */ + + +/*------------------------------------------------------------------------- * Function: main * * Usage: debug FILENAME [OFFSET] @@ -494,6 +532,40 @@ main(int argc, char *argv[]) status = H5EA__dblock_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra, (size_t)extra2); + } else if(!HDmemcmp(sig, H5FA_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug a fixed array header. + */ + const H5FA_class_t *cls = get_H5FA_class(sig); + HDassert(cls); + + /* Check for enough valid parameters */ + if(extra == 0) { + fprintf(stderr, "ERROR: Need object header address containing the layout messagein order to dump header\n"); + fprintf(stderr, "Fixed array header block usage:\n"); + fprintf(stderr, "\th5debug \n"); + HDexit(4); + } /* end if */ + + status = H5FA__hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra); + + } else if(!HDmemcmp(sig, H5FA_DBLOCK_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { + /* + * Debug a fixed array data block. + */ + const H5FA_class_t *cls = get_H5FA_class(sig); + HDassert(cls); + + /* Check for enough valid parameters */ + if(extra == 0 || extra2 == 0) { + fprintf(stderr, "ERROR: Need fixed array header address and object header address containing the layout message in order to dump data block\n"); + fprintf(stderr, "fixed array data block usage:\n"); + fprintf(stderr, "\th5debug \n"); + HDexit(4); + } /* end if */ + + status = H5FA__dblock_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra, (size_t)extra2); + } else if(!HDmemcmp(sig, H5O_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* * Debug v2 object header (which have signatures). -- cgit v0.12