From 4494348eb229ae0661754c974695d8a293c6168b Mon Sep 17 00:00:00 2001 From: Robb Matzke Date: Tue, 17 Mar 1998 16:50:32 -0500 Subject: [svn-r323] Changes since 19980316 ---------------------- ./src/H5D.c ./src/H5T.c ./src/H5Tprivate.h Fixed a bug found by Kevin Powell regarding preservation of existing data during a read or write when the source and destination data types are the same. Thanks Kevin! Fixed a couple warnings on Irix64. ./src/H5D.c ./src/H5Dprivate.h ./src/H5P.c ./src/H5Ppublic.c ./src/H5Tconv.c ./src/H5Tpublic.h ./test/cmpd_dset.c The application can now turn on/off the part of the I/O pipeline that deals with preservation of initialized data. The default is off since this will be the usual case and turning it on slows down the pipe. Use H5Pset_preserve() and H5Pget_preserve(). ./src/H5Fistore.c Added an optimization for reading/writing a single chunk of chunked storage. ./src/H5Odtype.c ./src/H5Oefl.c ./src/H5Olayout.c ./src/H5Oname.c ./src/H5Osdspace.c ./src/H5Ostab.c Fixed warnings reported by marek@iiasa.ac.at. Thanks Marek. ./src/H5Odtype.c Fixed a failing assert() wrt reading compound types (not present in hdf5-1.0.0a). --- src/H5D.c | 113 ++++--- src/H5Distore.c | 882 +++++++++++++++++++++++++++++-------------------------- src/H5Dprivate.h | 9 +- src/H5Fistore.c | 882 +++++++++++++++++++++++++++++-------------------------- src/H5Odtype.c | 7 +- src/H5Oefl.c | 6 +- src/H5Olayout.c | 6 +- src/H5Oname.c | 2 +- src/H5Osdspace.c | 4 +- src/H5Ostab.c | 4 +- src/H5P.c | 84 +++++- src/H5Ppublic.h | 2 + src/H5T.c | 14 +- src/H5Tconv.c | 10 +- src/H5Tprivate.h | 3 +- src/H5Tpublic.h | 2 +- test/cmpd_dset.c | 17 +- 17 files changed, 1127 insertions(+), 920 deletions(-) diff --git a/src/H5D.c b/src/H5D.c index fce1528..3a73c40 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -66,6 +66,7 @@ const H5D_xfer_t H5D_xfer_dflt = { 1024*1024, /* Temporary buffer size */ NULL, /* Type conversion buffer or NULL */ NULL, /* Background buffer or NULL */ + H5T_BKG_NO, /* Type of background buffer needed */ }; /* Interface initialization? */ @@ -1104,8 +1105,8 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, size_t src_type_size; /*size of source type */ size_t dst_type_size; /*size of destination type*/ size_t target_size; /*desired buffer size */ - size_t buffer_size; /*actual buffer size */ size_t request_nelmts; /*requested strip mine */ + H5T_bkg_t need_bkg; /*type of background buf*/ FUNC_ENTER(H5D_read, FAIL); @@ -1121,9 +1122,13 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* * Locate the type conversion function and data space conversion * functions, and set up the element numbering information. If a data - * type conversion is necessary then register data type atoms. + * type conversion is necessary then register data type atoms. Data type + * conversion is necessary if the user has set the `need_bkg' to a high + * enough value in xfer_parms since turning off data type conversion also + * turns off background preservation. */ - if (NULL == (tconv_func = H5T_find(dataset->type, mem_type, &cdata))) { + if (NULL == (tconv_func = H5T_find(dataset->type, mem_type, + xfer_parms->need_bkg, &cdata))) { HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types"); } else if (H5T_conv_noop!=tconv_func) { @@ -1185,7 +1190,6 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, smine_nelmts = request_nelmts; HDmemset (&numbering, 0, sizeof numbering); } - buffer_size = smine_nelmts * MAX (src_type_size, dst_type_size); /* * Get a temporary buffer for type conversion unless the app has already @@ -1194,28 +1198,36 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * malloc() is usually less resource-intensive if we allocate/free the * same size over and over. */ - if (NULL==(tconv_buf=xfer_parms->tconv)) { + if (cdata->need_bkg) { + need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg); + } else { + need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/ + } + if (NULL==(tconv_buf=xfer_parms->tconv_buf)) { tconv_buf = H5MM_xmalloc (target_size); } - if (cdata->need_bkg && NULL==(bkg_buf=xfer_parms->bkg)) { + if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) { bkg_buf = H5MM_xmalloc (smine_nelmts * dst_type_size); } #ifdef H5D_DEBUG - /* Strip mine diagnostics.... */ - if (smine_nelmtsneed_bkg) { + if ((H5D_OPTIMIZE_PIPE && H5T_BKG_YES==need_bkg) || + (!H5D_OPTIMIZE_PIPE && need_bkg)) { if ((sconv_func->mgath)(buf, H5T_get_size (mem_type), mem_space, &numbering, smine_start, smine_nelmts, bkg_buf/*out*/)!=smine_nelmts) { @@ -1271,10 +1284,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, done: if (src_id >= 0) H5A_dec_ref(src_id); if (dst_id >= 0) H5A_dec_ref(dst_id); - if (tconv_buf && NULL==xfer_parms->tconv) { + if (tconv_buf && NULL==xfer_parms->tconv_buf) { H5MM_xfree(tconv_buf); } - if (bkg_buf && NULL==xfer_parms->bkg) { + if (bkg_buf && NULL==xfer_parms->bkg_buf) { H5MM_xfree (bkg_buf); } FUNC_LEAVE(ret_value); @@ -1317,8 +1330,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, size_t src_type_size; /*size of source type */ size_t dst_type_size; /*size of destination type*/ size_t target_size; /*desired buffer size */ - size_t buffer_size; /*actual buffer size */ size_t request_nelmts; /*requested strip mine */ + H5T_bkg_t need_bkg; /*type of background buf*/ FUNC_ENTER(H5D_write, FAIL); @@ -1334,9 +1347,13 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* * Locate the type conversion function and data space conversion * functions, and set up the element numbering information. If a data - * type conversion is necessary then register data type atoms. + * type conversion is necessary then register data type atoms. Data type + * conversion is necessary if the user has set the `need_bkg' to a high + * enough value in xfer_parms since turning off data type conversion also + * turns off background preservation. */ - if (NULL == (tconv_func = H5T_find(mem_type, dataset->type, &cdata))) { + if (NULL == (tconv_func = H5T_find(mem_type, dataset->type, + xfer_parms->need_bkg, &cdata))) { HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types"); } else if (H5T_conv_noop!=tconv_func) { @@ -1398,7 +1415,6 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, smine_nelmts = request_nelmts; HDmemset (&numbering, 0, sizeof numbering); } - buffer_size = smine_nelmts * MAX (src_type_size, dst_type_size); /* * Get a temporary buffer for type conversion unless the app has already @@ -1407,28 +1423,36 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * malloc() is usually less resource-intensive if we allocate/free the * same size over and over. */ - if (NULL==(tconv_buf=xfer_parms->tconv)) { + if (cdata->need_bkg) { + need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg); + } else { + need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/ + } + if (NULL==(tconv_buf=xfer_parms->tconv_buf)) { tconv_buf = H5MM_xmalloc (target_size); } - if (cdata->need_bkg && NULL==(bkg_buf=xfer_parms->bkg)) { + if (need_bkg && NULL==(bkg_buf=xfer_parms->bkg_buf)) { bkg_buf = H5MM_xmalloc (smine_nelmts * dst_type_size); } #ifdef H5D_DEBUG - /* Strip mine diagnostics.... */ - if (smine_nelmtsneed_bkg) { + if ((H5D_OPTIMIZE_PIPE && H5T_BKG_YES==need_bkg) || + (!H5D_OPTIMIZE_PIPE && need_bkg)) { if ((sconv_func->fgath)(dataset->ent.file, &(dataset->layout), &(dataset->create_parms->efl), H5T_get_size (dataset->type), file_space, @@ -1487,10 +1512,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, done: if (src_id >= 0) H5A_dec_ref(src_id); if (dst_id >= 0) H5A_dec_ref(dst_id); - if (tconv_buf && NULL==xfer_parms->tconv) { + if (tconv_buf && NULL==xfer_parms->tconv_buf) { H5MM_xfree(tconv_buf); } - if (bkg_buf && NULL==xfer_parms->bkg) { + if (bkg_buf && NULL==xfer_parms->bkg_buf) { H5MM_xfree (bkg_buf); } FUNC_LEAVE(ret_value); diff --git a/src/H5Distore.c b/src/H5Distore.c index 25b81b2..c75a3b7 100644 --- a/src/H5Distore.c +++ b/src/H5Distore.c @@ -1,9 +1,9 @@ /* * Copyright (C) 1997 NCSA - * All rights reserved. + * All rights reserved. * * Programmer: Robb Matzke - * Wednesday, October 8, 1997 + * Wednesday, October 8, 1997 */ #include #include @@ -15,48 +15,48 @@ #include typedef enum H5F_isop_t { - H5F_ISTORE_READ, /*read from file to memory */ - H5F_ISTORE_WRITE /*write from memory to file */ + H5F_ISTORE_READ, /*read from file to memory */ + H5F_ISTORE_WRITE /*write from memory to file */ } H5F_isop_t; /* Does the array domain include negative indices? */ #undef H5F_ISTORE_NEGATIVE_DOMAIN -#define PABLO_MASK H5F_istore_mask +#define PABLO_MASK H5F_istore_mask /* Interface initialization */ -static hbool_t interface_initialize_g = FALSE; +static hbool_t interface_initialize_g = FALSE; #define INTERFACE_INIT NULL /* PRIVATE PROTOTYPES */ -static size_t H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata); -static herr_t H5F_istore_new_node(H5F_t *f, H5B_ins_t, void *_lt_key, - void *_udata, void *_rt_key, haddr_t *); -static intn H5F_istore_cmp2(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static intn H5F_istore_cmp3(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static herr_t H5F_istore_found(H5F_t *f, const haddr_t *addr, - const void *_lt_key, void *_udata, - const void *_rt_key); -static H5B_ins_t H5F_istore_insert(H5F_t *f, const haddr_t *addr, - void *_lt_key, hbool_t *lt_key_changed, - void *_md_key, void *_udata, - void *_rt_key, hbool_t *rt_key_changed, - haddr_t *); -static herr_t H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static herr_t H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, - H5F_isop_t op, - const size_t offset_f[], - const size_t size[], - const size_t offset_m[], - const size_t size_m[], const void *buf); +static size_t H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata); +static herr_t H5F_istore_new_node(H5F_t *f, H5B_ins_t, void *_lt_key, + void *_udata, void *_rt_key, haddr_t *); +static intn H5F_istore_cmp2(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static intn H5F_istore_cmp3(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static herr_t H5F_istore_found(H5F_t *f, const haddr_t *addr, + const void *_lt_key, void *_udata, + const void *_rt_key); +static H5B_ins_t H5F_istore_insert(H5F_t *f, const haddr_t *addr, + void *_lt_key, hbool_t *lt_key_changed, + void *_md_key, void *_udata, + void *_rt_key, hbool_t *rt_key_changed, + haddr_t *new_node/*out*/); +static herr_t H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static herr_t H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, + H5F_isop_t op, const size_t offset_f[], + const size_t size[], + const size_t offset_m[], + const size_t size_m[], + void *buf); /* - * B-tree key. A key contains the minimum logical N-dimensional address and + * B-tree key. A key contains the minimum logical N-dimensional address and * the logical size of the chunk to which this key refers. The * fastest-varying dimension is assumed to reference individual bytes of the * array, so a 100-element 1-d array of 4-byte integers would really be a 2-d @@ -70,50 +70,49 @@ static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t * * The storage file address is part of the B-tree and not part of the key. */ typedef struct H5F_istore_key_t { - uintn file_number; /*external file number */ - size_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start */ - size_t size[H5O_LAYOUT_NDIMS]; /*logical chunk size */ + uintn file_number; /*external file number */ + size_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/ + size_t size[H5O_LAYOUT_NDIMS]; /*logical chunk size */ } H5F_istore_key_t; typedef struct H5F_istore_ud1_t { - H5F_istore_key_t key; /*key values */ - haddr_t addr; /*file address of chunk */ - H5O_layout_t mesg; /*layout message */ + H5F_istore_key_t key; /*key values */ + haddr_t addr; /*file address of chunk */ + H5O_layout_t mesg; /*layout message */ } H5F_istore_ud1_t; /* inherits B-tree like properties from H5B */ -H5B_class_t H5B_ISTORE[1] = -{ - { - H5B_ISTORE_ID, /*id */ - sizeof(H5F_istore_key_t), /*sizeof_nkey */ - H5F_istore_sizeof_rkey, /*get_sizeof_rkey */ - H5F_istore_new_node, /*new */ - H5F_istore_cmp2, /*cmp2 */ - H5F_istore_cmp3, /*cmp3 */ - H5F_istore_found, /*found */ - H5F_istore_insert, /*insert */ - FALSE, /*follow min branch? */ - FALSE, /*follow max branch? */ - NULL, /*list */ - H5F_istore_decode_key, /*decode */ - H5F_istore_encode_key, /*encode */ - }}; +H5B_class_t H5B_ISTORE[1] = {{ + H5B_ISTORE_ID, /*id */ + sizeof(H5F_istore_key_t), /*sizeof_nkey */ + H5F_istore_sizeof_rkey, /*get_sizeof_rkey */ + H5F_istore_new_node, /*new */ + H5F_istore_cmp2, /*cmp2 */ + H5F_istore_cmp3, /*cmp3 */ + H5F_istore_found, /*found */ + H5F_istore_insert, /*insert */ + FALSE, /*follow min branch? */ + FALSE, /*follow max branch? */ + NULL, /*list */ + H5F_istore_decode_key, /*decode */ + H5F_istore_encode_key, /*encode */ +}}; + /*------------------------------------------------------------------------- - * Function: H5F_istore_sizeof_rkey + * Function: H5F_istore_sizeof_rkey * - * Purpose: Returns the size of a raw key for the specified UDATA. The - * size of the key is dependent on the number of dimensions for - * the object to which this B-tree points. The dimensionality - * of the UDATA is the only portion that's referenced here. + * Purpose: Returns the size of a raw key for the specified UDATA. The + * size of the key is dependent on the number of dimensions for + * the object to which this B-tree points. The dimensionality + * of the UDATA is the only portion that's referenced here. * - * Return: Success: Size of raw key in bytes. + * Return: Success: Size of raw key in bytes. * - * Failure: abort() + * Failure: abort() * - * Programmer: Robb Matzke - * Wednesday, October 8, 1997 + * Programmer: Robb Matzke + * Wednesday, October 8, 1997 * * Modifications: * @@ -123,29 +122,30 @@ static size_t H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata) { const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *) _udata; - size_t nbytes; + size_t nbytes; assert(udata); assert(udata->mesg.ndims > 0 && udata->mesg.ndims <= H5O_LAYOUT_NDIMS); - nbytes = 4 + /*external file number */ - udata->mesg.ndims * 4 + /*dimension indices */ - udata->mesg.ndims * 4; /*dimension sizes */ + nbytes = 4 + /*external file number */ + udata->mesg.ndims * 4 + /*dimension indices */ + udata->mesg.ndims * 4; /*dimension sizes */ return nbytes; } + /*------------------------------------------------------------------------- - * Function: H5F_istore_decode_key + * Function: H5F_istore_decode_key * - * Purpose: Decodes a raw key into a native key for the B-tree + * Purpose: Decodes a raw key into a native key for the B-tree * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Friday, October 10, 1997 + * Programmer: Robb Matzke + * Friday, October 10, 1997 * * Modifications: * @@ -154,9 +154,9 @@ H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata) static herr_t H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) { - H5F_istore_key_t *key = (H5F_istore_key_t *) _key; - intn i; - intn ndims = (intn)(bt->sizeof_rkey / 8); + H5F_istore_key_t *key = (H5F_istore_key_t *) _key; + intn i; + intn ndims = (intn)(bt->sizeof_rkey/8); FUNC_ENTER(H5F_istore_decode_key, FAIL); @@ -171,25 +171,25 @@ H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) UINT32DECODE(raw, key->file_number); assert(0 == key->file_number); for (i = 0; i < ndims; i++) { - UINT32DECODE(raw, key->offset[i]); - UINT32DECODE(raw, key->size[i]); + UINT32DECODE(raw, key->offset[i]); + UINT32DECODE(raw, key->size[i]); } FUNC_LEAVE(SUCCEED); - } + /*------------------------------------------------------------------------- - * Function: H5F_istore_encode_key + * Function: H5F_istore_encode_key * - * Purpose: Encode a key from native format to raw format. + * Purpose: Encode a key from native format to raw format. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Friday, October 10, 1997 + * Programmer: Robb Matzke + * Friday, October 10, 1997 * * Modifications: * @@ -198,9 +198,9 @@ H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) static herr_t H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) { - H5F_istore_key_t *key = (H5F_istore_key_t *) _key; - intn ndims = (intn)(bt->sizeof_rkey / 8); - intn i; + H5F_istore_key_t *key = (H5F_istore_key_t *) _key; + intn ndims = (intn)(bt->sizeof_rkey / 8); + intn i; FUNC_ENTER(H5F_istore_encode_key, FAIL); @@ -215,29 +215,30 @@ H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) UINT32ENCODE(raw, key->file_number); assert(0 == key->file_number); for (i = 0; i < ndims; i++) { - UINT32ENCODE(raw, key->offset[i]); - UINT32ENCODE(raw, key->size[i]); + UINT32ENCODE(raw, key->offset[i]); + UINT32ENCODE(raw, key->size[i]); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_cmp2 + * Function: H5F_istore_cmp2 * - * Purpose: Compares two keys sort of like strcmp(). The UDATA pointer - * is only to supply extra information not carried in the keys - * (in this case, the dimensionality) and is not compared - * against the keys. + * Purpose: Compares two keys sort of like strcmp(). The UDATA pointer + * is only to supply extra information not carried in the keys + * (in this case, the dimensionality) and is not compared + * against the keys. * - * Return: Success: -1 if LT_KEY is less than RT_KEY; - * 1 if LT_KEY is greater than RT_KEY; - * 0 if LT_KEY and RT_KEY are equal. + * Return: Success: -1 if LT_KEY is less than RT_KEY; + * 1 if LT_KEY is greater than RT_KEY; + * 0 if LT_KEY and RT_KEY are equal. * - * Failure: FAIL (same as LT_KEYmesg.ndims > 0 && udata->mesg.ndims <= H5O_LAYOUT_NDIMS); if (H5V_vector_lt(udata->mesg.ndims, udata->key.offset, lt_key->offset)) { - cmp = -1; + cmp = -1; } else if (H5V_vector_ge(udata->mesg.ndims, udata->key.offset, - rt_key->offset)) { - cmp = 1; + rt_key->offset)) { + cmp = 1; } FUNC_LEAVE(cmp); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_new_node + * Function: H5F_istore_new_node * - * Purpose: Adds a new entry to an i-storage B-tree. We can assume that - * the domain represented by UDATA doesn't intersect the domain - * already represented by the B-tree. + * Purpose: Adds a new entry to an i-storage B-tree. We can assume that + * the domain represented by UDATA doesn't intersect the domain + * already represented by the B-tree. * - * Return: Success: SUCCEED. The address of leaf is returned - * through the ADDR argument. It is also added - * to the UDATA. + * Return: Success: SUCCEED. The address of leaf is returned + * through the ADDR argument. It is also added + * to the UDATA. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, October 14, 1997 + * Programmer: Robb Matzke + * Tuesday, October 14, 1997 * * Modifications: * @@ -339,14 +342,14 @@ H5F_istore_cmp3(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) */ static herr_t H5F_istore_new_node(H5F_t *f, H5B_ins_t op, - void *_lt_key, void *_udata, void *_rt_key, - haddr_t *addr /*out */ ) + void *_lt_key, void *_udata, void *_rt_key, + haddr_t *addr/*out*/) { - H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; - H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; - H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; - size_t nbytes; - intn i; + H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; + H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; + H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; + size_t nbytes; + intn i; FUNC_ENTER(H5F_istore_new_node, FAIL); @@ -362,55 +365,56 @@ H5F_istore_new_node(H5F_t *f, H5B_ins_t op, nbytes = H5V_vector_reduce_product(udata->mesg.ndims, udata->key.size); assert(nbytes > 0); if (H5MF_alloc(f, H5MF_RAW, nbytes, addr /*out */ ) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "couldn't allocate new file storage"); + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, + "couldn't allocate new file storage"); } udata->addr = *addr; udata->key.file_number = 0; lt_key->file_number = udata->key.file_number; if (H5B_INS_LEFT != op) - rt_key->file_number = 0; + rt_key->file_number = 0; /* Initialize the key(s) */ for (i = 0; i < udata->mesg.ndims; i++) { - /* - * The left key describes the storage of the UDATA chunk being inserted - * into the tree. - */ - assert(udata->key.size[i] > 0); - lt_key->offset[i] = udata->key.offset[i]; - lt_key->size[i] = udata->key.size[i]; - - /* - * The right key might already be present. If not, then add - * a zero-width chunk. - */ - if (H5B_INS_LEFT != op) { - rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i]; - rt_key->size[i] = 0; - } + /* + * The left key describes the storage of the UDATA chunk being + * inserted into the tree. + */ + assert(udata->key.size[i] > 0); + lt_key->offset[i] = udata->key.offset[i]; + lt_key->size[i] = udata->key.size[i]; + + /* + * The right key might already be present. If not, then add + * a zero-width chunk. + */ + if (H5B_INS_LEFT != op) { + rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i]; + rt_key->size[i] = 0; + } } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_found + * Function: H5F_istore_found * - * Purpose: This function is called when the B-tree search engine has - * found the leaf entry that points to a chunk of storage that - * contains the beginning of the logical address space - * represented by UDATA. The LT_KEY is the left key (the one - * that describes the chunk) and RT_KEY is the right key (the - * one that describes the next or last chunk). + * Purpose: This function is called when the B-tree search engine has + * found the leaf entry that points to a chunk of storage that + * contains the beginning of the logical address space + * represented by UDATA. The LT_KEY is the left key (the one + * that describes the chunk) and RT_KEY is the right key (the + * one that describes the next or last chunk). * - * Return: Success: SUCCEED with information about the chunk - * returned through the UDATA argument. + * Return: Success: SUCCEED with information about the chunk + * returned through the UDATA argument. * - * Failure: FAIL if not found. + * Failure: FAIL if not found. * - * Programmer: Robb Matzke - * Thursday, October 9, 1997 + * Programmer: Robb Matzke + * Thursday, October 9, 1997 * * Modifications: * @@ -418,11 +422,11 @@ H5F_istore_new_node(H5F_t *f, H5B_ins_t op, */ static herr_t H5F_istore_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, - void *_udata, const void *_rt_key) + void *_udata, const void *_rt_key) { - H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; + H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *) _lt_key; - int i; + int i; FUNC_ENTER(H5F_istore_found, FAIL); @@ -437,39 +441,40 @@ H5F_istore_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, udata->key.file_number = lt_key->file_number; assert(0 == lt_key->file_number); for (i = 0; i < udata->mesg.ndims; i++) { - udata->key.offset[i] = lt_key->offset[i]; - udata->key.size[i] = lt_key->size[i]; - assert(lt_key->size[i] > 0); + udata->key.offset[i] = lt_key->offset[i]; + udata->key.size[i] = lt_key->size[i]; + assert(lt_key->size[i] > 0); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_insert + * Function: H5F_istore_insert * - * Purpose: This function is called when the B-tree insert engine finds - * the node to use to insert new data. The UDATA argument - * points to a struct that describes the logical addresses being - * added to the file. This function allocates space for the - * data and returns information through UDATA describing a - * file chunk to receive (part of) the data. + * Purpose: This function is called when the B-tree insert engine finds + * the node to use to insert new data. The UDATA argument + * points to a struct that describes the logical addresses being + * added to the file. This function allocates space for the + * data and returns information through UDATA describing a + * file chunk to receive (part of) the data. * - * The LT_KEY is always the key describing the chunk of file - * memory at address ADDR. On entry, UDATA describes the logical - * addresses for which storage is being requested (through the - * `offset' and `size' fields). On return, UDATA describes the - * logical addresses contained in a chunk on disk. + * The LT_KEY is always the key describing the chunk of file + * memory at address ADDR. On entry, UDATA describes the logical + * addresses for which storage is being requested (through the + * `offset' and `size' fields). On return, UDATA describes the + * logical addresses contained in a chunk on disk. * - * Return: Success: An insertion command for the caller, one of - * the H5B_INS_* constants. The address of the - * new chunk is returned through the NEW_NODE - * argument. + * Return: Success: An insertion command for the caller, one of + * the H5B_INS_* constants. The address of the + * new chunk is returned through the NEW_NODE + * argument. * - * Failure: H5B_INS_ERROR + * Failure: H5B_INS_ERROR * - * Programmer: Robb Matzke - * Thursday, October 9, 1997 + * Programmer: Robb Matzke + * Thursday, October 9, 1997 * * Modifications: * @@ -477,18 +482,18 @@ H5F_istore_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, */ static H5B_ins_t H5F_istore_insert(H5F_t *f, const haddr_t *addr, - void *_lt_key, hbool_t *lt_key_changed, - void *_md_key, void *_udata, - void *_rt_key, hbool_t *rt_key_changed, - haddr_t *new_node /*out */ ) + void *_lt_key, hbool_t *lt_key_changed, + void *_md_key, void *_udata, + void *_rt_key, hbool_t *rt_key_changed, + haddr_t *new_node/*out*/) { - H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; - H5F_istore_key_t *md_key = (H5F_istore_key_t *) _md_key; - H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; - H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; - intn i, cmp; - H5B_ins_t ret_value = H5B_INS_ERROR; - size_t nbytes; + H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; + H5F_istore_key_t *md_key = (H5F_istore_key_t *) _md_key; + H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; + H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; + intn i, cmp; + H5B_ins_t ret_value = H5B_INS_ERROR; + size_t nbytes; FUNC_ENTER(H5F_istore_insert, H5B_INS_ERROR); @@ -507,86 +512,89 @@ H5F_istore_insert(H5F_t *f, const haddr_t *addr, assert(cmp <= 0); if (cmp < 0) { - /* Negative indices not supported yet */ - assert("HDF5 INTERNAL ERROR -- see rpm" && 0); - HRETURN_ERROR(H5E_STORAGE, H5E_UNSUPPORTED, H5B_INS_ERROR, "internal error"); + /* Negative indices not supported yet */ + assert("HDF5 INTERNAL ERROR -- see rpm" && 0); + HRETURN_ERROR(H5E_STORAGE, H5E_UNSUPPORTED, H5B_INS_ERROR, + "internal error"); } else if (H5V_hyper_eq(udata->mesg.ndims, - udata->key.offset, udata->key.size, - lt_key->offset, lt_key->size)) { - /* - * Already exists. Just return the info. - */ - udata->addr = *addr; - udata->key.file_number = lt_key->file_number; - ret_value = H5B_INS_NOOP; + udata->key.offset, udata->key.size, + lt_key->offset, lt_key->size)) { + /* + * Already exists. Just return the info. + */ + udata->addr = *addr; + udata->key.file_number = lt_key->file_number; + ret_value = H5B_INS_NOOP; } else if (H5V_hyper_disjointp(udata->mesg.ndims, - lt_key->offset, lt_key->size, - udata->key.offset, udata->key.size)) { - assert(H5V_hyper_disjointp(udata->mesg.ndims, - rt_key->offset, rt_key->size, - udata->key.offset, udata->key.size)); - - /* - * Split this node, inserting the new new node to the right of the - * current node. The MD_KEY is where the split occurs. - */ - md_key->file_number = udata->key.file_number; - for (i = 0, nbytes = 1; i < udata->mesg.ndims; i++) { - assert(0 == udata->key.offset[i] % udata->mesg.dim[i]); - assert(udata->key.size[i] == udata->mesg.dim[i]); - md_key->offset[i] = udata->key.offset[i]; - md_key->size[i] = udata->key.size[i]; - nbytes *= udata->key.size[i]; - } - - /* - * Allocate storage for the new chunk - */ - if (H5MF_alloc(f, H5MF_RAW, nbytes, new_node /*out */ ) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, H5B_INS_ERROR, - "file allocation failed"); - } - udata->addr = *new_node; - udata->key.file_number = 0; - ret_value = H5B_INS_RIGHT; + lt_key->offset, lt_key->size, + udata->key.offset, udata->key.size)) { + assert(H5V_hyper_disjointp(udata->mesg.ndims, + rt_key->offset, rt_key->size, + udata->key.offset, udata->key.size)); + + /* + * Split this node, inserting the new new node to the right of the + * current node. The MD_KEY is where the split occurs. + */ + md_key->file_number = udata->key.file_number; + for (i = 0, nbytes = 1; i < udata->mesg.ndims; i++) { + assert(0 == udata->key.offset[i] % udata->mesg.dim[i]); + assert(udata->key.size[i] == udata->mesg.dim[i]); + md_key->offset[i] = udata->key.offset[i]; + md_key->size[i] = udata->key.size[i]; + nbytes *= udata->key.size[i]; + } + + /* + * Allocate storage for the new chunk + */ + if (H5MF_alloc(f, H5MF_RAW, nbytes, new_node /*out */ ) < 0) { + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, H5B_INS_ERROR, + "file allocation failed"); + } + udata->addr = *new_node; + udata->key.file_number = 0; + ret_value = H5B_INS_RIGHT; } else { - assert("HDF5 INTERNAL ERROR -- see rpm" && 0); - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, H5B_INS_ERROR, "internal error"); + assert("HDF5 INTERNAL ERROR -- see rpm" && 0); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, H5B_INS_ERROR, + "internal error"); } FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_copy_hyperslab + * Function: H5F_istore_copy_hyperslab * - * Purpose: Reads or writes a hyperslab to disk depending on whether OP - * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab - * storage is described with ISTORE and exists in file F. The - * file hyperslab begins at location OFFSET_F[] (an N-dimensional - * point in the domain in terms of elements) in the file and - * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[] - * elements. The dimensionality of memory is assumed to be the - * same as the file and the total size of the multi-dimensional - * memory buffer is SIZE_M[]. + * Purpose: Reads or writes a hyperslab to disk depending on whether OP + * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab + * storage is described with ISTORE and exists in file F. The + * file hyperslab begins at location OFFSET_F[] (an N-dimensional + * point in the domain in terms of elements) in the file and + * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[] + * elements. The dimensionality of memory is assumed to be the + * same as the file and the total size of the multi-dimensional + * memory buffer is SIZE_M[]. * - * The slowest varying dimension is always listed first in the - * various offset and size arrays. + * The slowest varying dimension is always listed first in the + * various offset and size arrays. * - * A `chunk' is a hyperslab of the disk array which is stored - * contiguously. I/O occurs in units of chunks where the size of - * a chunk is determined by the alignment constraints specified - * in ISTORE. + * A `chunk' is a hyperslab of the disk array which is stored + * contiguously. I/O occurs in units of chunks where the size of + * a chunk is determined by the alignment constraints specified + * in ISTORE. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Friday, October 17, 1997 + * Programmer: Robb Matzke + * Friday, October 17, 1997 * * Modifications: * @@ -594,22 +602,22 @@ H5F_istore_insert(H5F_t *f, const haddr_t *addr, */ static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, - const size_t offset_f[], const size_t size[], - const size_t offset_m[], const size_t size_m[], - const void *buf) + const size_t offset_f[], const size_t size[], + const size_t offset_m[], const size_t size_m[], + void *buf/*in or out*/) { - intn i, carry; - size_t idx_cur[H5O_LAYOUT_NDIMS]; - size_t idx_min[H5O_LAYOUT_NDIMS]; - size_t idx_max[H5O_LAYOUT_NDIMS]; - size_t sub_size[H5O_LAYOUT_NDIMS]; - size_t offset_wrt_chunk[H5O_LAYOUT_NDIMS]; - size_t sub_offset_m[H5O_LAYOUT_NDIMS]; - size_t chunk_size; - uint8 *chunk = NULL; - H5F_istore_ud1_t udata; - herr_t status; - herr_t ret_value = FAIL; + intn i, carry; + size_t idx_cur[H5O_LAYOUT_NDIMS]; + size_t idx_min[H5O_LAYOUT_NDIMS]; + size_t idx_max[H5O_LAYOUT_NDIMS]; + size_t sub_size[H5O_LAYOUT_NDIMS]; + size_t offset_wrt_chunk[H5O_LAYOUT_NDIMS]; + size_t sub_offset_m[H5O_LAYOUT_NDIMS]; + size_t chunk_size; + uint8 *chunk = NULL; + H5F_istore_ud1_t udata; + herr_t status; + herr_t ret_value = FAIL; FUNC_ENTER(H5F_istore_copy_hyperslab, FAIL); @@ -623,24 +631,64 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, assert(size_m); assert(buf); #ifndef NDEBUG - for (i = 0; i < layout->ndims; i++) { - assert(size_m[i] > 0); /*destination must exist */ - /*hyperslab must fit in BUF */ - assert((offset_m ? offset_m[i] : 0) + size[i] <= size_m[i]); - assert(layout->dim[i] > 0); + for (i=0; indims; i++) { + assert(size_m[i] > 0); /*destination must exist */ + /*hyperslab must fit in BUF */ + assert((offset_m?offset_m[i]:0) + size[i] <= size_m[i]); + assert(layout->dim[i] > 0); } #endif - /* Initialize indices */ - for (i = 0; i < layout->ndims; i++) { - idx_min[i] = (offset_f ? offset_f[i] : 0) / layout->dim[i]; - idx_max[i] = ((offset_f ? offset_f[i] : 0) + size[i] - 1) / layout->dim[i] + 1; - idx_cur[i] = idx_min[i]; + /* + * As a special case of H5F_ISTORE_READ, if the source is aligned on + * a chunk boundary and is the same size as a chunk, and the destination + * is the same size as a chunk, then instead of reading into a temporary + * buffer and then into the destination, we read directly into the + * destination. + */ + if (H5F_ISTORE_READ==op) { + for (i=0, chunk_size=1; indims; i++) { + if (offset_f[i] % layout->dim[i]) break; /*src not aligned*/ + if (size[i]!=layout->dim[i]) break; /*src not a chunk*/ + if (size_m[i]!=layout->dim[i]) break; /*dst not a chunk*/ + udata.key.offset[i] = offset_f[i]; + udata.key.size[i] = layout->dim[i]; + chunk_size *= layout->dim[i]; + } + + if (i==layout->ndims) { + udata.mesg = *layout; + H5F_addr_undef (&(udata.addr)); + udata.key.file_number = 0; + status = H5B_find (f, H5B_ISTORE, &(layout->addr), &udata); + if (status>=0 && H5F_addr_defined (&(udata.addr))) { + assert (0==udata.key.file_number); + if (H5F_block_read (f, &(udata.addr), chunk_size, buf)<0) { + HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, + "unable to read raw storage chunk"); + } + } else { + HDmemset (buf, 0, chunk_size); + } + HRETURN (SUCCEED); + } + } + + /* + * This is the general case. We set up multi-dimensional counters + * (idx_min, idx_max, and idx_cur) and loop through the chunks copying + * each chunk into a temporary buffer, compressing or decompressing, and + * then copying it to it's destination. + */ + for (i=0; indims; i++) { + idx_min[i] = (offset_f?offset_f[i]:0) / layout->dim[i]; + idx_max[i] = ((offset_f?offset_f[i]:0) + size[i]-1) / layout->dim[i]+1; + idx_cur[i] = idx_min[i]; } /* Allocate buffers */ - for (i = 0, chunk_size = 1; i < layout->ndims; i++) { - chunk_size *= layout->dim[i]; + for (i=0, chunk_size=1; indims; i++) { + chunk_size *= layout->dim[i]; } chunk = H5MM_xmalloc(chunk_size); @@ -650,80 +698,77 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, /* Loop over all chunks */ while (1) { - /* Read/Write chunk or create it if it doesn't exist */ - udata.mesg.ndims = layout->ndims; - H5F_addr_undef(&(udata.addr)); - udata.key.file_number = 0; - - for (i = 0; i < layout->ndims; i++) { - - /* The location and size of the chunk being accessed */ - udata.key.offset[i] = idx_cur[i] * layout->dim[i]; - udata.key.size[i] = layout->dim[i]; - - /* The offset and size wrt the chunk */ - offset_wrt_chunk[i] = MAX((offset_f ? offset_f[i] : 0), - udata.key.offset[i]) - - udata.key.offset[i]; - sub_size[i] = MIN((idx_cur[i] + 1) * layout->dim[i], - (offset_f ? offset_f[i] : 0) + size[i]) - - (udata.key.offset[i] + offset_wrt_chunk[i]); - - /* Offset into mem buffer */ - sub_offset_m[i] = udata.key.offset[i] + offset_wrt_chunk[i] + - (offset_m ? offset_m[i] : 0) - - (offset_f ? offset_f[i] : 0); - } - - if (H5F_ISTORE_WRITE == op) { - status = H5B_insert(f, H5B_ISTORE, &(layout->addr), &udata); - assert(status >= 0); - } else { - status = H5B_find(f, H5B_ISTORE, &(layout->addr), &udata); - } - - /* - * If the operation is reading from the disk or if we are writing a - * partial chunk then load the chunk from disk. - */ - if (H5F_ISTORE_READ == op || - !H5V_vector_zerop(layout->ndims, offset_wrt_chunk) || - !H5V_vector_eq(layout->ndims, sub_size, udata.key.size)) { - if (status >= 0 && H5F_addr_defined(&(udata.addr))) { - assert(0 == udata.key.file_number); - if (H5F_block_read(f, &(udata.addr), chunk_size, chunk) < 0) { - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, - "unable to read raw storage chunk"); - } - } else { - HDmemset(chunk, 0, chunk_size); - } - } - /* Transfer data to/from the chunk */ - if (H5F_ISTORE_WRITE == op) { - H5V_hyper_copy(layout->ndims, sub_size, - udata.key.size, offset_wrt_chunk, chunk, - size_m, sub_offset_m, buf); - assert(0 == udata.key.file_number); - if (H5F_block_write(f, &(udata.addr), chunk_size, chunk) < 0) { - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "unable to write raw storage chunk"); - } - } else { - H5V_hyper_copy(layout->ndims, sub_size, - size_m, sub_offset_m, (void *)buf, - udata.key.size, offset_wrt_chunk, chunk); - } - - /* Increment indices */ - for (i = layout->ndims - 1, carry = 1; i >= 0 && carry; --i) { - if (++idx_cur[i] >= idx_max[i]) - idx_cur[i] = idx_min[i]; - else - carry = 0; - } - if (carry) - break; + /* Read/Write chunk or create it if it doesn't exist */ + udata.mesg.ndims = layout->ndims; + H5F_addr_undef(&(udata.addr)); + udata.key.file_number = 0; + + for (i=0; indims; i++) { + + /* The location and size of the chunk being accessed */ + udata.key.offset[i] = idx_cur[i] * layout->dim[i]; + udata.key.size[i] = layout->dim[i]; + + /* The offset and size wrt the chunk */ + offset_wrt_chunk[i] = MAX((offset_f ? offset_f[i] : 0), + udata.key.offset[i]) - + udata.key.offset[i]; + sub_size[i] = MIN((idx_cur[i] + 1) * layout->dim[i], + (offset_f ? offset_f[i] : 0) + size[i]) - + (udata.key.offset[i] + offset_wrt_chunk[i]); + + /* Offset into mem buffer */ + sub_offset_m[i] = udata.key.offset[i] + offset_wrt_chunk[i] + + (offset_m ? offset_m[i] : 0) - + (offset_f ? offset_f[i] : 0); + } + + if (H5F_ISTORE_WRITE == op) { + status = H5B_insert(f, H5B_ISTORE, &(layout->addr), &udata); + assert(status >= 0); + } else { + status = H5B_find(f, H5B_ISTORE, &(layout->addr), &udata); + } + + /* + * If the operation is reading from the disk or if we are writing a + * partial chunk then load the chunk from disk. + */ + if (H5F_ISTORE_READ == op || + !H5V_vector_zerop(layout->ndims, offset_wrt_chunk) || + !H5V_vector_eq(layout->ndims, sub_size, udata.key.size)) { + if (status>=0 && H5F_addr_defined(&(udata.addr))) { + assert(0==udata.key.file_number); + if (H5F_block_read(f, &(udata.addr), chunk_size, chunk) < 0) { + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, + "unable to read raw storage chunk"); + } + } else { + HDmemset(chunk, 0, chunk_size); + } + } + /* Transfer data to/from the chunk */ + if (H5F_ISTORE_WRITE==op) { + H5V_hyper_copy(layout->ndims, sub_size, + udata.key.size, offset_wrt_chunk, chunk, + size_m, sub_offset_m, buf); + assert(0 == udata.key.file_number); + if (H5F_block_write(f, &(udata.addr), chunk_size, chunk) < 0) { + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "unable to write raw storage chunk"); + } + } else { + H5V_hyper_copy(layout->ndims, sub_size, + size_m, sub_offset_m, (void *)buf, + udata.key.size, offset_wrt_chunk, chunk); + } + + /* Increment indices */ + for (i=layout->ndims-1, carry=1; i>=0 && carry; --i) { + if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i]; + else carry = 0; + } + if (carry) break; } ret_value = SUCCEED; @@ -731,19 +776,20 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, chunk = H5MM_xfree(chunk); FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_read + * Function: H5F_istore_read * - * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw - * storage array. + * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw + * storage array. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 15, 1997 + * Programmer: Robb Matzke + * Wednesday, October 15, 1997 * * Modifications: * @@ -751,7 +797,7 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, */ herr_t H5F_istore_read(H5F_t *f, const H5O_layout_t *layout, - const size_t offset[], const size_t size[], void *buf) + const size_t offset[], const size_t size[], void *buf) { FUNC_ENTER(H5F_istore_read, FAIL); @@ -763,25 +809,26 @@ H5F_istore_read(H5F_t *f, const H5O_layout_t *layout, assert(buf); if (H5F_istore_copy_hyperslab(f, layout, H5F_ISTORE_READ, - offset, size, H5V_ZERO, size, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "hyperslab output failure"); + offset, size, H5V_ZERO, size, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "hyperslab output failure"); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_write + * Function: H5F_istore_write * - * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw - * storage array. + * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw + * storage array. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 15, 1997 + * Programmer: Robb Matzke + * Wednesday, October 15, 1997 * * Modifications: * @@ -789,8 +836,8 @@ H5F_istore_read(H5F_t *f, const H5O_layout_t *layout, */ herr_t H5F_istore_write(H5F_t *f, const H5O_layout_t *layout, - const size_t offset[], const size_t size[], - const void *buf) + const size_t offset[], const size_t size[], + const void *buf) { FUNC_ENTER(H5F_istore_write, FAIL); @@ -802,30 +849,32 @@ H5F_istore_write(H5F_t *f, const H5O_layout_t *layout, assert(buf); if (H5F_istore_copy_hyperslab(f, layout, H5F_ISTORE_WRITE, - offset, size, H5V_ZERO, size, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "hyperslab output failure"); + offset, size, H5V_ZERO, size, + (void*)buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "hyperslab output failure"); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_create + * Function: H5F_istore_create * - * Purpose: Creates a new indexed-storage B-tree and initializes the - * istore struct with information about the storage. The - * struct should be immediately written to the object header. + * Purpose: Creates a new indexed-storage B-tree and initializes the + * istore struct with information about the storage. The + * struct should be immediately written to the object header. * - * This function must be called before passing ISTORE to any of - * the other indexed storage functions! + * This function must be called before passing ISTORE to any of + * the other indexed storage functions! * - * Return: Success: SUCCEED with the ISTORE argument initialized - * and ready to write to an object header. + * Return: Success: SUCCEED with the ISTORE argument initialized + * and ready to write to an object header. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, October 21, 1997 + * Programmer: Robb Matzke + * Tuesday, October 21, 1997 * * Modifications: * @@ -834,9 +883,9 @@ H5F_istore_write(H5F_t *f, const H5O_layout_t *layout, herr_t H5F_istore_create(H5F_t *f, H5O_layout_t *layout /*out */ ) { - H5F_istore_ud1_t udata; + H5F_istore_ud1_t udata; #ifndef NDEBUG - int i; + int i; #endif FUNC_ENTER(H5F_istore_create, FAIL); @@ -847,13 +896,14 @@ H5F_istore_create(H5F_t *f, H5O_layout_t *layout /*out */ ) assert(layout->ndims > 0 && layout->ndims <= H5O_LAYOUT_NDIMS); #ifndef NDEBUG for (i = 0; i < layout->ndims; i++) { - assert(layout->dim[i] > 0); + assert(layout->dim[i] > 0); } #endif udata.mesg.ndims = layout->ndims; if (H5B_create(f, H5B_ISTORE, &udata, &(layout->addr) /*out */ ) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't create B-tree"); + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't create B-tree"); } + FUNC_LEAVE(SUCCEED); } diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index f678ef7..14a471a 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -22,9 +22,9 @@ #include #include /*for the H5F_t type */ #include /*symbol tables */ -#include /*for the H5T_t type */ -#include /*for the H5S_t type */ #include /*object Headers */ +#include /*for the H5S_t type */ +#include /*for the H5T_t type */ /* * Feature: Define H5D_DEBUG on the compiler command line if you want to @@ -51,8 +51,9 @@ typedef struct H5D_create_t { /* Dataset transfer property list */ typedef struct H5D_xfer_t { size_t buf_size; /*max temp buffer size */ - void *tconv; /*type conversion buffer or null */ - void *bkg; /*background buffer or null */ + void *tconv_buf; /*type conversion buffer or null */ + void *bkg_buf; /*background buffer or null */ + H5T_bkg_t need_bkg; /*type of background buffer needed */ } H5D_xfer_t; typedef struct H5D_t H5D_t; diff --git a/src/H5Fistore.c b/src/H5Fistore.c index 25b81b2..c75a3b7 100644 --- a/src/H5Fistore.c +++ b/src/H5Fistore.c @@ -1,9 +1,9 @@ /* * Copyright (C) 1997 NCSA - * All rights reserved. + * All rights reserved. * * Programmer: Robb Matzke - * Wednesday, October 8, 1997 + * Wednesday, October 8, 1997 */ #include #include @@ -15,48 +15,48 @@ #include typedef enum H5F_isop_t { - H5F_ISTORE_READ, /*read from file to memory */ - H5F_ISTORE_WRITE /*write from memory to file */ + H5F_ISTORE_READ, /*read from file to memory */ + H5F_ISTORE_WRITE /*write from memory to file */ } H5F_isop_t; /* Does the array domain include negative indices? */ #undef H5F_ISTORE_NEGATIVE_DOMAIN -#define PABLO_MASK H5F_istore_mask +#define PABLO_MASK H5F_istore_mask /* Interface initialization */ -static hbool_t interface_initialize_g = FALSE; +static hbool_t interface_initialize_g = FALSE; #define INTERFACE_INIT NULL /* PRIVATE PROTOTYPES */ -static size_t H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata); -static herr_t H5F_istore_new_node(H5F_t *f, H5B_ins_t, void *_lt_key, - void *_udata, void *_rt_key, haddr_t *); -static intn H5F_istore_cmp2(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static intn H5F_istore_cmp3(H5F_t *f, void *_lt_key, void *_udata, - void *_rt_key); -static herr_t H5F_istore_found(H5F_t *f, const haddr_t *addr, - const void *_lt_key, void *_udata, - const void *_rt_key); -static H5B_ins_t H5F_istore_insert(H5F_t *f, const haddr_t *addr, - void *_lt_key, hbool_t *lt_key_changed, - void *_md_key, void *_udata, - void *_rt_key, hbool_t *rt_key_changed, - haddr_t *); -static herr_t H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static herr_t H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, - void *_key); -static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, - H5F_isop_t op, - const size_t offset_f[], - const size_t size[], - const size_t offset_m[], - const size_t size_m[], const void *buf); +static size_t H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata); +static herr_t H5F_istore_new_node(H5F_t *f, H5B_ins_t, void *_lt_key, + void *_udata, void *_rt_key, haddr_t *); +static intn H5F_istore_cmp2(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static intn H5F_istore_cmp3(H5F_t *f, void *_lt_key, void *_udata, + void *_rt_key); +static herr_t H5F_istore_found(H5F_t *f, const haddr_t *addr, + const void *_lt_key, void *_udata, + const void *_rt_key); +static H5B_ins_t H5F_istore_insert(H5F_t *f, const haddr_t *addr, + void *_lt_key, hbool_t *lt_key_changed, + void *_md_key, void *_udata, + void *_rt_key, hbool_t *rt_key_changed, + haddr_t *new_node/*out*/); +static herr_t H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static herr_t H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, + void *_key); +static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, + H5F_isop_t op, const size_t offset_f[], + const size_t size[], + const size_t offset_m[], + const size_t size_m[], + void *buf); /* - * B-tree key. A key contains the minimum logical N-dimensional address and + * B-tree key. A key contains the minimum logical N-dimensional address and * the logical size of the chunk to which this key refers. The * fastest-varying dimension is assumed to reference individual bytes of the * array, so a 100-element 1-d array of 4-byte integers would really be a 2-d @@ -70,50 +70,49 @@ static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t * * The storage file address is part of the B-tree and not part of the key. */ typedef struct H5F_istore_key_t { - uintn file_number; /*external file number */ - size_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start */ - size_t size[H5O_LAYOUT_NDIMS]; /*logical chunk size */ + uintn file_number; /*external file number */ + size_t offset[H5O_LAYOUT_NDIMS]; /*logical offset to start*/ + size_t size[H5O_LAYOUT_NDIMS]; /*logical chunk size */ } H5F_istore_key_t; typedef struct H5F_istore_ud1_t { - H5F_istore_key_t key; /*key values */ - haddr_t addr; /*file address of chunk */ - H5O_layout_t mesg; /*layout message */ + H5F_istore_key_t key; /*key values */ + haddr_t addr; /*file address of chunk */ + H5O_layout_t mesg; /*layout message */ } H5F_istore_ud1_t; /* inherits B-tree like properties from H5B */ -H5B_class_t H5B_ISTORE[1] = -{ - { - H5B_ISTORE_ID, /*id */ - sizeof(H5F_istore_key_t), /*sizeof_nkey */ - H5F_istore_sizeof_rkey, /*get_sizeof_rkey */ - H5F_istore_new_node, /*new */ - H5F_istore_cmp2, /*cmp2 */ - H5F_istore_cmp3, /*cmp3 */ - H5F_istore_found, /*found */ - H5F_istore_insert, /*insert */ - FALSE, /*follow min branch? */ - FALSE, /*follow max branch? */ - NULL, /*list */ - H5F_istore_decode_key, /*decode */ - H5F_istore_encode_key, /*encode */ - }}; +H5B_class_t H5B_ISTORE[1] = {{ + H5B_ISTORE_ID, /*id */ + sizeof(H5F_istore_key_t), /*sizeof_nkey */ + H5F_istore_sizeof_rkey, /*get_sizeof_rkey */ + H5F_istore_new_node, /*new */ + H5F_istore_cmp2, /*cmp2 */ + H5F_istore_cmp3, /*cmp3 */ + H5F_istore_found, /*found */ + H5F_istore_insert, /*insert */ + FALSE, /*follow min branch? */ + FALSE, /*follow max branch? */ + NULL, /*list */ + H5F_istore_decode_key, /*decode */ + H5F_istore_encode_key, /*encode */ +}}; + /*------------------------------------------------------------------------- - * Function: H5F_istore_sizeof_rkey + * Function: H5F_istore_sizeof_rkey * - * Purpose: Returns the size of a raw key for the specified UDATA. The - * size of the key is dependent on the number of dimensions for - * the object to which this B-tree points. The dimensionality - * of the UDATA is the only portion that's referenced here. + * Purpose: Returns the size of a raw key for the specified UDATA. The + * size of the key is dependent on the number of dimensions for + * the object to which this B-tree points. The dimensionality + * of the UDATA is the only portion that's referenced here. * - * Return: Success: Size of raw key in bytes. + * Return: Success: Size of raw key in bytes. * - * Failure: abort() + * Failure: abort() * - * Programmer: Robb Matzke - * Wednesday, October 8, 1997 + * Programmer: Robb Matzke + * Wednesday, October 8, 1997 * * Modifications: * @@ -123,29 +122,30 @@ static size_t H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata) { const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *) _udata; - size_t nbytes; + size_t nbytes; assert(udata); assert(udata->mesg.ndims > 0 && udata->mesg.ndims <= H5O_LAYOUT_NDIMS); - nbytes = 4 + /*external file number */ - udata->mesg.ndims * 4 + /*dimension indices */ - udata->mesg.ndims * 4; /*dimension sizes */ + nbytes = 4 + /*external file number */ + udata->mesg.ndims * 4 + /*dimension indices */ + udata->mesg.ndims * 4; /*dimension sizes */ return nbytes; } + /*------------------------------------------------------------------------- - * Function: H5F_istore_decode_key + * Function: H5F_istore_decode_key * - * Purpose: Decodes a raw key into a native key for the B-tree + * Purpose: Decodes a raw key into a native key for the B-tree * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Friday, October 10, 1997 + * Programmer: Robb Matzke + * Friday, October 10, 1997 * * Modifications: * @@ -154,9 +154,9 @@ H5F_istore_sizeof_rkey(H5F_t *f, const void *_udata) static herr_t H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) { - H5F_istore_key_t *key = (H5F_istore_key_t *) _key; - intn i; - intn ndims = (intn)(bt->sizeof_rkey / 8); + H5F_istore_key_t *key = (H5F_istore_key_t *) _key; + intn i; + intn ndims = (intn)(bt->sizeof_rkey/8); FUNC_ENTER(H5F_istore_decode_key, FAIL); @@ -171,25 +171,25 @@ H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) UINT32DECODE(raw, key->file_number); assert(0 == key->file_number); for (i = 0; i < ndims; i++) { - UINT32DECODE(raw, key->offset[i]); - UINT32DECODE(raw, key->size[i]); + UINT32DECODE(raw, key->offset[i]); + UINT32DECODE(raw, key->size[i]); } FUNC_LEAVE(SUCCEED); - } + /*------------------------------------------------------------------------- - * Function: H5F_istore_encode_key + * Function: H5F_istore_encode_key * - * Purpose: Encode a key from native format to raw format. + * Purpose: Encode a key from native format to raw format. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Friday, October 10, 1997 + * Programmer: Robb Matzke + * Friday, October 10, 1997 * * Modifications: * @@ -198,9 +198,9 @@ H5F_istore_decode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) static herr_t H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) { - H5F_istore_key_t *key = (H5F_istore_key_t *) _key; - intn ndims = (intn)(bt->sizeof_rkey / 8); - intn i; + H5F_istore_key_t *key = (H5F_istore_key_t *) _key; + intn ndims = (intn)(bt->sizeof_rkey / 8); + intn i; FUNC_ENTER(H5F_istore_encode_key, FAIL); @@ -215,29 +215,30 @@ H5F_istore_encode_key(H5F_t *f, H5B_t *bt, uint8 *raw, void *_key) UINT32ENCODE(raw, key->file_number); assert(0 == key->file_number); for (i = 0; i < ndims; i++) { - UINT32ENCODE(raw, key->offset[i]); - UINT32ENCODE(raw, key->size[i]); + UINT32ENCODE(raw, key->offset[i]); + UINT32ENCODE(raw, key->size[i]); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_cmp2 + * Function: H5F_istore_cmp2 * - * Purpose: Compares two keys sort of like strcmp(). The UDATA pointer - * is only to supply extra information not carried in the keys - * (in this case, the dimensionality) and is not compared - * against the keys. + * Purpose: Compares two keys sort of like strcmp(). The UDATA pointer + * is only to supply extra information not carried in the keys + * (in this case, the dimensionality) and is not compared + * against the keys. * - * Return: Success: -1 if LT_KEY is less than RT_KEY; - * 1 if LT_KEY is greater than RT_KEY; - * 0 if LT_KEY and RT_KEY are equal. + * Return: Success: -1 if LT_KEY is less than RT_KEY; + * 1 if LT_KEY is greater than RT_KEY; + * 0 if LT_KEY and RT_KEY are equal. * - * Failure: FAIL (same as LT_KEYmesg.ndims > 0 && udata->mesg.ndims <= H5O_LAYOUT_NDIMS); if (H5V_vector_lt(udata->mesg.ndims, udata->key.offset, lt_key->offset)) { - cmp = -1; + cmp = -1; } else if (H5V_vector_ge(udata->mesg.ndims, udata->key.offset, - rt_key->offset)) { - cmp = 1; + rt_key->offset)) { + cmp = 1; } FUNC_LEAVE(cmp); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_new_node + * Function: H5F_istore_new_node * - * Purpose: Adds a new entry to an i-storage B-tree. We can assume that - * the domain represented by UDATA doesn't intersect the domain - * already represented by the B-tree. + * Purpose: Adds a new entry to an i-storage B-tree. We can assume that + * the domain represented by UDATA doesn't intersect the domain + * already represented by the B-tree. * - * Return: Success: SUCCEED. The address of leaf is returned - * through the ADDR argument. It is also added - * to the UDATA. + * Return: Success: SUCCEED. The address of leaf is returned + * through the ADDR argument. It is also added + * to the UDATA. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, October 14, 1997 + * Programmer: Robb Matzke + * Tuesday, October 14, 1997 * * Modifications: * @@ -339,14 +342,14 @@ H5F_istore_cmp3(H5F_t *f, void *_lt_key, void *_udata, void *_rt_key) */ static herr_t H5F_istore_new_node(H5F_t *f, H5B_ins_t op, - void *_lt_key, void *_udata, void *_rt_key, - haddr_t *addr /*out */ ) + void *_lt_key, void *_udata, void *_rt_key, + haddr_t *addr/*out*/) { - H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; - H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; - H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; - size_t nbytes; - intn i; + H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; + H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; + H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; + size_t nbytes; + intn i; FUNC_ENTER(H5F_istore_new_node, FAIL); @@ -362,55 +365,56 @@ H5F_istore_new_node(H5F_t *f, H5B_ins_t op, nbytes = H5V_vector_reduce_product(udata->mesg.ndims, udata->key.size); assert(nbytes > 0); if (H5MF_alloc(f, H5MF_RAW, nbytes, addr /*out */ ) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, - "couldn't allocate new file storage"); + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, + "couldn't allocate new file storage"); } udata->addr = *addr; udata->key.file_number = 0; lt_key->file_number = udata->key.file_number; if (H5B_INS_LEFT != op) - rt_key->file_number = 0; + rt_key->file_number = 0; /* Initialize the key(s) */ for (i = 0; i < udata->mesg.ndims; i++) { - /* - * The left key describes the storage of the UDATA chunk being inserted - * into the tree. - */ - assert(udata->key.size[i] > 0); - lt_key->offset[i] = udata->key.offset[i]; - lt_key->size[i] = udata->key.size[i]; - - /* - * The right key might already be present. If not, then add - * a zero-width chunk. - */ - if (H5B_INS_LEFT != op) { - rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i]; - rt_key->size[i] = 0; - } + /* + * The left key describes the storage of the UDATA chunk being + * inserted into the tree. + */ + assert(udata->key.size[i] > 0); + lt_key->offset[i] = udata->key.offset[i]; + lt_key->size[i] = udata->key.size[i]; + + /* + * The right key might already be present. If not, then add + * a zero-width chunk. + */ + if (H5B_INS_LEFT != op) { + rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i]; + rt_key->size[i] = 0; + } } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_found + * Function: H5F_istore_found * - * Purpose: This function is called when the B-tree search engine has - * found the leaf entry that points to a chunk of storage that - * contains the beginning of the logical address space - * represented by UDATA. The LT_KEY is the left key (the one - * that describes the chunk) and RT_KEY is the right key (the - * one that describes the next or last chunk). + * Purpose: This function is called when the B-tree search engine has + * found the leaf entry that points to a chunk of storage that + * contains the beginning of the logical address space + * represented by UDATA. The LT_KEY is the left key (the one + * that describes the chunk) and RT_KEY is the right key (the + * one that describes the next or last chunk). * - * Return: Success: SUCCEED with information about the chunk - * returned through the UDATA argument. + * Return: Success: SUCCEED with information about the chunk + * returned through the UDATA argument. * - * Failure: FAIL if not found. + * Failure: FAIL if not found. * - * Programmer: Robb Matzke - * Thursday, October 9, 1997 + * Programmer: Robb Matzke + * Thursday, October 9, 1997 * * Modifications: * @@ -418,11 +422,11 @@ H5F_istore_new_node(H5F_t *f, H5B_ins_t op, */ static herr_t H5F_istore_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, - void *_udata, const void *_rt_key) + void *_udata, const void *_rt_key) { - H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; + H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *) _lt_key; - int i; + int i; FUNC_ENTER(H5F_istore_found, FAIL); @@ -437,39 +441,40 @@ H5F_istore_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, udata->key.file_number = lt_key->file_number; assert(0 == lt_key->file_number); for (i = 0; i < udata->mesg.ndims; i++) { - udata->key.offset[i] = lt_key->offset[i]; - udata->key.size[i] = lt_key->size[i]; - assert(lt_key->size[i] > 0); + udata->key.offset[i] = lt_key->offset[i]; + udata->key.size[i] = lt_key->size[i]; + assert(lt_key->size[i] > 0); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_insert + * Function: H5F_istore_insert * - * Purpose: This function is called when the B-tree insert engine finds - * the node to use to insert new data. The UDATA argument - * points to a struct that describes the logical addresses being - * added to the file. This function allocates space for the - * data and returns information through UDATA describing a - * file chunk to receive (part of) the data. + * Purpose: This function is called when the B-tree insert engine finds + * the node to use to insert new data. The UDATA argument + * points to a struct that describes the logical addresses being + * added to the file. This function allocates space for the + * data and returns information through UDATA describing a + * file chunk to receive (part of) the data. * - * The LT_KEY is always the key describing the chunk of file - * memory at address ADDR. On entry, UDATA describes the logical - * addresses for which storage is being requested (through the - * `offset' and `size' fields). On return, UDATA describes the - * logical addresses contained in a chunk on disk. + * The LT_KEY is always the key describing the chunk of file + * memory at address ADDR. On entry, UDATA describes the logical + * addresses for which storage is being requested (through the + * `offset' and `size' fields). On return, UDATA describes the + * logical addresses contained in a chunk on disk. * - * Return: Success: An insertion command for the caller, one of - * the H5B_INS_* constants. The address of the - * new chunk is returned through the NEW_NODE - * argument. + * Return: Success: An insertion command for the caller, one of + * the H5B_INS_* constants. The address of the + * new chunk is returned through the NEW_NODE + * argument. * - * Failure: H5B_INS_ERROR + * Failure: H5B_INS_ERROR * - * Programmer: Robb Matzke - * Thursday, October 9, 1997 + * Programmer: Robb Matzke + * Thursday, October 9, 1997 * * Modifications: * @@ -477,18 +482,18 @@ H5F_istore_found(H5F_t *f, const haddr_t *addr, const void *_lt_key, */ static H5B_ins_t H5F_istore_insert(H5F_t *f, const haddr_t *addr, - void *_lt_key, hbool_t *lt_key_changed, - void *_md_key, void *_udata, - void *_rt_key, hbool_t *rt_key_changed, - haddr_t *new_node /*out */ ) + void *_lt_key, hbool_t *lt_key_changed, + void *_md_key, void *_udata, + void *_rt_key, hbool_t *rt_key_changed, + haddr_t *new_node/*out*/) { - H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; - H5F_istore_key_t *md_key = (H5F_istore_key_t *) _md_key; - H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; - H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; - intn i, cmp; - H5B_ins_t ret_value = H5B_INS_ERROR; - size_t nbytes; + H5F_istore_key_t *lt_key = (H5F_istore_key_t *) _lt_key; + H5F_istore_key_t *md_key = (H5F_istore_key_t *) _md_key; + H5F_istore_key_t *rt_key = (H5F_istore_key_t *) _rt_key; + H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *) _udata; + intn i, cmp; + H5B_ins_t ret_value = H5B_INS_ERROR; + size_t nbytes; FUNC_ENTER(H5F_istore_insert, H5B_INS_ERROR); @@ -507,86 +512,89 @@ H5F_istore_insert(H5F_t *f, const haddr_t *addr, assert(cmp <= 0); if (cmp < 0) { - /* Negative indices not supported yet */ - assert("HDF5 INTERNAL ERROR -- see rpm" && 0); - HRETURN_ERROR(H5E_STORAGE, H5E_UNSUPPORTED, H5B_INS_ERROR, "internal error"); + /* Negative indices not supported yet */ + assert("HDF5 INTERNAL ERROR -- see rpm" && 0); + HRETURN_ERROR(H5E_STORAGE, H5E_UNSUPPORTED, H5B_INS_ERROR, + "internal error"); } else if (H5V_hyper_eq(udata->mesg.ndims, - udata->key.offset, udata->key.size, - lt_key->offset, lt_key->size)) { - /* - * Already exists. Just return the info. - */ - udata->addr = *addr; - udata->key.file_number = lt_key->file_number; - ret_value = H5B_INS_NOOP; + udata->key.offset, udata->key.size, + lt_key->offset, lt_key->size)) { + /* + * Already exists. Just return the info. + */ + udata->addr = *addr; + udata->key.file_number = lt_key->file_number; + ret_value = H5B_INS_NOOP; } else if (H5V_hyper_disjointp(udata->mesg.ndims, - lt_key->offset, lt_key->size, - udata->key.offset, udata->key.size)) { - assert(H5V_hyper_disjointp(udata->mesg.ndims, - rt_key->offset, rt_key->size, - udata->key.offset, udata->key.size)); - - /* - * Split this node, inserting the new new node to the right of the - * current node. The MD_KEY is where the split occurs. - */ - md_key->file_number = udata->key.file_number; - for (i = 0, nbytes = 1; i < udata->mesg.ndims; i++) { - assert(0 == udata->key.offset[i] % udata->mesg.dim[i]); - assert(udata->key.size[i] == udata->mesg.dim[i]); - md_key->offset[i] = udata->key.offset[i]; - md_key->size[i] = udata->key.size[i]; - nbytes *= udata->key.size[i]; - } - - /* - * Allocate storage for the new chunk - */ - if (H5MF_alloc(f, H5MF_RAW, nbytes, new_node /*out */ ) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, H5B_INS_ERROR, - "file allocation failed"); - } - udata->addr = *new_node; - udata->key.file_number = 0; - ret_value = H5B_INS_RIGHT; + lt_key->offset, lt_key->size, + udata->key.offset, udata->key.size)) { + assert(H5V_hyper_disjointp(udata->mesg.ndims, + rt_key->offset, rt_key->size, + udata->key.offset, udata->key.size)); + + /* + * Split this node, inserting the new new node to the right of the + * current node. The MD_KEY is where the split occurs. + */ + md_key->file_number = udata->key.file_number; + for (i = 0, nbytes = 1; i < udata->mesg.ndims; i++) { + assert(0 == udata->key.offset[i] % udata->mesg.dim[i]); + assert(udata->key.size[i] == udata->mesg.dim[i]); + md_key->offset[i] = udata->key.offset[i]; + md_key->size[i] = udata->key.size[i]; + nbytes *= udata->key.size[i]; + } + + /* + * Allocate storage for the new chunk + */ + if (H5MF_alloc(f, H5MF_RAW, nbytes, new_node /*out */ ) < 0) { + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, H5B_INS_ERROR, + "file allocation failed"); + } + udata->addr = *new_node; + udata->key.file_number = 0; + ret_value = H5B_INS_RIGHT; } else { - assert("HDF5 INTERNAL ERROR -- see rpm" && 0); - HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, H5B_INS_ERROR, "internal error"); + assert("HDF5 INTERNAL ERROR -- see rpm" && 0); + HRETURN_ERROR(H5E_IO, H5E_UNSUPPORTED, H5B_INS_ERROR, + "internal error"); } FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_copy_hyperslab + * Function: H5F_istore_copy_hyperslab * - * Purpose: Reads or writes a hyperslab to disk depending on whether OP - * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab - * storage is described with ISTORE and exists in file F. The - * file hyperslab begins at location OFFSET_F[] (an N-dimensional - * point in the domain in terms of elements) in the file and - * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[] - * elements. The dimensionality of memory is assumed to be the - * same as the file and the total size of the multi-dimensional - * memory buffer is SIZE_M[]. + * Purpose: Reads or writes a hyperslab to disk depending on whether OP + * is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab + * storage is described with ISTORE and exists in file F. The + * file hyperslab begins at location OFFSET_F[] (an N-dimensional + * point in the domain in terms of elements) in the file and + * OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[] + * elements. The dimensionality of memory is assumed to be the + * same as the file and the total size of the multi-dimensional + * memory buffer is SIZE_M[]. * - * The slowest varying dimension is always listed first in the - * various offset and size arrays. + * The slowest varying dimension is always listed first in the + * various offset and size arrays. * - * A `chunk' is a hyperslab of the disk array which is stored - * contiguously. I/O occurs in units of chunks where the size of - * a chunk is determined by the alignment constraints specified - * in ISTORE. + * A `chunk' is a hyperslab of the disk array which is stored + * contiguously. I/O occurs in units of chunks where the size of + * a chunk is determined by the alignment constraints specified + * in ISTORE. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Friday, October 17, 1997 + * Programmer: Robb Matzke + * Friday, October 17, 1997 * * Modifications: * @@ -594,22 +602,22 @@ H5F_istore_insert(H5F_t *f, const haddr_t *addr, */ static herr_t H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, - const size_t offset_f[], const size_t size[], - const size_t offset_m[], const size_t size_m[], - const void *buf) + const size_t offset_f[], const size_t size[], + const size_t offset_m[], const size_t size_m[], + void *buf/*in or out*/) { - intn i, carry; - size_t idx_cur[H5O_LAYOUT_NDIMS]; - size_t idx_min[H5O_LAYOUT_NDIMS]; - size_t idx_max[H5O_LAYOUT_NDIMS]; - size_t sub_size[H5O_LAYOUT_NDIMS]; - size_t offset_wrt_chunk[H5O_LAYOUT_NDIMS]; - size_t sub_offset_m[H5O_LAYOUT_NDIMS]; - size_t chunk_size; - uint8 *chunk = NULL; - H5F_istore_ud1_t udata; - herr_t status; - herr_t ret_value = FAIL; + intn i, carry; + size_t idx_cur[H5O_LAYOUT_NDIMS]; + size_t idx_min[H5O_LAYOUT_NDIMS]; + size_t idx_max[H5O_LAYOUT_NDIMS]; + size_t sub_size[H5O_LAYOUT_NDIMS]; + size_t offset_wrt_chunk[H5O_LAYOUT_NDIMS]; + size_t sub_offset_m[H5O_LAYOUT_NDIMS]; + size_t chunk_size; + uint8 *chunk = NULL; + H5F_istore_ud1_t udata; + herr_t status; + herr_t ret_value = FAIL; FUNC_ENTER(H5F_istore_copy_hyperslab, FAIL); @@ -623,24 +631,64 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, assert(size_m); assert(buf); #ifndef NDEBUG - for (i = 0; i < layout->ndims; i++) { - assert(size_m[i] > 0); /*destination must exist */ - /*hyperslab must fit in BUF */ - assert((offset_m ? offset_m[i] : 0) + size[i] <= size_m[i]); - assert(layout->dim[i] > 0); + for (i=0; indims; i++) { + assert(size_m[i] > 0); /*destination must exist */ + /*hyperslab must fit in BUF */ + assert((offset_m?offset_m[i]:0) + size[i] <= size_m[i]); + assert(layout->dim[i] > 0); } #endif - /* Initialize indices */ - for (i = 0; i < layout->ndims; i++) { - idx_min[i] = (offset_f ? offset_f[i] : 0) / layout->dim[i]; - idx_max[i] = ((offset_f ? offset_f[i] : 0) + size[i] - 1) / layout->dim[i] + 1; - idx_cur[i] = idx_min[i]; + /* + * As a special case of H5F_ISTORE_READ, if the source is aligned on + * a chunk boundary and is the same size as a chunk, and the destination + * is the same size as a chunk, then instead of reading into a temporary + * buffer and then into the destination, we read directly into the + * destination. + */ + if (H5F_ISTORE_READ==op) { + for (i=0, chunk_size=1; indims; i++) { + if (offset_f[i] % layout->dim[i]) break; /*src not aligned*/ + if (size[i]!=layout->dim[i]) break; /*src not a chunk*/ + if (size_m[i]!=layout->dim[i]) break; /*dst not a chunk*/ + udata.key.offset[i] = offset_f[i]; + udata.key.size[i] = layout->dim[i]; + chunk_size *= layout->dim[i]; + } + + if (i==layout->ndims) { + udata.mesg = *layout; + H5F_addr_undef (&(udata.addr)); + udata.key.file_number = 0; + status = H5B_find (f, H5B_ISTORE, &(layout->addr), &udata); + if (status>=0 && H5F_addr_defined (&(udata.addr))) { + assert (0==udata.key.file_number); + if (H5F_block_read (f, &(udata.addr), chunk_size, buf)<0) { + HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL, + "unable to read raw storage chunk"); + } + } else { + HDmemset (buf, 0, chunk_size); + } + HRETURN (SUCCEED); + } + } + + /* + * This is the general case. We set up multi-dimensional counters + * (idx_min, idx_max, and idx_cur) and loop through the chunks copying + * each chunk into a temporary buffer, compressing or decompressing, and + * then copying it to it's destination. + */ + for (i=0; indims; i++) { + idx_min[i] = (offset_f?offset_f[i]:0) / layout->dim[i]; + idx_max[i] = ((offset_f?offset_f[i]:0) + size[i]-1) / layout->dim[i]+1; + idx_cur[i] = idx_min[i]; } /* Allocate buffers */ - for (i = 0, chunk_size = 1; i < layout->ndims; i++) { - chunk_size *= layout->dim[i]; + for (i=0, chunk_size=1; indims; i++) { + chunk_size *= layout->dim[i]; } chunk = H5MM_xmalloc(chunk_size); @@ -650,80 +698,77 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, /* Loop over all chunks */ while (1) { - /* Read/Write chunk or create it if it doesn't exist */ - udata.mesg.ndims = layout->ndims; - H5F_addr_undef(&(udata.addr)); - udata.key.file_number = 0; - - for (i = 0; i < layout->ndims; i++) { - - /* The location and size of the chunk being accessed */ - udata.key.offset[i] = idx_cur[i] * layout->dim[i]; - udata.key.size[i] = layout->dim[i]; - - /* The offset and size wrt the chunk */ - offset_wrt_chunk[i] = MAX((offset_f ? offset_f[i] : 0), - udata.key.offset[i]) - - udata.key.offset[i]; - sub_size[i] = MIN((idx_cur[i] + 1) * layout->dim[i], - (offset_f ? offset_f[i] : 0) + size[i]) - - (udata.key.offset[i] + offset_wrt_chunk[i]); - - /* Offset into mem buffer */ - sub_offset_m[i] = udata.key.offset[i] + offset_wrt_chunk[i] + - (offset_m ? offset_m[i] : 0) - - (offset_f ? offset_f[i] : 0); - } - - if (H5F_ISTORE_WRITE == op) { - status = H5B_insert(f, H5B_ISTORE, &(layout->addr), &udata); - assert(status >= 0); - } else { - status = H5B_find(f, H5B_ISTORE, &(layout->addr), &udata); - } - - /* - * If the operation is reading from the disk or if we are writing a - * partial chunk then load the chunk from disk. - */ - if (H5F_ISTORE_READ == op || - !H5V_vector_zerop(layout->ndims, offset_wrt_chunk) || - !H5V_vector_eq(layout->ndims, sub_size, udata.key.size)) { - if (status >= 0 && H5F_addr_defined(&(udata.addr))) { - assert(0 == udata.key.file_number); - if (H5F_block_read(f, &(udata.addr), chunk_size, chunk) < 0) { - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, - "unable to read raw storage chunk"); - } - } else { - HDmemset(chunk, 0, chunk_size); - } - } - /* Transfer data to/from the chunk */ - if (H5F_ISTORE_WRITE == op) { - H5V_hyper_copy(layout->ndims, sub_size, - udata.key.size, offset_wrt_chunk, chunk, - size_m, sub_offset_m, buf); - assert(0 == udata.key.file_number); - if (H5F_block_write(f, &(udata.addr), chunk_size, chunk) < 0) { - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "unable to write raw storage chunk"); - } - } else { - H5V_hyper_copy(layout->ndims, sub_size, - size_m, sub_offset_m, (void *)buf, - udata.key.size, offset_wrt_chunk, chunk); - } - - /* Increment indices */ - for (i = layout->ndims - 1, carry = 1; i >= 0 && carry; --i) { - if (++idx_cur[i] >= idx_max[i]) - idx_cur[i] = idx_min[i]; - else - carry = 0; - } - if (carry) - break; + /* Read/Write chunk or create it if it doesn't exist */ + udata.mesg.ndims = layout->ndims; + H5F_addr_undef(&(udata.addr)); + udata.key.file_number = 0; + + for (i=0; indims; i++) { + + /* The location and size of the chunk being accessed */ + udata.key.offset[i] = idx_cur[i] * layout->dim[i]; + udata.key.size[i] = layout->dim[i]; + + /* The offset and size wrt the chunk */ + offset_wrt_chunk[i] = MAX((offset_f ? offset_f[i] : 0), + udata.key.offset[i]) - + udata.key.offset[i]; + sub_size[i] = MIN((idx_cur[i] + 1) * layout->dim[i], + (offset_f ? offset_f[i] : 0) + size[i]) - + (udata.key.offset[i] + offset_wrt_chunk[i]); + + /* Offset into mem buffer */ + sub_offset_m[i] = udata.key.offset[i] + offset_wrt_chunk[i] + + (offset_m ? offset_m[i] : 0) - + (offset_f ? offset_f[i] : 0); + } + + if (H5F_ISTORE_WRITE == op) { + status = H5B_insert(f, H5B_ISTORE, &(layout->addr), &udata); + assert(status >= 0); + } else { + status = H5B_find(f, H5B_ISTORE, &(layout->addr), &udata); + } + + /* + * If the operation is reading from the disk or if we are writing a + * partial chunk then load the chunk from disk. + */ + if (H5F_ISTORE_READ == op || + !H5V_vector_zerop(layout->ndims, offset_wrt_chunk) || + !H5V_vector_eq(layout->ndims, sub_size, udata.key.size)) { + if (status>=0 && H5F_addr_defined(&(udata.addr))) { + assert(0==udata.key.file_number); + if (H5F_block_read(f, &(udata.addr), chunk_size, chunk) < 0) { + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, + "unable to read raw storage chunk"); + } + } else { + HDmemset(chunk, 0, chunk_size); + } + } + /* Transfer data to/from the chunk */ + if (H5F_ISTORE_WRITE==op) { + H5V_hyper_copy(layout->ndims, sub_size, + udata.key.size, offset_wrt_chunk, chunk, + size_m, sub_offset_m, buf); + assert(0 == udata.key.file_number); + if (H5F_block_write(f, &(udata.addr), chunk_size, chunk) < 0) { + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "unable to write raw storage chunk"); + } + } else { + H5V_hyper_copy(layout->ndims, sub_size, + size_m, sub_offset_m, (void *)buf, + udata.key.size, offset_wrt_chunk, chunk); + } + + /* Increment indices */ + for (i=layout->ndims-1, carry=1; i>=0 && carry; --i) { + if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i]; + else carry = 0; + } + if (carry) break; } ret_value = SUCCEED; @@ -731,19 +776,20 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, chunk = H5MM_xfree(chunk); FUNC_LEAVE(ret_value); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_read + * Function: H5F_istore_read * - * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw - * storage array. + * Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw + * storage array. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 15, 1997 + * Programmer: Robb Matzke + * Wednesday, October 15, 1997 * * Modifications: * @@ -751,7 +797,7 @@ H5F_istore_copy_hyperslab(H5F_t *f, const H5O_layout_t *layout, H5F_isop_t op, */ herr_t H5F_istore_read(H5F_t *f, const H5O_layout_t *layout, - const size_t offset[], const size_t size[], void *buf) + const size_t offset[], const size_t size[], void *buf) { FUNC_ENTER(H5F_istore_read, FAIL); @@ -763,25 +809,26 @@ H5F_istore_read(H5F_t *f, const H5O_layout_t *layout, assert(buf); if (H5F_istore_copy_hyperslab(f, layout, H5F_ISTORE_READ, - offset, size, H5V_ZERO, size, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, - "hyperslab output failure"); + offset, size, H5V_ZERO, size, buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_READERROR, FAIL, + "hyperslab output failure"); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_write + * Function: H5F_istore_write * - * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw - * storage array. + * Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw + * storage array. * - * Return: Success: SUCCEED + * Return: Success: SUCCEED * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Wednesday, October 15, 1997 + * Programmer: Robb Matzke + * Wednesday, October 15, 1997 * * Modifications: * @@ -789,8 +836,8 @@ H5F_istore_read(H5F_t *f, const H5O_layout_t *layout, */ herr_t H5F_istore_write(H5F_t *f, const H5O_layout_t *layout, - const size_t offset[], const size_t size[], - const void *buf) + const size_t offset[], const size_t size[], + const void *buf) { FUNC_ENTER(H5F_istore_write, FAIL); @@ -802,30 +849,32 @@ H5F_istore_write(H5F_t *f, const H5O_layout_t *layout, assert(buf); if (H5F_istore_copy_hyperslab(f, layout, H5F_ISTORE_WRITE, - offset, size, H5V_ZERO, size, buf) < 0) { - HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, - "hyperslab output failure"); + offset, size, H5V_ZERO, size, + (void*)buf) < 0) { + HRETURN_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, + "hyperslab output failure"); } FUNC_LEAVE(SUCCEED); } + /*------------------------------------------------------------------------- - * Function: H5F_istore_create + * Function: H5F_istore_create * - * Purpose: Creates a new indexed-storage B-tree and initializes the - * istore struct with information about the storage. The - * struct should be immediately written to the object header. + * Purpose: Creates a new indexed-storage B-tree and initializes the + * istore struct with information about the storage. The + * struct should be immediately written to the object header. * - * This function must be called before passing ISTORE to any of - * the other indexed storage functions! + * This function must be called before passing ISTORE to any of + * the other indexed storage functions! * - * Return: Success: SUCCEED with the ISTORE argument initialized - * and ready to write to an object header. + * Return: Success: SUCCEED with the ISTORE argument initialized + * and ready to write to an object header. * - * Failure: FAIL + * Failure: FAIL * - * Programmer: Robb Matzke - * Tuesday, October 21, 1997 + * Programmer: Robb Matzke + * Tuesday, October 21, 1997 * * Modifications: * @@ -834,9 +883,9 @@ H5F_istore_write(H5F_t *f, const H5O_layout_t *layout, herr_t H5F_istore_create(H5F_t *f, H5O_layout_t *layout /*out */ ) { - H5F_istore_ud1_t udata; + H5F_istore_ud1_t udata; #ifndef NDEBUG - int i; + int i; #endif FUNC_ENTER(H5F_istore_create, FAIL); @@ -847,13 +896,14 @@ H5F_istore_create(H5F_t *f, H5O_layout_t *layout /*out */ ) assert(layout->ndims > 0 && layout->ndims <= H5O_LAYOUT_NDIMS); #ifndef NDEBUG for (i = 0; i < layout->ndims; i++) { - assert(layout->dim[i] > 0); + assert(layout->dim[i] > 0); } #endif udata.mesg.ndims = layout->ndims; if (H5B_create(f, H5B_ISTORE, &udata, &(layout->addr) /*out */ ) < 0) { - HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't create B-tree"); + HRETURN_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't create B-tree"); } + FUNC_LEAVE(SUCCEED); } diff --git a/src/H5Odtype.c b/src/H5Odtype.c index e2a09a3..fe30d00 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -174,6 +174,7 @@ H5O_dtype_decode_helper(const uint8 **pp, H5T_t *dt) dt->u.compnd.memb[i].perm[1] = (perm_word >> 8) & 0xff; dt->u.compnd.memb[i].perm[2] = (perm_word >> 16) & 0xff; dt->u.compnd.memb[i].perm[3] = (perm_word >> 24) & 0xff; + dt->u.compnd.memb[i].type = H5MM_xcalloc (1, sizeof(H5T_t)); if (H5O_dtype_decode_helper(pp, dt->u.compnd.memb[i].type) < 0 || H5T_COMPOUND == dt->u.compnd.memb[i].type->type) { for (j = 0; j <= i; j++) @@ -548,7 +549,7 @@ H5O_dtype_copy(const void *_src, void *_dst) H5F_t *f; IN: pointer to the HDF5 file struct const void *mesg; IN: Pointer to the source simple datatype struct RETURNS - Size of message on success, FAIL on failure + Size of message on success, 0 on failure DESCRIPTION This function returns the size of the raw simple datatype message on success. (Not counting the message type or size fields, only the data @@ -561,7 +562,7 @@ H5O_dtype_size(H5F_t *f, const void *mesg) size_t ret_value = 8; const H5T_t *dt = (const H5T_t *) mesg; - FUNC_ENTER(H5O_dtype_size, FAIL); + FUNC_ENTER(H5O_dtype_size, 0); assert(mesg); @@ -728,7 +729,7 @@ H5O_dtype_debug(H5F_t *f, const void *mesg, FILE * stream, } fprintf(stream, "}\n"); } - H5O_dtype_debug(f, &(dt->u.compnd.memb[i].type), stream, + H5O_dtype_debug(f, dt->u.compnd.memb[i].type, stream, indent + 3, MAX(0, fwidth - 3)); } } else { diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 5f2db2a..e1f3247 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -233,7 +233,7 @@ H5O_efl_copy(const void *_mesg, void *_dest) * * Return: Success: Message data size in bytes. * - * Failure: FAIL + * Failure: 0 * * Programmer: Robb Matzke * Tuesday, November 25, 1997 @@ -246,9 +246,9 @@ static size_t H5O_efl_size(H5F_t *f, const void *_mesg) { const H5O_efl_t *mesg = (const H5O_efl_t *) _mesg; - size_t ret_value = FAIL; + size_t ret_value = 0; - FUNC_ENTER(H5O_efl_size, FAIL); + FUNC_ENTER(H5O_efl_size, 0); /* check args */ assert(f); diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 5972cca..71fe092 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -187,7 +187,7 @@ H5O_layout_copy(const void *_mesg, void *_dest) * * Return: Success: Message data size in bytes * - * Failure: FAIL + * Failure: 0 * * Programmer: Robb Matzke * Wednesday, October 8, 1997 @@ -200,9 +200,9 @@ static size_t H5O_layout_size(H5F_t *f, const void *_mesg) { const H5O_layout_t *mesg = (const H5O_layout_t *) _mesg; - size_t ret_value = FAIL; + size_t ret_value = 0; - FUNC_ENTER(H5O_layout_size, FAIL); + FUNC_ENTER(H5O_layout_size, 0); /* check args */ assert(f); diff --git a/src/H5Oname.c b/src/H5Oname.c index c8e6a57..b36c550 100644 --- a/src/H5Oname.c +++ b/src/H5Oname.c @@ -193,7 +193,7 @@ H5O_name_size(H5F_t *f, const void *_mesg) const H5O_name_t *mesg = (const H5O_name_t *) _mesg; size_t size; - FUNC_ENTER(H5O_name_size, FAIL); + FUNC_ENTER(H5O_name_size, 0); /* check args */ assert(f); diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index f4a690e..9818130 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -224,7 +224,7 @@ H5O_sdspace_copy(const void *mesg, void *dest) H5F_t *f; IN: pointer to the HDF5 file struct const void *mesg; IN: Pointer to the source simple dimensionality struct RETURNS - Size of message on success, FAIL on failure + Size of message on success, zero on failure DESCRIPTION This function returns the size of the raw simple dimensionality message on success. (Not counting the message type or size fields, only the data @@ -236,7 +236,7 @@ H5O_sdspace_size(H5F_t *f, const void *mesg) const H5S_simple_t *sdim = (const H5S_simple_t *) mesg; size_t ret_value = 8; /* all dimensionality messages are at least 8 bytes long (rank and flags) */ - FUNC_ENTER(H5O_sim_dtype_size, FAIL); + FUNC_ENTER(H5O_sim_dtype_size, 0); ret_value += sdim->rank * 4; /* add in the dimension sizes */ ret_value += sdim->max ? sdim->rank * 4 : 0; /* add in the space for the maximum dimensions, if they are present */ diff --git a/src/H5Ostab.c b/src/H5Ostab.c index 7600f47..56d3955 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -208,7 +208,7 @@ H5O_stab_copy(const void *_mesg, void *_dest) * * Return: Success: Message data size in bytes without alignment. * - * Failure: FAIL + * Failure: zero * * Programmer: Robb Matzke * matzke@llnl.gov @@ -221,7 +221,7 @@ H5O_stab_copy(const void *_mesg, void *_dest) static size_t H5O_stab_size(H5F_t *f, const void *_mesg) { - FUNC_ENTER(H5O_stab_size, FAIL); + FUNC_ENTER(H5O_stab_size, 0); FUNC_LEAVE(2 * H5F_SIZEOF_ADDR(f)); } diff --git a/src/H5P.c b/src/H5P.c index e990675..9f5ddc7 100644 --- a/src/H5P.c +++ b/src/H5P.c @@ -1727,8 +1727,8 @@ H5Pset_buffer (hid_t plist_id, size_t size, void *tconv, void *bkg) /* Update property list */ plist->buf_size = size; - plist->tconv = tconv; - plist->bkg = bkg; + plist->tconv_buf = tconv; + plist->bkg_buf = bkg; FUNC_LEAVE (SUCCEED); } @@ -1765,14 +1765,90 @@ H5Pget_buffer (hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/) } /* Return values */ - if (tconv) *tconv = plist->tconv; - if (bkg) *bkg = plist->bkg; + if (tconv) *tconv = plist->tconv_buf; + if (bkg) *bkg = plist->bkg_buf; FUNC_LEAVE (plist->buf_size); } /*------------------------------------------------------------------------- + * Function: H5Pset_preserve + * + * Purpose: When reading or writing compound data types and the + * destination is partially initialized and the read/write is + * intended to initialize the other members, one must set this + * property to TRUE. Otherwise the I/O pipeline treats the + * destination datapoints as completely uninitialized. + * + * Return: Success: SUCCEED + * + * Failure: FAIL + * + * Programmer: Robb Matzke + * Tuesday, March 17, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_preserve (hid_t plist_id, hbool_t status) +{ + H5D_xfer_t *plist = NULL; + + FUNC_ENTER (H5Pset_preserve, FAIL); + + /* Check arguments */ + if (H5P_DATASET_XFER != H5Pget_class (plist_id) || + NULL == (plist = H5A_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset transfer property list"); + } + + /* Update property list */ + plist->need_bkg = status ? H5T_BKG_YES : H5T_BKG_NO; + + FUNC_LEAVE (SUCCEED); +} + + +/*------------------------------------------------------------------------- + * Function: H5Pget_preserve + * + * Purpose: The inverse of H5Pset_preserve() + * + * Return: Success: TRUE or FALSE + * + * Failure: -1 + * + * Programmer: Robb Matzke + * Tuesday, March 17, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +int +H5Pget_preserve (hid_t plist_id) +{ + H5D_xfer_t *plist = NULL; + + FUNC_ENTER (H5Pset_preserve, FAIL); + + /* Check arguments */ + if (H5P_DATASET_XFER != H5Pget_class (plist_id) || + NULL == (plist = H5A_object (plist_id))) { + HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, + "not a dataset transfer property list"); + } + + FUNC_LEAVE (plist->need_bkg?TRUE:FALSE); +} + + + +/*------------------------------------------------------------------------- * Function: H5Pset_mpi * * Signature: herr_t H5Pset_mpi(hid_t tid, MPI_Comm comm, MPI_Info info, diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index 7e91ce2..f5a84ee 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -85,6 +85,8 @@ herr_t H5Pset_family (hid_t tid, hid_t memb_tid); herr_t H5Pget_family (hid_t tid, hid_t *memb_tid/*out*/); herr_t H5Pset_buffer (hid_t plist_id, size_t size, void *tconv, void *bkg); size_t H5Pget_buffer (hid_t plist_id, void **tconv/*out*/, void **bkg/*out*/); +herr_t H5Pset_preserve (hid_t plist_id, hbool_t status); +int H5Pget_preserve (hid_t plist_id); #ifdef HAVE_PARALLEL herr_t H5Pset_mpi (hid_t tid, MPI_Comm comm, MPI_Info info, diff --git a/src/H5T.c b/src/H5T.c index c3fb26c..b8b1f37 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -303,7 +303,7 @@ H5T_term_interface(void) H5T_soft_g = H5MM_xfree (H5T_soft_g); /* Clear noop function */ - if ((cfunc=H5T_find (NULL, NULL, &pcdata))) { + if ((cfunc=H5T_find (NULL, NULL, H5T_BKG_NO, &pcdata))) { pcdata->command = H5T_CONV_FREE; (cfunc)(FAIL, FAIL, pcdata, 0, NULL, NULL); } @@ -2383,7 +2383,7 @@ H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata) /* Find it */ *pcdata = NULL; - if (NULL == (ret_value = H5T_find(src, dst, pcdata))) { + if (NULL == (ret_value = H5T_find(src, dst, H5T_BKG_NO, pcdata))) { HRETURN_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "conversion function not found"); } @@ -3019,7 +3019,10 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) /*------------------------------------------------------------------------- * Function: H5T_find * - * Purpose: Finds a conversion function for the specified path. + * Purpose: Finds a conversion function for the specified path. If the + * source and destination types are the same and NEED_BKG is not + * H5T_BKG_YES then a pointer to the H5T_conv_noop() function is + * returned. * * Return: Success: A pointer to an appropriate conversion * function. The PCDATA argument is initialized @@ -3036,7 +3039,8 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) *------------------------------------------------------------------------- */ H5T_conv_t -H5T_find(const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata) +H5T_find(const H5T_t *src, const H5T_t *dst, H5T_bkg_t need_bkg, + H5T_cdata_t **pcdata/*out*/) { H5T_path_t *path = NULL; H5T_conv_t ret_value = NULL; @@ -3045,7 +3049,7 @@ H5T_find(const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata) FUNC_ENTER(H5T_find, NULL); /* No-op case */ - if (0 == H5T_cmp(src, dst)) { + if (need_bkgneed_bkg = H5T_BKG_YES; -#endif - + cdata->need_bkg = H5T_BKG_TEMP; cdata->recalc = FALSE; FUNC_LEAVE (SUCCEED); } diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 6af43b8..7ff5d18 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -40,7 +40,8 @@ herr_t H5T_insert (H5T_t *parent, const char *name, off_t offset, herr_t H5T_sort_by_offset (H5T_t *dt); herr_t H5T_pack (H5T_t *dt); herr_t H5T_debug (H5T_t *dt, FILE * stream); -H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst, H5T_cdata_t **pcdata); +H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst, H5T_bkg_t need_bkg, + H5T_cdata_t **pcdata/*out*/); /* * This conversion function is here so we can determine whether a conversion diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index db72bab..8e0f8e8 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -94,7 +94,7 @@ typedef enum H5T_pad_t { /* How is the `bkg' buffer used by the conversion function? */ typedef enum H5T_bkg_t { - H5T_BKG_NONE = 0, /*background buffer is not needed, send NULL */ + H5T_BKG_NO = 0, /*background buffer is not needed, send NULL */ H5T_BKG_TEMP = 1, /*bkg buffer used as temp storage only */ H5T_BKG_YES = 2 /*init bkg buf with data before conversion */ } H5T_bkg_t; diff --git a/test/cmpd_dset.c b/test/cmpd_dset.c index a98a9b3..cd36ca1 100644 --- a/test/cmpd_dset.c +++ b/test/cmpd_dset.c @@ -5,6 +5,7 @@ * Programmer: Robb Matzke * Friday, January 23, 1998 */ +#undef NDEBUG #include #include #include @@ -121,7 +122,7 @@ main (void) /* Other variables */ int i, j, ndims; - hid_t file, dataset, space; + hid_t file, dataset, space, PRESERVE; herr_t status; static size_t dim[] = {NX, NY}; int f_offset[2]; /*offset of hyperslab in file */ @@ -137,7 +138,11 @@ main (void) space = H5Screate_simple (2, dim, NULL); assert (space>=0); - + /* Create xfer properties to preserve initialized data */ + PRESERVE = H5Pcreate (H5P_DATASET_XFER); + assert (PRESERVE>=0); + status = H5Pset_preserve (PRESERVE, 1); + assert (status>=0); /* *###################################################################### @@ -291,7 +296,7 @@ STEP 5: Read members into a superset which is partially initialized.\n"); assert (s5_tid>=0); /* Read the data */ - status = H5Dread (dataset, s5_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s5); + status = H5Dread (dataset, s5_tid, H5S_ALL, H5S_ALL, PRESERVE, s5); assert (status>=0); /* Check that the data was read properly */ @@ -329,7 +334,7 @@ STEP 6: Update fields `b' and `d' on the file, leaving the other fields\n\ } /* Write the data to file */ - status = H5Dwrite (dataset, s4_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, s4); + status = H5Dwrite (dataset, s4_tid, H5S_ALL, H5S_ALL, PRESERVE, s4); assert (status>=0); /* Read the data back */ @@ -474,7 +479,7 @@ STEP 10: Read middle third of hyperslab into middle third of memory array\n\ memset (s5, 0xFF, NX*NY*sizeof(s5_t)); /* Read the hyperslab */ - status = H5Dread (dataset, s5_tid, s8_f_sid, s8_f_sid, H5P_DEFAULT, s5); + status = H5Dread (dataset, s5_tid, s8_f_sid, s8_f_sid, PRESERVE, s5); assert (status>=0); /* Compare */ @@ -525,7 +530,7 @@ STEP 11: Write an array back to the middle third of the dataset to\n\ memset (s11, 0xff, h_size[0]*h_size[1]*sizeof(s4_t)); /* Write to disk */ - status = H5Dwrite (dataset, s4_tid, s8_m_sid, s8_f_sid, H5P_DEFAULT, s11); + status = H5Dwrite (dataset, s4_tid, s8_m_sid, s8_f_sid, PRESERVE, s11); assert (status>=0); /* Read the whole thing */ -- cgit v0.12