From 349ca8daa9a1d0f094d716ea603d7d41ac14b862 Mon Sep 17 00:00:00 2001 From: James Laird Date: Fri, 18 Mar 2005 12:19:36 -0500 Subject: [PATCH] [svn-r10234] Purpose: Added Packet Table to high-level APIs Description: The Packet Table is an API that allows the user to append records ("packets") to a table, and read the back again. It supports fixed-length records with a defined datatype and variable-length records. It also supports a "current record" index to track the user's position in the table. Solution: The Packet Table code lives in hl/src, and its tests in hl/test. Some code is shared between the H5TB table and the H5PT Packet Table in the form of functions in H5HL_private.c. Some documentation exists for a previous version of the API. Updated documentation and C++ wrapper API coming soon. Platforms tested: sleipnir, eirene, copper, modi4 --- MANIFEST | 5 + hl/Makefile.am | 10 +- hl/Makefile.in | 2 +- hl/src/H5HL_private.c | 167 ++++++++ hl/src/H5HL_private.h | 55 +++ hl/src/H5PT.c | 862 +++++++++++++++++++++++++++++++++++++++ hl/src/H5PT.h | 125 ++++++ hl/src/H5TB.c | 43 +- hl/src/Makefile.am | 5 +- hl/src/Makefile.in | 10 +- hl/test/Makefile.am | 2 +- hl/test/Makefile.in | 20 +- hl/test/test_packet.c | 907 ++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 2158 insertions(+), 55 deletions(-) create mode 100644 hl/src/H5HL_private.c create mode 100644 hl/src/H5HL_private.h create mode 100644 hl/src/H5PT.c create mode 100644 hl/src/H5PT.h create mode 100644 hl/test/test_packet.c diff --git a/MANIFEST b/MANIFEST index 659f8fb895..f442e86691 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1584,11 +1584,16 @@ ./hl/src/H5TB.h ./hl/src/H5DS.c ./hl/src/H5DS.h +./hl/src/H5PT.c +./hl/src/H5PT.h +./hl/src/H5HL_private.c +./hl/src/H5HL_private.h ./hl/test/Makefile.am ./hl/test/Makefile.in ./hl/test/test_image.c ./hl/test/test_lite.c ./hl/test/test_table.c +./hl/test/test_packet.c ./hl/test/test_ds.c ./hl/test/test_table_le.hdf5 ./hl/test/test_table_be.hdf5 diff --git a/hl/Makefile.am b/hl/Makefile.am index f178df1526..780e49438d 100644 --- a/hl/Makefile.am +++ b/hl/Makefile.am @@ -20,12 +20,10 @@ include $(top_srcdir)/config/commence.am if BUILD_FORTRAN_CONDITIONAL FORTRAN_DIR = fortran endif +##if BUILD_CXX_CONDITIONAL +## CXX_DIR = c++ +##endif -SUBDIRS=src test $(FORTRAN_DIR) - -##lib progs tests test _test: -## @@SETX@; for d in $(SUBDIRS); do \ -## (cd $$d && $(MAKE) $@) || exit 1; \ -## done +SUBDIRS=src test $(CXX_DIR) $(FORTRAN_DIR) include $(top_srcdir)/config/conclude.am diff --git a/hl/Makefile.in b/hl/Makefile.in index d3a17ed126..634e3bd965 100755 --- a/hl/Makefile.in +++ b/hl/Makefile.in @@ -262,7 +262,7 @@ H5CC_PP = $(bindir)/h5pcc H5FC = $(bindir)/h5fc H5FC_PP = $(bindir)/h5pfc @BUILD_FORTRAN_CONDITIONAL_TRUE@FORTRAN_DIR = fortran -SUBDIRS = src test $(FORTRAN_DIR) +SUBDIRS = src test $(CXX_DIR) $(FORTRAN_DIR) # Automake needs to be taught how to build lib, progs, and tests targets. # These will be filled in automatically for the most part (e.g., diff --git a/hl/src/H5HL_private.c b/hl/src/H5HL_private.c new file mode 100644 index 0000000000..723e9ead19 --- /dev/null +++ b/hl/src/H5HL_private.c @@ -0,0 +1,167 @@ +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + +#include "H5HL_private.h" + +/*------------------------------------------------------------------------- + * + * Functions shared between H5TB and H5PT + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5TBcommon_append_records + * + * Purpose: Common code for reading records shared between H5PT and H5TB + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: Called by H5TBappend_records and H5PTappend_records + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5TBcommon_append_records( hid_t dataset_id, + hid_t mem_type_id, + hsize_t nrecords, + hsize_t orig_table_size, + const void * data) +{ + hsize_t count[1]; + hsize_t offset[1]; + hid_t space_id = H5I_BADID; + hid_t mem_space_id = H5I_BADID; + hsize_t dims[1]; + hsize_t mem_dims[1]; + + /* Extend the dataset */ + dims[0] = nrecords + orig_table_size; + if ( H5Dextend ( dataset_id, dims ) < 0 ) + goto out; + + /* Create a simple memory data space */ + mem_dims[0]=nrecords; + if ( (mem_space_id = H5Screate_simple( 1, mem_dims, NULL )) < 0 ) + goto out; + + /* Get a copy of the new file data space for writing */ + if ( (space_id = H5Dget_space( dataset_id )) < 0 ) + goto out; + + /* Define a hyperslab in the dataset */ + offset[0] = orig_table_size; + count[0] = nrecords; + if ( H5Sselect_hyperslab( space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Write the records */ + if ( H5Dwrite( dataset_id, mem_type_id, mem_space_id, space_id, H5P_DEFAULT, data ) < +0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + if ( H5Sclose( space_id ) < 0 ) + goto out; + + return 0; + +out: + H5E_BEGIN_TRY + H5Sclose(mem_space_id); + H5Sclose(space_id); + H5E_END_TRY + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: H5TBcommon_read_records + * + * Purpose: Common code for reading records shared between H5PT and H5TB + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: Called by H5TBread_records and H5PTread_records + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5TBcommon_read_records( hid_t dataset_id, + hid_t mem_type_id, + hsize_t start, + hsize_t nrecords, + hsize_t table_size, + void *data) +{ + hsize_t count[1]; + hsize_t offset[1]; + hid_t space_id = H5I_BADID; + hid_t mem_space_id = H5I_BADID; + hsize_t mem_size[1]; + + /* Make sure the read request is in bounds */ + if ( start + nrecords > table_size ) + goto out; + + /* Get the dataspace handle */ + if ( (space_id = H5Dget_space( dataset_id )) < 0 ) + goto out; + + /* Define a hyperslab in the dataset of the size of the records */ + offset[0] = start; + count[0] = nrecords; + if ( H5Sselect_hyperslab( space_id, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) + goto out; + + /* Create a memory dataspace handle */ + mem_size[0] = count[0]; + if ((mem_space_id = H5Screate_simple( 1, mem_size, NULL )) < 0 ) + goto out; + if ((H5Dread( dataset_id, mem_type_id, mem_space_id, space_id, H5P_DEFAULT, data)) < 0 + ) + goto out; + + /* Terminate access to the memory dataspace */ + if ( H5Sclose( mem_space_id ) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id ) < 0 ) + goto out; + + return 0; + +out: + H5E_BEGIN_TRY + H5Sclose(space_id); + H5Sclose(mem_space_id); + H5E_END_TRY + return -1; +} + diff --git a/hl/src/H5HL_private.h b/hl/src/H5HL_private.h new file mode 100644 index 0000000000..d6f2157cf9 --- /dev/null +++ b/hl/src/H5HL_private.h @@ -0,0 +1,55 @@ +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + + +#ifndef _H5HL_private_H +#define _H5HL_private_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------------- + * + * Private write function used by H5TB and H5PT + * + *------------------------------------------------------------------------- + */ + +herr_t H5TBcommon_append_records( hid_t dataset_id, + hid_t mem_type_id, + hsize_t nrecords, + hsize_t orig_table_size, + const void * data); + +/*------------------------------------------------------------------------- + * + * Private read function used by H5TB and H5PT + * + *------------------------------------------------------------------------- + */ + + +herr_t H5TBcommon_read_records( hid_t dataset_id, + hid_t mem_type_id, + hsize_t start, + hsize_t nrecords, + hsize_t table_size, + void *data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hl/src/H5PT.c b/hl/src/H5PT.c new file mode 100644 index 0000000000..2c9b3590db --- /dev/null +++ b/hl/src/H5PT.c @@ -0,0 +1,862 @@ +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + +#include "H5PT.h" +#include "H5HL_private.h" +#include + +/* Packet Table private data */ + +typedef struct +{ + hid_t dset_id; /* The ID of the dataset containing this table */ + hid_t dspace_id; /* Single packet dataspace used for reading and writing one packet at a time */ + hid_t mem_type_id; /* The type ID of the memory datatype */ + hid_t mem_space_id; /* The space ID of the memory space data will be read into and written from */ + hsize_t current_index; /* The index of the packet that get_next_packet will read next */ + hsize_t set_size; /* The number of packets currently contained in this table */ +} htbl_t; + +static hsize_t H5PT_ptable_count = 0; +static H5I_type_t H5PT_ptable_id_type = H5I_UNINIT; + +#define H5PT_HASH_TABLE_SIZE 64 + +/* Packet Table private functions */ +herr_t H5PT_close( htbl_t* table ); +herr_t H5PT_create_index(htbl_t *table_id); +herr_t H5PT_set_index(htbl_t *table_id, hsize_t pt_index); + +/*------------------------------------------------------------------------- + * + * Create/Open/Close functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5PTcreate_fl + * + * Purpose: Creates a dataset containing a table and returns the Identifier + * of the table. + * + * Return: Success: table ID, Failure: Negative + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 12, 2004 + * + * Comments: This function does not handle compression or fill data + * currently. Fill data is not necessary because the + * table is initially of size 0. + * + * Modifications: + * + *------------------------------------------------------------------------- + */ + +hid_t H5PTcreate_fl ( hid_t loc_id, + const char *dset_name, + hid_t dtype_id, + hsize_t chunk_size ) +{ + htbl_t * table = NULL; + hid_t dset_id = H5I_BADID; + hid_t space_id = H5I_BADID; + hid_t plist_id = H5I_BADID; + hsize_t dims[1]; + hsize_t dims_chunk[1]; + hsize_t maxdims[1]; + hid_t ret_value; + + /* Register the packet table ID type if this is the first table created */ + if( H5PT_ptable_id_type < 0) + if((H5PT_ptable_id_type = H5Iregister_type(H5PT_HASH_TABLE_SIZE, 0, (H5I_free_t)free)) <0) + goto out; + + /* Get memory for the table identifier */ + table = (htbl_t *)malloc(sizeof(htbl_t)); + + /* Create a simple data space with unlimited size */ + dims[0] = 0; + dims_chunk[0] = chunk_size; + maxdims[0] = H5S_UNLIMITED; + if ( (space_id = H5Screate_simple( 1, dims, maxdims )) < 0 ) + goto out; + + /* Modify dataset creation properties to enable chunking */ + plist_id = H5Pcreate (H5P_DATASET_CREATE); + if ( H5Pset_chunk ( plist_id, 1, dims_chunk ) < 0 ) + goto out; + + /* Create the dataset. */ + if ( (dset_id=H5Dcreate( loc_id, dset_name, dtype_id, space_id, plist_id))<0 ) + goto out; + + /* Terminate access to the data space. */ + if ( H5Sclose( space_id ) < 0 ) + goto out; + + /* End access to the property list */ + if ( H5Pclose( plist_id ) < 0 ) + goto out; + + /* Create the table identifier */ + table->dset_id = dset_id; + + dims[0] = 1; + if ((table->dspace_id = H5Screate_simple(1, dims, NULL)) < 0) + goto out; + + if((table->mem_type_id = H5Tcopy(dtype_id)) <0) + goto out; + + /* Create a simple memory data space */ + if ( (table->mem_space_id = H5Screate_simple( 1, dims, NULL )) < 0 ) + goto out; + + H5PT_create_index(table); + table->set_size = 0; + + /* Get an ID for this table */ + ret_value = H5Iregister(H5PT_ptable_id_type, table); + + if (ret_value != H5I_INVALID_HID) + H5PT_ptable_count++; + else + H5PT_close(table); + + return ret_value; + + out: + H5E_BEGIN_TRY + H5Sclose(space_id); + H5Pclose(plist_id); + H5Dclose(dset_id); + if(table) + { + H5Sclose(table->mem_space_id); + H5Sclose(table->dspace_id); + free(table); + } + H5E_END_TRY + return H5I_INVALID_HID; +} + +/*------------------------------------------------------------------------- + * Function: H5PTcreate_vl + * + * Purpose: Creates a dataset containing a table of variable length records + * and returns the Identifier of the table. + * + * Return: Success: table ID, Failure: Negative + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: April 12, 2004 + * + * Comments: This function does not handle compression or fill data + * currently. Fill data is not necessary because the + * table is initially of size 0. + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t H5PTcreate_vl ( hid_t loc_id, + const char*dset_name, + hsize_t chunk_size) +{ + hid_t ret_value=H5I_BADID; + hid_t vltype; + + /* Create a variable length type that uses single bytes as its base type */ + vltype = H5Tvlen_create(H5T_NATIVE_UCHAR); + if (vltype < 0) + goto out; + + if((ret_value=H5PTcreate_fl(loc_id, dset_name, vltype, chunk_size)) <0) + goto out; + + /* close the vltype */ + if (H5Tclose(vltype) < 0) + goto out; + + return ret_value; + +out: + if(ret_value != H5I_BADID) + H5PTclose(ret_value); + return H5I_BADID; +} + +/*------------------------------------------------------------------------- + * Function: H5PTopen + * + * Purpose: Opens a dataset containing a table and returns the Identifier + * of the table. + * + * Return: Success: table ID, Failure: Negative + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 10, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +hid_t H5PTopen( hid_t loc_id, + char *dset_name ) +{ + hid_t type_id=H5I_BADID; + htbl_t * table = NULL; + hid_t ret_value; + hsize_t dims[1]; + + /* Register the packet table ID type if this is the first table created */ + if( H5PT_ptable_id_type < 0) + if((H5PT_ptable_id_type = H5Iregister_type(H5PT_HASH_TABLE_SIZE, 0, (H5I_free_t)free))<0) + goto out; + + table = (htbl_t *) malloc(sizeof(htbl_t)); + + /* Open the dataset */ + table->dset_id = H5Dopen(loc_id, dset_name); + if (table->dset_id < 0) + goto out; + + /* Create the dataspace */ + dims[0] = 1; + if ((table->dspace_id = H5Screate_simple(1, dims, NULL)) < 0) + goto out; + + /* Get the dataset's disk datatype */ + if ((type_id = H5Dget_type(table->dset_id)) < 0) + goto out; + + /* Get the native type for memory */ + if ((table->mem_type_id = H5Tget_native_type(type_id, H5T_DIR_ASCEND)) < 0) + goto out; + + /* Create a simple memory data space */ + if ( (table->mem_space_id = H5Screate_simple( 1, dims, NULL )) < 0 ) + goto out; + + /* Initialize the current record pointer */ + if((H5PT_create_index(table)) <0) + goto out; + + /* Get the dataset size from disk */ + if (H5PTget_num_records( table->dset_id, &(table->set_size)) < 0) + goto out; + + /* Get an ID for this table */ + ret_value = H5Iregister(H5PT_ptable_id_type, table); + + if (ret_value != H5I_INVALID_HID) + H5PT_ptable_count++; + else + H5PT_close(table); + + return ret_value; + +out: + H5E_BEGIN_TRY + H5Tclose(type_id); + if(table) + { + H5Sclose(table->dspace_id); + H5Dclose(table->dset_id); + H5Tclose(table->mem_type_id); + H5Sclose(table->mem_space_id); + free(table); + } + H5E_END_TRY + return H5I_INVALID_HID; +} + + +/*------------------------------------------------------------------------- + * Function: H5PT_close + * + * Purpose: Closes a table (i.e. cleans up all open resources used by a + * table). + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 10, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5PT_close( htbl_t* table) +{ + herr_t return_status = 0; + + if(table == NULL) + goto out; + + /* Close the dataspace */ + if (H5Sclose( table->dspace_id ) < 0) + goto out; + + /* Close the dataset */ + if (H5Dclose(table->dset_id) < 0) + goto out; + + /* Close the memory datatype */ + if (H5Tclose(table->mem_type_id) < 0) + goto out; + + /* Close the memory dataspace */ + if ( H5Sclose( table->mem_space_id ) < 0 ) + goto out; + + free(table); + + return 0; + +out: + if(table) + { + H5E_BEGIN_TRY + H5Sclose( table->dspace_id ); + H5Dclose(table->dset_id); + H5Tclose(table->mem_type_id); + H5Sclose( table->mem_space_id ); + H5E_END_TRY + free(table); + } + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5PTclose + * + * Purpose: Closes a table (i.e. cleans up all open resources used by a + * table). + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: April 21, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5PTclose( hid_t table_id ) +{ + htbl_t * table; + + /* Remove the ID from the library */ + if((table = H5Iremove_verify(table_id, H5PT_ptable_id_type)) ==NULL) + goto out; + + /* If the library found the table, remove it */ + if( H5PT_close(table) < 0) + goto out; + + /* One less packet table open */ + H5PT_ptable_count--; + + /* Remove the packet table type ID if no more packet */ + /* tables are open */ + if (H5PT_ptable_count == 0) + { + H5Idestroy_type(H5PT_ptable_id_type); + H5PT_ptable_id_type = H5I_UNINIT; + } + + return 0; + +out: + return -1; +} + + +/*------------------------------------------------------------------------- + * + * Write functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5PTappend + * + * Purpose: Appends packets to the end of a packet table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 12, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5PTappend( hid_t table_id, + hsize_t nrecords, + const void * data ) +{ + htbl_t * table; + + /* Find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) == NULL) + goto out; + + /* If we are asked to write 0 records, just do nothing */ + if (nrecords == 0) + return 0; + + if((H5TBcommon_append_records(table->dset_id, table->mem_type_id, + nrecords, table->set_size, data)) <0) + goto out; + + /* Update table size */ + table->set_size += nrecords; + return 0; + +out: + return -1; +} + +/*------------------------------------------------------------------------- + * + * Read functions + * + *------------------------------------------------------------------------- + */ + + +/*------------------------------------------------------------------------- + * Function: H5PTget_next + * + * Purpose: Reads packets starting at the current index and updates + * that index + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 10, 2004 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5PTget_next( hid_t table_id, + hsize_t nrecords, + void * data) +{ + htbl_t * table; + + /* Find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) == NULL) + goto out; + + /* If nrecords == 0, do nothing */ + if (nrecords == 0) + return 0; + + if((H5TBcommon_read_records(table->dset_id, table->mem_type_id, + table->current_index, nrecords, table->set_size, data)) < 0) + goto out; + + /* Update the current index */ + table->current_index += nrecords; + return 0; + +out: + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5PTread_packets + * + * Purpose: Reads packets from anywhere in a packet table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 12, 2004 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5PTread_packets( hid_t table_id, + hsize_t start, + hsize_t nrecords, + void *data) +{ + htbl_t * table; + + /* find the table struct from its ID */ + table = H5Iobject_verify(table_id, H5PT_ptable_id_type); + if (table == NULL) + goto out; + + /* If nrecords == 0, do nothing */ + if (nrecords == 0) + return 0; + + if( H5TBcommon_read_records(table->dset_id, table->mem_type_id, + start, nrecords, table->set_size, data) < 0) + goto out; + + return 0; + +out: + return -1; +} + +/*------------------------------------------------------------------------- + * + * Table attribute functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5PT_create_index, H5PT_set_index + * + * Purpose: Resets and sets the current record index for a packet table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 12, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5PT_create_index(htbl_t *table) +{ + if( table != NULL) + { + table->current_index = 0; + return 0; + } + return -1; +} + +herr_t H5PT_set_index(htbl_t *table, hsize_t index) +{ + /* Ensure index is valid */ + if( table != NULL ) + { + if( index < table->set_size ) + { + table->current_index = index; + return 0; + } + } + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5PTcreate_index, H5PTset_index + * + * Purpose: Resets and sets the current record index for a packet table + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: April 23, 2004 + * + * Comments: + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t H5PTcreate_index(hid_t table_id) +{ + htbl_t * table; + + /* find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) == NULL) + return -1; + + return H5PT_create_index(table); +} + +herr_t H5PTset_index(hid_t table_id, hsize_t pt_index) +{ + htbl_t * table; + + /* find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) == NULL) + return -1; + + return H5PT_set_index(table, pt_index); +} +/*------------------------------------------------------------------------- + * + * Inquiry functions + * + *------------------------------------------------------------------------- + */ + + +/*------------------------------------------------------------------------- + * Function: H5PTget_num_records + * + * Purpose: Returns by reference the number of records in the dataset + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 8, 2004 + * + * Comments: Called by H5PTget_field_info + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5PTget_num_records( hid_t dataset_id, hsize_t *nrecords) +{ + hid_t space_id = H5I_BADID; + hsize_t dims[1]; + + /* Get the dataspace handle */ + if ( (space_id = H5Dget_space( dataset_id )) < 0 ) + goto out; + + /* Get records */ + if ( H5Sget_simple_extent_dims( space_id, dims, NULL) < 0 ) + goto out; + + /* Terminate access to the dataspace */ + if ( H5Sclose( space_id ) < 0 ) + goto out; + + *nrecords = dims[0]; + + return 0; + +out: + H5E_BEGIN_TRY + H5Sclose(space_id); + H5E_END_TRY + return -1; +} + +/*------------------------------------------------------------------------- + * Function: H5PTget_num_packets + * + * Purpose: Returns by reference the number of packets in the dataset + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 12, 2004 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5PTget_num_packets( hid_t table_id, hsize_t *nrecords) +{ + htbl_t * table; + + /* find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) == NULL) + goto out; + + *nrecords = table->set_size; + + return 0; +out: + return -1; +} + + +/*------------------------------------------------------------------------- + * Function: H5PTis_valid + * + * Purpose: Validates a table identifier + * + * Return: Success: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: March 12, 2004 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5PTis_valid(hid_t table_id) +{ + htbl_t * table; + + /* find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) ==NULL) + return -1; + + return 0; +} + +/*------------------------------------------------------------------------- + * Function: H5PTis_varlen + * + * Purpose: Returns 1 if a table_id corresponds to a packet table of variable- + * length records or 0 for fixed-length records. + * + * Return: True: 1, False: 0, Failure: -1 + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: April 14, 2004 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ +herr_t H5PTis_varlen(hid_t table_id) +{ + H5T_class_t type; + htbl_t * table; + + /* find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) == NULL) + goto out; + + if((type = H5Tget_class( table->mem_type_id )) == H5T_NO_CLASS) + goto out; + + if( type == H5T_VLEN ) + return 1; + else + return 0; +out: + return -1; +} + +/*------------------------------------------------------------------------- + * + * Memory Management functions + * + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5PTfree_vlen_readbuff + * + * Purpose: Frees memory used when reading from a variable length packet + * table. + * + * Return: Success: 0, Failure: -1 + * -2 if memory was reclaimed but another error occurred + * + * Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu + * James Laird, jlaird@ncsa.uiuc.edu + * + * Date: April 12, 2004 + * + * Comments: + * + * Modifications: + * + * + *------------------------------------------------------------------------- + */ + +herr_t H5PTfree_vlen_readbuff( hid_t table_id, + hsize_t bufflen, + void * buff ) +{ + hid_t space_id = H5I_BADID; + htbl_t * table; + herr_t ret_value; + + /* find the table struct from its ID */ + if((table = H5Iobject_verify(table_id, H5PT_ptable_id_type)) == NULL) + goto out; + + if ((space_id = H5Screate_simple(1, &bufflen, NULL)) < 0) + goto out; + + /* Free the memory. If this succeeds, ret_value should be 0. */ + if((ret_value = H5Dvlen_reclaim(table->mem_type_id, space_id, H5P_DEFAULT, buff)) < 0) + goto out; + + /* If the dataspace cannot be closed, return -2 to indicate that memory */ + /* was freed successfully but an error still occurred. */ + if(H5Sclose(space_id) < 0) + return -2; + + return ret_value; + +out: + H5E_BEGIN_TRY + H5Sclose(space_id); + H5E_END_TRY + return -1; +} diff --git a/hl/src/H5PT.h b/hl/src/H5PT.h new file mode 100644 index 0000000000..e7cceb8a21 --- /dev/null +++ b/hl/src/H5PT.h @@ -0,0 +1,125 @@ +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING file. * + * * + ****************************************************************************/ + + +#ifndef _H5PT_H +#define _H5PT_H + +#include + +#if 0 +#define H5_PT_DEBUG +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------------- + * + * Create/Open/Close functions + * + *------------------------------------------------------------------------- + */ + +hid_t H5PTcreate_fl ( hid_t loc_id, + const char *dset_name, + hid_t dtype_id, + hsize_t chunk_size ); + +hid_t H5PTcreate_vl ( hid_t loc_id, + const char *dset_name, + hsize_t chunk_size ); + +hid_t H5PTopen( hid_t loc_id, + char *dset_name ); + +herr_t H5PTclose( hid_t table_id ); + + +/*------------------------------------------------------------------------- + * + * Write functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5PTappend( hid_t table_id, + hsize_t nrecords, + const void * data ); + +herr_t H5PTappend_single_packet( hid_t table_id, + const void * data ); + +/*------------------------------------------------------------------------- + * + * Read functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5PTget_next( hid_t table_id, + hsize_t nrecords, + void * data ); + +herr_t H5PTread_packets( hid_t table_id, + hsize_t start, + hsize_t nrecords, + void *data ); + +/*------------------------------------------------------------------------- + * + * Inquiry functions + * + *------------------------------------------------------------------------- + */ + + +herr_t H5PTget_num_records( hid_t dataset_id, + hsize_t *nrecords ); + +herr_t H5PTget_num_packets( hid_t table_id, + hsize_t *nrecords ); + +herr_t H5PTis_valid( hid_t table_id ); + +herr_t H5PTis_varlen( hid_t table_id ); + +/*------------------------------------------------------------------------- + * + * Packet Table "current index" functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5PTcreate_index( hid_t table_id ); + +herr_t H5PTset_index( hid_t table_id, + hsize_t pt_index ); + +/*------------------------------------------------------------------------- + * + * Memory Management functions + * + *------------------------------------------------------------------------- + */ + +herr_t H5PTfree_vlen_readbuff( hid_t table_id, + hsize_t bufflen, + void * buff ); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hl/src/H5TB.c b/hl/src/H5TB.c index 6b58c0f606..84f626e5d0 100644 --- a/hl/src/H5TB.c +++ b/hl/src/H5TB.c @@ -11,6 +11,7 @@ ****************************************************************************/ #include "H5TB.h" +#include "H5HL_private.h" #include #include @@ -328,42 +329,10 @@ herr_t H5TBappend_records( hid_t loc_id, if ((mem_type_id=H5TB_create_type(loc_id,dset_name,dst_size,dst_offset,dst_sizes,tid))<0) goto out; - /* Extend the dataset */ - dims[0] = nrecords_orig; - dims[0] += nrecords; + /* Append the records */ + if ((H5TBcommon_append_records(did, mem_type_id, nrecords, nrecords_orig, data))<0) + goto out; - if ( H5Dextend ( did, dims ) < 0 ) - goto out; - - /* Create a simple memory data space */ - mem_dims[0]=nrecords; - if ( (mem_space_id = H5Screate_simple( 1, mem_dims, NULL )) < 0 ) - return -1; - - /* Get the file data space */ - if ( (sid = H5Dget_space( did )) < 0 ) - return -1; - - /* Get the dimensions */ - if ( H5Sget_simple_extent_dims( sid, dims, NULL ) != 1 ) - goto out; - - /* Define a hyperslab in the dataset */ - offset[0] = nrecords_orig; - count[0] = nrecords; - if ( H5Sselect_hyperslab( sid, H5S_SELECT_SET, offset, NULL, count, NULL) < 0 ) - goto out; - - if ( H5Dwrite( did, mem_type_id, mem_space_id, sid, H5P_DEFAULT, data ) < 0 ) - goto out; - - /* Terminate access to the dataspace */ - if ( H5Sclose( mem_space_id ) < 0 ) - goto out; - - if ( H5Sclose( sid ) < 0 ) - goto out; - /* Release the datatype. */ if ( H5Tclose( tid ) < 0 ) return -1; @@ -975,6 +944,10 @@ herr_t H5TBread_records( hid_t loc_id, if ((mem_type_id=H5TB_create_type(loc_id,dset_name,dst_size,dst_offset,dst_sizes,ftype_id))<0) goto out; + /* Read the records */ + if ((H5TBcommon_read_records(did, mem_type_id, start, nrecords, nrecords_orig, data)) < 0) + goto out; + /* get the dataspace handle */ if ( (sid = H5Dget_space( did )) < 0 ) goto out; diff --git a/hl/src/Makefile.am b/hl/src/Makefile.am index adbe00a16d..db8c059269 100644 --- a/hl/src/Makefile.am +++ b/hl/src/Makefile.am @@ -10,15 +10,14 @@ include $(top_srcdir)/config/commence.am # Add include directories to the C preprocessor flags -#AM_CPPFLAGS=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src -I$(top-srcdir)/tools/lib AM_CPPFLAGS=-I$(top_srcdir)/src # This library is our main target. lib_LTLIBRARIES=libhdf5_hl.la -libhdf5_hl_la_SOURCES=H5LT.c H5TB.c H5IM.c H5DS.c +libhdf5_hl_la_SOURCES=H5LT.c H5TB.c H5IM.c H5DS.c H5PT.c H5HL_private.c # Public header files (to be installed) -include_HEADERS=H5IM.h H5LT.h H5TB.h H5DS.h +include_HEADERS=H5IM.h H5LT.h H5TB.h H5DS.h H5PT.h include $(top_srcdir)/config/conclude.am diff --git a/hl/src/Makefile.in b/hl/src/Makefile.in index f83b3c0981..060ada9656 100644 --- a/hl/src/Makefile.in +++ b/hl/src/Makefile.in @@ -66,7 +66,8 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) libhdf5_hl_la_LIBADD = -am_libhdf5_hl_la_OBJECTS = H5LT.lo H5TB.lo H5IM.lo H5DS.lo +am_libhdf5_hl_la_OBJECTS = H5LT.lo H5TB.lo H5IM.lo H5DS.lo H5PT.lo \ + H5HL_private.lo libhdf5_hl_la_OBJECTS = $(am_libhdf5_hl_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/bin/depcomp @@ -280,15 +281,14 @@ H5FC = $(bindir)/h5fc H5FC_PP = $(bindir)/h5pfc # Add include directories to the C preprocessor flags -#AM_CPPFLAGS=-I. -I$(srcdir) -I$(top_builddir)/src -I$(top_srcdir)/src -I$(top-srcdir)/tools/lib AM_CPPFLAGS = -I$(top_srcdir)/src # This library is our main target. lib_LTLIBRARIES = libhdf5_hl.la -libhdf5_hl_la_SOURCES = H5LT.c H5TB.c H5IM.c H5DS.c +libhdf5_hl_la_SOURCES = H5LT.c H5TB.c H5IM.c H5DS.c H5PT.c H5HL_private.c # Public header files (to be installed) -include_HEADERS = H5IM.h H5LT.h H5TB.h H5DS.h +include_HEADERS = H5IM.h H5LT.h H5TB.h H5DS.h H5PT.h # Automake needs to be taught how to build lib, progs, and tests targets. # These will be filled in automatically for the most part (e.g., @@ -372,8 +372,10 @@ distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5DS.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HL_private.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5IM.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5LT.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5PT.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5TB.Plo@am__quote@ .c.o: diff --git a/hl/test/Makefile.am b/hl/test/Makefile.am index 0e1c0decc4..983ac9a236 100644 --- a/hl/test/Makefile.am +++ b/hl/test/Makefile.am @@ -18,7 +18,7 @@ LDADD=$(LIBH5_HL) $(LIBHDF5) # Test programs. These are our main targets. They should be listed in the # order to be executed, generally most specific tests to least specific tests. -TEST_PROG=test_lite test_image test_table test_ds +TEST_PROG=test_lite test_image test_table test_ds test_packet check_PROGRAMS=$(TEST_PROG) # Temporary files. These files are the ones created by running `make test'. diff --git a/hl/test/Makefile.in b/hl/test/Makefile.in index ca9f292f38..84bc142916 100644 --- a/hl/test/Makefile.in +++ b/hl/test/Makefile.in @@ -21,7 +21,7 @@ # # HDF5 High-Level Test Makefile(.in) # -SOURCES = test_ds.c test_image.c test_lite.c test_table.c +SOURCES = test_ds.c test_image.c test_lite.c test_packet.c test_table.c srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -58,7 +58,7 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/bin/mkinstalldirs CONFIG_HEADER = $(top_builddir)/src/H5config.h CONFIG_CLEAN_FILES = am__EXEEXT_1 = test_lite$(EXEEXT) test_image$(EXEEXT) \ - test_table$(EXEEXT) test_ds$(EXEEXT) + test_table$(EXEEXT) test_ds$(EXEEXT) test_packet$(EXEEXT) test_ds_SOURCES = test_ds.c test_ds_OBJECTS = test_ds.$(OBJEXT) test_ds_LDADD = $(LDADD) @@ -73,6 +73,10 @@ test_lite_SOURCES = test_lite.c test_lite_OBJECTS = test_lite.$(OBJEXT) test_lite_LDADD = $(LDADD) test_lite_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) +test_packet_SOURCES = test_packet.c +test_packet_OBJECTS = test_packet.$(OBJEXT) +test_packet_LDADD = $(LDADD) +test_packet_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) test_table_SOURCES = test_table.c test_table_OBJECTS = test_table.$(OBJEXT) test_table_LDADD = $(LDADD) @@ -88,8 +92,10 @@ LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = test_ds.c test_image.c test_lite.c test_table.c -DIST_SOURCES = test_ds.c test_image.c test_lite.c test_table.c +SOURCES = test_ds.c test_image.c test_lite.c test_packet.c \ + test_table.c +DIST_SOURCES = test_ds.c test_image.c test_lite.c test_packet.c \ + test_table.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) @@ -294,7 +300,7 @@ LDADD = $(LIBH5_HL) $(LIBHDF5) # Test programs. These are our main targets. They should be listed in the # order to be executed, generally most specific tests to least specific tests. -TEST_PROG = test_lite test_image test_table test_ds +TEST_PROG = test_lite test_image test_table test_ds test_packet # Temporary files. These files are the ones created by running `make test'. MOSTLYCLEANFILES = combine_tables[1-2].h5 test_ds[1-3].h5 test_image.h5 \ @@ -362,6 +368,9 @@ test_image$(EXEEXT): $(test_image_OBJECTS) $(test_image_DEPENDENCIES) test_lite$(EXEEXT): $(test_lite_OBJECTS) $(test_lite_DEPENDENCIES) @rm -f test_lite$(EXEEXT) $(LINK) $(test_lite_LDFLAGS) $(test_lite_OBJECTS) $(test_lite_LDADD) $(LIBS) +test_packet$(EXEEXT): $(test_packet_OBJECTS) $(test_packet_DEPENDENCIES) + @rm -f test_packet$(EXEEXT) + $(LINK) $(test_packet_LDFLAGS) $(test_packet_OBJECTS) $(test_packet_LDADD) $(LIBS) test_table$(EXEEXT): $(test_table_OBJECTS) $(test_table_DEPENDENCIES) @rm -f test_table$(EXEEXT) $(LINK) $(test_table_LDFLAGS) $(test_table_OBJECTS) $(test_table_LDADD) $(LIBS) @@ -375,6 +384,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_ds.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_image.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lite.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_packet.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_table.Po@am__quote@ .c.o: diff --git a/hl/test/test_packet.c b/hl/test/test_packet.c new file mode 100644 index 0000000000..0500eddcb0 --- /dev/null +++ b/hl/test/test_packet.c @@ -0,0 +1,907 @@ + +/**************************************************************************** + * NCSA HDF * + * Scientific Data Technologies * + * National Center for Supercomputing Applications * + * University of Illinois at Urbana-Champaign * + * 605 E. Springfield, Champaign IL 61820 * + * * + * For conditions of distribution and use, see the accompanying * + * hdf/COPYING f. * + * * + ****************************************************************************/ + +#include "H5PT.h" +#include "H5TB.h" +#include +#include +#include + +/*------------------------------------------------------------------------- + * Packet Table API test + * + *------------------------------------------------------------------------- + */ + +#define NRECORDS 8 +#define BIG_TABLE_SIZE 8000 +#define NFIELDS 5 +#define TEST_FILE_NAME "test_packet_table.h5" +#define PT_NAME "Test Packet Table" +#define VL_TABLE_NAME "Varlen Test Table" +#define H5TB_TABLE_NAME "Table1" +#define TESTING(WHAT) {printf("%-70s", "Testing " WHAT); fflush(stdout);} +#define PASSED() {puts(" PASSED");fflush(stdout);} +#define H5_FAILED() {puts("*FAILED*");fflush(stdout);} + +/*------------------------------------------------------------------------- + * structure used for some tests, a particle + *------------------------------------------------------------------------- + */ +typedef struct particle_t +{ + char name[16]; + int lati; + int longi; + float pressure; + double temperature; +} particle_t; + +/*------------------------------------------------------------------------- + * a static array of particles for writing and checking reads + *------------------------------------------------------------------------- + */ +static particle_t testPart[NRECORDS] = { + {"zero", 0,0, 0.0f, 0.0}, + {"one", 10,10, 1.0f, 10.0}, + {"two", 20,20, 2.0f, 20.0}, + {"three",30,30, 3.0f, 30.0}, + {"four", 40,40, 4.0f, 40.0}, + {"five", 50,50, 5.0f, 50.0}, + {"six", 60,60, 6.0f, 60.0}, + {"seven",70,70, 7.0f, 70.0} + }; + +/*------------------------------------------------------------------------- + * function that compares one particle + *------------------------------------------------------------------------- + */ +static int cmp_par(hsize_t i, hsize_t j, particle_t *rbuf, particle_t *wbuf ) +{ + if ( ( strcmp( rbuf[i].name, wbuf[j].name ) != 0 ) || + rbuf[i].lati != wbuf[j].lati || + rbuf[i].longi != wbuf[j].longi || + rbuf[i].pressure != wbuf[j].pressure || + rbuf[i].temperature != wbuf[j].temperature ) { + return -1; + } + return 0; +} + +/*------------------------------------------------------------------------- + * function to create a datatype representing the particle struct + *------------------------------------------------------------------------- + */ +static hid_t make_particle_type() +{ + hid_t type_id; + hid_t string_type; + size_t type_size = sizeof(particle_t); + + /* Create the memory data type. */ + if ((type_id = H5Tcreate (H5T_COMPOUND, type_size )) < 0 ) + return -1; + + /* Insert fields. */ + string_type = H5Tcopy( H5T_C_S1 ); + H5Tset_size( string_type, 16 ); + + if ( H5Tinsert(type_id, "Name", HOFFSET(particle_t, name) , string_type ) < 0 ) + return -1; + if ( H5Tinsert(type_id, "Lat", HOFFSET(particle_t, lati) , H5T_NATIVE_INT ) < 0 ) + return -1; + if ( H5Tinsert(type_id, "Long", HOFFSET(particle_t, longi) , H5T_NATIVE_INT ) < 0 ) + return -1; + if ( H5Tinsert(type_id, "Pressure", HOFFSET(particle_t, pressure) , H5T_NATIVE_FLOAT ) < 0 ) + return -1; + if ( H5Tinsert(type_id, "Temperature", HOFFSET(particle_t, temperature) , H5T_NATIVE_DOUBLE ) < 0 ) + return -1; + + return type_id; +} + + /* Create a normal HL table just like the HL examples do */ +static int create_hl_table(hid_t fid) +{ + particle_t testparticle; + + /* Calculate the offsets of the particle struct members in memory */ + size_t part_offset[NFIELDS] = { HOFFSET( particle_t, name ), + HOFFSET( particle_t, lati ), + HOFFSET( particle_t, longi ), + HOFFSET( particle_t, pressure ), + HOFFSET( particle_t, temperature )}; + + size_t part_sizes[NFIELDS] = { sizeof( testparticle.name), + sizeof( testparticle.lati), + sizeof( testparticle.longi), + sizeof( testparticle.pressure), + sizeof( testparticle.temperature)}; + + /* Define field information */ + const char *field_names[NFIELDS] = + { "Name","Latitude", "Longitude", "Pressure", "Temperature" }; + hid_t field_type[NFIELDS]; + hid_t string_type; + hsize_t chunk_size = 10; + int *fill_data = NULL; + int compress = 0; + herr_t status; + + /* Initialize the field field_type */ + string_type = H5Tcopy( H5T_C_S1 ); + H5Tset_size( string_type, 16 ); + field_type[0] = string_type; + field_type[1] = H5T_NATIVE_INT; + field_type[2] = H5T_NATIVE_INT; + field_type[3] = H5T_NATIVE_FLOAT; + field_type[4] = H5T_NATIVE_DOUBLE; + + + /*------------------------------------------------------------------------ + * H5TBmake_table + *------------------------------------------------------------------------- + */ + + status=H5TBmake_table( "Table Title", fid, H5TB_TABLE_NAME, (hsize_t) NFIELDS, + (hsize_t)NRECORDS, sizeof(particle_t), + field_names, part_offset, field_type, + chunk_size, fill_data, compress, testPart ); + +if(status<0) + return -1; +else + return 0; +} + + + +/*------------------------------------------------------------------------- + * test_create_close + * + * Tests creation and closing of an FL packet table + * + *------------------------------------------------------------------------- + */ + +int test_create_close(hid_t fid) +{ + herr_t err; + hid_t table; + hid_t part_t; + + TESTING("H5PTcreate_fl and H5TBclose"); + + /* Create a datatype for the particle struct */ + part_t = make_particle_type(); + + assert(part_t != -1); + + /* Create the table */ + table = H5PTcreate_fl(fid, PT_NAME, part_t, 100); + H5Tclose(part_t); + if( H5PTis_valid(table) < 0) + goto out; + if( H5PTis_varlen(table) != 0) + goto out; + + /* Close the table */ + err = H5PTclose(table); + if( err < 0) + goto out; + + PASSED(); + return 0; + + out: + H5_FAILED(); + return -1; +} + +/*------------------------------------------------------------------------- + * test_open + * + * Tests opening and closing a FL packet table + * + *------------------------------------------------------------------------- + */ +int test_open(hid_t fid) +{ + herr_t err; + hid_t table; + + TESTING("H5PTopen"); + + /* Open the table */ + table = H5PTopen(fid, PT_NAME); + if( H5PTis_valid(table) < 0) + goto out; + if( H5PTis_varlen(table) != 0) + goto out; + + /* Close the table */ + err = H5PTclose(table); + if( err < 0) + goto out; + + PASSED(); + return 0; + + out: + H5_FAILED(); + return -1; +} + +/*------------------------------------------------------------------------- + * test_append + * + * Tests appending packets to a FL packet table + * + *------------------------------------------------------------------------- + */ +int test_append(hid_t fid) +{ + herr_t err; + hid_t table; + hsize_t count; + + TESTING("H5PTappend"); + + /* Open the table */ + table = H5PTopen(fid, PT_NAME); + if( H5PTis_valid(table) < 0) + goto out; + + /* Count the number of packets in the table */ + err = H5PTget_num_packets(table, &count); + if( err < 0) + goto out; + /* There should be 0 records in the table */ + if( count != 0 ) + goto out; + + /* Append one particle */ + err = H5PTappend(table, 1, &(testPart[0])); + if( err < 0) + goto out; + + /* Append several particles */ + err = H5PTappend(table, 6, &(testPart[1])); + if( err < 0) + goto out; + + /* Append one more particle */ + err = H5PTappend(table, 1, &(testPart[7])); + if( err < 0) + goto out; + + /* Count the number of packets in the table */ + err = H5PTget_num_packets(table, &count); + if( err < 0) + goto out; + /* There should be 8 records in the table now */ + if( count != 8 ) + goto out; + + /* Close the table */ + err = H5PTclose(table); + if( err < 0) + goto out; + + PASSED(); + return 0; + + out: + H5_FAILED(); + if( H5PTis_valid(table) < 0) + H5PTclose(table); + return -1; +} + +/*------------------------------------------------------------------------- + * test_read + * + * Tests that the packets appended by test_append can be read back. + * + *------------------------------------------------------------------------- + */ +int test_read(hid_t fid) +{ + herr_t err; + hid_t table; + particle_t readBuf[NRECORDS]; + int c; + + TESTING("H5PTread_packets"); + + /* Open the table */ + table = H5PTopen(fid, PT_NAME); + if( H5PTis_valid(table) < 0) + goto out; + + /* Read several particles */ + err = H5PTread_packets(table, 0, 3, &(readBuf[0])); + if( err < 0) + goto out; + + /* Read one particle */ + err = H5PTread_packets(table, 3, 1, &(readBuf[3])); + if( err < 0) + goto out; + + /* Read several particles */ + err = H5PTread_packets(table, 4, (NRECORDS - 4 ), &(readBuf[4])); + if( err < 0) + goto out; + + /* Ensure that particles were read correctly */ + for(c=0; c= 0) + goto out; + if(H5PTopen(fid, "group1") >= 0) + goto out; + H5E_END_TRY + + /* Try to execute packet table commands on an invalid ID */ + H5E_BEGIN_TRY + if(H5PTis_valid(id) >= 0) + goto out; + if(H5PTis_varlen(id) >= 0) + goto out; + if(H5PTclose(id) >= 0) + goto out; + if(H5PTappend(id, 1, testPart) >= 0) + goto out; + if(H5PTread_packets(id, 0, 1, readBuf) >= 0) + goto out; + if(H5PTcreate_index(id) >= 0) + goto out; + H5E_END_TRY + + /* Open a high-level non-packet (H5TB) table and try to */ + /* execute commands on it. */ + if((id=H5Dopen(fid, H5TB_TABLE_NAME)) <0) + goto out; + id_open = 1; + + H5E_BEGIN_TRY + if(H5PTis_valid(id) >= 0) + goto out; + if(H5PTis_varlen(id) >= 0) + goto out; + if(H5PTclose(id) >= 0) + goto out; + if(H5PTappend(id, 1, testPart) >= 0) + goto out; + if(H5PTread_packets(id, 0, 1, readBuf) >= 0) + goto out; + if(H5PTcreate_index(id) >= 0) + goto out; + H5E_END_TRY + + id_open=0; + if(H5Dclose(id) <0) + goto out; + + /* Open and close a packet table. Try to execute */ + /* commands on the closed ID. */ + if((id=H5PTopen(fid, PT_NAME))<0) + goto out; + if(H5PTclose(id) <0) + goto out; + + H5E_BEGIN_TRY + if(H5PTis_valid(id) >= 0) + goto out; + if(H5PTis_varlen(id) >= 0) + goto out; + if(H5PTclose(id) >= 0) + goto out; + if(H5PTappend(id, 1, testPart) >= 0) + goto out; + if(H5PTread_packets(id, 0, 1, readBuf) >= 0) + goto out; + if(H5PTcreate_index(id) >= 0) + goto out; + H5E_END_TRY + + PASSED(); + return 0; + +out: + H5_FAILED(); + if(id_open) + H5Dclose(id); + return -1; +} + + +int test_packet_table(hid_t fid) +{ + + if( test_create_close(fid) < 0 ) + return -1; + + if( test_open(fid) < 0 ) + return -1; + + /* test_append must be run before test_count and test_read, as it */ + /* creates the packet table they use. */ + if( test_append(fid) < 0 ) + return -1; + + /* These tests will not necessarily cause failures in each other, + so we don't abort the other tests if one fails. */ + test_read(fid); + test_get_next(fid); + test_big_table(fid); + test_varlen(fid); + test_opaque(fid); + test_error(fid); + + return 0; +} + +int main(void) +{ + /* identifier for the file */ + hid_t fid; + int status = 0; + +/*------------------------------------------------------------------------- + * Packet test: test each function of the packet table + *------------------------------------------------------------------------- + */ + + /* create a file using default properties */ + fid=H5Fcreate(TEST_FILE_NAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + + puts("Testing packet table"); + + /* run tests */ + if ( test_packet_table(fid) < 0) + status = 1; + + /* close */ + H5Fclose(fid); + + return status; +}