diff options
author | Vailin Choi <vchoi@hdfgroup.org> | 2010-09-13 21:57:00 (GMT) |
---|---|---|
committer | Vailin Choi <vchoi@hdfgroup.org> | 2010-09-13 21:57:00 (GMT) |
commit | ae7d45d612db414c8f9f8d21d732974ab33bb651 (patch) | |
tree | 989c7c5a6d48cb81249bac73602e6a3b53ba2abb | |
parent | c348f9405e134e722edfb0c26133c471c926c64d (diff) | |
download | hdf5-ae7d45d612db414c8f9f8d21d732974ab33bb651.zip hdf5-ae7d45d612db414c8f9f8d21d732974ab33bb651.tar.gz hdf5-ae7d45d612db414c8f9f8d21d732974ab33bb651.tar.bz2 |
[svn-r19378] Modifications to using v2 B-tree as index for chunked datasets with >1 unlimited dimensions.
h5committested.
-rw-r--r-- | src/H5B2.c | 8 | ||||
-rw-r--r-- | src/H5B2dbg.c | 30 | ||||
-rw-r--r-- | src/H5B2pkg.h | 6 | ||||
-rw-r--r-- | src/H5B2private.h | 16 | ||||
-rw-r--r-- | src/H5B2test.c | 1 | ||||
-rw-r--r-- | src/H5Dbtree2.c | 1769 | ||||
-rw-r--r-- | src/H5Dchunk.c | 94 | ||||
-rw-r--r-- | src/H5Dint.c | 7 | ||||
-rw-r--r-- | src/H5Dlayout.c | 80 | ||||
-rw-r--r-- | src/H5Dpkg.h | 31 | ||||
-rw-r--r-- | src/H5Dpublic.h | 3 | ||||
-rw-r--r-- | src/H5HFbtree2.c | 1 | ||||
-rw-r--r-- | src/H5Olayout.c | 28 | ||||
-rw-r--r-- | src/H5Oprivate.h | 18 | ||||
-rw-r--r-- | src/H5Ostorage.c | 18 | ||||
-rwxr-xr-x | src/H5SMbtree2.c | 1 | ||||
-rwxr-xr-x | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 19 | ||||
-rw-r--r-- | test/dsets.c | 618 | ||||
-rwxr-xr-x | test/objcopy.c | 3 | ||||
-rw-r--r-- | test/set_extent.c | 3 | ||||
-rw-r--r-- | tools/h5dump/h5dumpgentest.c | 15 | ||||
-rw-r--r-- | tools/misc/h5debug.c | 58 | ||||
-rw-r--r-- | tools/testfiles/tdset_idx.h5 | bin | 6760 -> 10562 bytes |
24 files changed, 2642 insertions, 187 deletions
@@ -82,6 +82,8 @@ extern const H5B2_class_t H5G_BT2_CORDER[1]; extern const H5B2_class_t H5SM_INDEX[1]; extern const H5B2_class_t H5A_BT2_NAME[1]; extern const H5B2_class_t H5A_BT2_CORDER[1]; +extern const H5B2_class_t H5D_BT2[1]; +extern const H5B2_class_t H5D_BT2_FILT[1]; const H5B2_class_t *const H5B2_client_class_g[] = { H5B2_TEST, /* 0 - H5B2_TEST_ID */ @@ -90,10 +92,12 @@ const H5B2_class_t *const H5B2_client_class_g[] = { H5HF_HUGE_BT2_DIR, /* 3 - H5B2_FHEAP_HUGE_DIR_ID */ H5HF_HUGE_BT2_FILT_DIR, /* 4 - H5B2_FHEAP_HUGE_FILT_DIR_ID */ H5G_BT2_NAME, /* 5 - H5B2_GRP_DENSE_NAME_ID */ - H5G_BT2_CORDER, /* 6 - H5B2_GRP_DENSE_CORDER_ID */ + H5G_BT2_CORDER, /* 6 - H5B2_GRP_DENSE_CORDER_ID */ H5SM_INDEX, /* 7 - H5B2_SOHM_INDEX_ID */ H5A_BT2_NAME, /* 8 - H5B2_ATTR_DENSE_NAME_ID */ - H5A_BT2_CORDER, /* 9 - H5B2_ATTR_DENSE_CORDER_ID */ + H5A_BT2_CORDER, /* 9 - H5B2_ATTR_DENSE_CORDER_ID */ + H5D_BT2, /* 10 - H5B2_CDSET_ID */ + H5D_BT2_FILT /* 11 - H5B2_CDSET_FILT_ID */ }; diff --git a/src/H5B2dbg.c b/src/H5B2dbg.c index cf7301d..1199edf 100644 --- a/src/H5B2dbg.c +++ b/src/H5B2dbg.c @@ -84,11 +84,14 @@ * koziol@ncsa.uiuc.edu * Feb 2 2005 * - *------------------------------------------------------------------------- + * Modifications: + * Vailin Choi; August 2010 + * Created debugging context so that the header can be loaded correctly. + *-------------------------------------------------------------------------- */ herr_t H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, - const H5B2_class_t *type) + const H5B2_class_t *type, haddr_t obj_addr) { H5B2_hdr_t *hdr = NULL; /* B-tree header info */ void *dbg_ctx = NULL; /* v2 B-tree debugging context */ @@ -104,6 +107,7 @@ H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, */ HDassert(f); HDassert(H5F_addr_defined(addr)); + HDassert(H5F_addr_defined(obj_addr)); HDassert(stream); HDassert(indent >= 0); HDassert(fwidth >= 0); @@ -114,7 +118,7 @@ H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, /* Check for debugging context callback available */ if(type->crt_dbg_ctx) { /* Create debugging context */ - if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, addr))) + if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, obj_addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context") } /* end if */ @@ -198,11 +202,14 @@ done: * koziol@ncsa.uiuc.edu * Feb 4 2005 * + * Modifications: + * Vailin Choi; August 2010 + * Created debugging context so that the header can be loaded correctly. *------------------------------------------------------------------------- */ herr_t H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, - const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec, unsigned depth) + const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec, unsigned depth, haddr_t obj_addr) { H5B2_hdr_t *hdr = NULL; /* B-tree header */ H5B2_internal_t *internal = NULL; /* B-tree internal node */ @@ -226,12 +233,13 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) || (NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx)); HDassert(H5F_addr_defined(hdr_addr)); + HDassert(H5F_addr_defined(obj_addr)); HDassert(nrec > 0); /* Check for debugging context callback available */ if(type->crt_dbg_ctx) { /* Create debugging context */ - if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, addr))) + if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, obj_addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context") } /* end if */ @@ -292,7 +300,7 @@ H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, temp_str); HDassert(H5B2_INT_NREC(internal, hdr, u)); (void)(type->debug)(stream, f, dxpl_id, indent + 6, MAX (0, fwidth-6), - H5B2_INT_NREC(internal, hdr, u), NULL); + H5B2_INT_NREC(internal, hdr, u), dbg_ctx); } /* end for */ /* Print final node pointer */ @@ -329,11 +337,14 @@ done: * koziol@ncsa.uiuc.edu * Feb 7 2005 * + * Modifications: + * Vailin Choi; August 2010 + * Created debugging context so that the header can be loaded correctly. *------------------------------------------------------------------------- */ herr_t H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, - const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec) + const H5B2_class_t *type, haddr_t hdr_addr, unsigned nrec, haddr_t obj_addr) { H5B2_hdr_t *hdr = NULL; /* B-tree header */ H5B2_leaf_t *leaf = NULL; /* B-tree leaf node */ @@ -357,12 +368,13 @@ H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, HDassert((type->crt_dbg_ctx && type->dst_dbg_ctx) || (NULL == type->crt_dbg_ctx && NULL == type->dst_dbg_ctx)); HDassert(H5F_addr_defined(hdr_addr)); + HDassert(H5F_addr_defined(obj_addr)); HDassert(nrec > 0); /* Check for debugging context callback available */ if(type->crt_dbg_ctx) { /* Create debugging context */ - if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, addr))) + if(NULL == (dbg_ctx = (type->crt_dbg_ctx)(f, dxpl_id, obj_addr))) HGOTO_ERROR(H5E_BTREE, H5E_CANTGET, FAIL, "unable to create v2 B-tree debugging context") } /* end if */ @@ -412,7 +424,7 @@ H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, temp_str); HDassert(H5B2_LEAF_NREC(leaf, hdr, u)); (void)(type->debug)(stream, f, dxpl_id, indent + 6, MAX (0, fwidth-6), - H5B2_LEAF_NREC(leaf, hdr, u), NULL); + H5B2_LEAF_NREC(leaf, hdr, u), dbg_ctx); } /* end for */ done: diff --git a/src/H5B2pkg.h b/src/H5B2pkg.h index 543fa3f..b820853 100644 --- a/src/H5B2pkg.h +++ b/src/H5B2pkg.h @@ -346,13 +346,13 @@ H5_DLL herr_t H5B2_delete_node(H5B2_hdr_t *hdr, hid_t dxpl_id, unsigned depth, /* Debugging routines for dumping file structures */ H5_DLL herr_t H5B2_hdr_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, - FILE *stream, int indent, int fwidth, const H5B2_class_t *type); + FILE *stream, int indent, int fwidth, const H5B2_class_t *type, haddr_t obj_addr); H5_DLL herr_t H5B2_int_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, const H5B2_class_t *type, - haddr_t hdr_addr, unsigned nrec, unsigned depth); + haddr_t hdr_addr, unsigned nrec, unsigned depth, haddr_t obj_addr); H5_DLL herr_t H5B2_leaf_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth, const H5B2_class_t *type, - haddr_t hdr_addr, unsigned nrec); + haddr_t hdr_addr, unsigned nrec, haddr_t obj_addr); /* Testing routines */ #ifdef H5B2_TESTING diff --git a/src/H5B2private.h b/src/H5B2private.h index 4880ab2..8ec9954 100644 --- a/src/H5B2private.h +++ b/src/H5B2private.h @@ -54,6 +54,8 @@ typedef enum H5B2_subid_t { H5B2_SOHM_INDEX_ID, /* B-tree is an index for shared object header messages */ H5B2_ATTR_DENSE_NAME_ID, /* B-tree is for indexing 'name' field for "dense" attribute storage on objects */ H5B2_ATTR_DENSE_CORDER_ID, /* B-tree is for indexing 'creation order' field for "dense" attribute storage on objects */ + H5B2_CDSET_ID, /* B-tree is for non-filtered chunked dataset storage w/ >1 unlim dims */ + H5B2_CDSET_FILT_ID, /* B-tree is for filtered chunked dataset storage w/ >1 unlim dims */ H5B2_NUM_BTREE_ID /* Number of B-tree IDs (must be last) */ } H5B2_subid_t; @@ -88,13 +90,13 @@ struct H5B2_class_t { /* Extensible array client callback methods */ void *(*crt_context)(void *udata); /* Create context for other client callbacks */ herr_t (*dst_context)(void *ctx); /* Destroy client callback context */ - herr_t (*store)(void *nrecord, const void *udata); /* Store application record in native record table */ - herr_t (*compare)(const void *rec1, const void *rec2); /* Compare two native records */ - herr_t (*encode)(uint8_t *raw, const void *record, void *ctx); /* Encode record from native form to disk storage form */ - herr_t (*decode)(const uint8_t *raw, void *record, void *ctx); /* Decode record from disk storage form to native form */ - herr_t (*debug)(FILE *stream, const H5F_t *f, hid_t dxpl_id, /* Print a record for debugging */ - int indent, int fwidth, const void *record, const void *udata); - void *(*crt_dbg_ctx)(H5F_t *f, hid_t dxpl_id, haddr_t obj_addr); /* Create debugging context */ + herr_t (*store)(void *nrecord, const void *udata); /* Store application record in native record table */ + herr_t (*compare)(const void *rec1, const void *rec2); /* Compare two native records */ + herr_t (*encode)(uint8_t *raw, const void *record, void *ctx); /* Encode record from native form to disk storage form */ + herr_t (*decode)(const uint8_t *raw, void *record, void *ctx); /* Decode record from disk storage form to native form */ + herr_t (*debug)(FILE *stream, const H5F_t *f, hid_t dxpl_id, /* Print a record for debugging */ + int indent, int fwidth, const void *record, const void *ctx); + void *(*crt_dbg_ctx)(H5F_t *f, hid_t dxpl_id, haddr_t obj_addr); /* Create debugging context */ herr_t (*dst_dbg_ctx)(void *dbg_ctx); /* Destroy debugging context */ }; diff --git a/src/H5B2test.c b/src/H5B2test.c index a0508fe..8076343 100644 --- a/src/H5B2test.c +++ b/src/H5B2test.c @@ -333,7 +333,6 @@ H5B2_test_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr) /* Sanity check */ HDassert(f); - HDassert(H5F_addr_defined(addr)); /* Allocate callback context */ if(NULL == (ctx = H5FL_MALLOC(H5B2_test_ctx_t))) diff --git a/src/H5Dbtree2.c b/src/H5Dbtree2.c new file mode 100644 index 0000000..1b014e5 --- /dev/null +++ b/src/H5Dbtree2.c @@ -0,0 +1,1769 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * + * Purpose: v2 B-tree indexing for chunked datasets with > 1 unlimited dimensions. + * Each dataset chunk in the b-tree is identified by its dimensional offset. + * + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5D_PACKAGE /*suppress error about including H5Dpkg */ + + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Dpkg.h" /* Datasets */ +#include "H5FLprivate.h" /* Free Lists */ +#include "H5MFprivate.h" /* File space management */ +#include "H5Vprivate.h" /* Vector and array functions */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ +/* Typedef for non-filtered object's records in v2 B-tree */ +typedef struct H5D_bt2_rec_t { + haddr_t addr; /* Address of the chunk in the file */ + hsize_t offset[H5O_LAYOUT_NDIMS]; /* logical offset to start*/ +} H5D_bt2_rec_t; + +/* Typedef for filtered object's records in v2 B-tree */ +typedef struct H5D_bt2_filt_rec_t { + haddr_t addr; /* Address of the filtered object in the file */ + uint32_t nbytes; /* Length of the filtered object in the file */ + uint32_t filter_mask; /* I/O pipeline filter mask for filtered object in the file */ + hsize_t offset[H5O_LAYOUT_NDIMS]; /* logical offset to start*/ +} H5D_bt2_filt_rec_t; + +/* User data for creating callback context */ +typedef struct H5D_bt2_ctx_ud_t { + const H5F_t *f; /* Pointer to file info */ + uint32_t chunk_size; /* Size of chunk (bytes; for filtered object) */ + unsigned ndims; /* Number of dimensions */ +} H5D_bt2_ctx_ud_t; + +/* The callback context */ +typedef struct H5D_bt2_ctx_t { + size_t sizeof_addr; /* Size of file addresses in the file (bytes) */ + size_t chunk_size_len; /* Size of chunk sizes in the file (bytes) */ + unsigned ndims; /* Number of dimensions */ +} H5D_bt2_ctx_t; + +/* User data for the chunk's removal callback routine */ +typedef struct H5D_bt2_remove_ud_t { + H5F_t *f; /* File pointer for operation */ + hid_t dxpl_id; /* DXPL ID for operation */ + uint32_t unfilt_size; /* Size of unfiltered chunk in bytes */ +} H5D_bt2_remove_ud_t; + +/* Callback info for iteration over chunks in v2 B-tree */ +typedef struct H5D_bt2_it_ud_t { + H5D_chunk_common_ud_t common; /* Common info for v2 B-tree user data (must be first) */ + H5D_chunk_rec_t chunk_rec; /* Generic chunk record for callback */ + hbool_t filtered; /* The chunk is filtered or not */ + H5D_chunk_cb_func_t cb; /* Callback routine for the chunk */ + void *udata; /* User data for the chunk's callback routine */ +} H5D_bt2_it_ud_t; + +/* User data for compare callback */ +typedef struct H5D_bt2_find_ud_t { + void *rec; /* The record to search for */ + unsigned ndims; /* Number of dimensions for the chunked dataset */ +} H5D_bt2_find_ud_t; + +/********************/ +/* Local Prototypes */ +/********************/ + +/* v2 B-tree class for indexing non-filtered chunked datasets */ +static void *H5D_bt2_crt_context(void *udata); +static herr_t H5D_bt2_dst_context(void *ctx); +static void *H5D_bt2_crt_dbg_context(H5F_t *f, hid_t dxpl_id, haddr_t obj_addr); +static herr_t H5D_bt2_dst_dbg_context(void *_u_ctx); + +static herr_t H5D_bt2_store(void *native, const void *udata); +static herr_t H5D_bt2_compare(const void *rec1, const void *rec2); +static herr_t H5D_bt2_encode(uint8_t *raw, const void *native, void *ctx); +static herr_t H5D_bt2_decode(const uint8_t *raw, void *native, void *ctx); +static herr_t H5D_bt2_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *u_ctx); + +/* v2 B-tree class for indexing filtered chunked datasets */ +static herr_t H5D_bt2_filt_store(void *native, const void *udata); +static herr_t H5D_bt2_filt_compare(const void *rec1, const void *rec2); +static herr_t H5D_bt2_filt_encode(uint8_t *raw, const void *native, void *ctx); +static herr_t H5D_bt2_filt_decode(const uint8_t *raw, void *native, void *ctx); +static herr_t H5D_bt2_filt_debug(FILE *stream, const H5F_t *f, hid_t dxpl_id, + int indent, int fwidth, const void *record, const void *u_ctx); + +/* Helper routine */ +static herr_t H5D_bt2_idx_open(const H5D_chk_idx_info_t *idx_info); + +/* Callback for H5B2_iterate() which is called in H5D_bt2_idx_iterate() */ +static int H5D_bt2_idx_iterate_cb(const void *_record, void *_udata); + +/* Callbacks for H5B2_find() which are called in H5D_bt2_idx_get_addr() and H5D_bt2_idx_insert() */ +static herr_t H5D_bt2_found_cb(const void *nrecord, void *op_data); +static herr_t H5D_bt2_filt_found_cb(const void *nrecord, void *op_data); + +/* + * Callbacks for H5B2_remove() and H5B2_delete() which are called + * in H5D_bt2_idx_remove() and H5D_bt2_idx_delete(). + */ +static herr_t H5D_bt2_remove_cb(const void *nrecord, void *_udata); +static herr_t H5D_bt2_filt_remove_cb(const void *nrecord, void *_udata); + +/* Callback for H5B2_modify() which is called in H5D_bt2_idx_insert() */ +static herr_t H5D_bt2_mod_filt_cb(void *_record, void *_op_data, hbool_t *changed); + +/* Chunked dataset I/O ops for v2 B-tree indexing */ +static herr_t H5D_bt2_idx_create(const H5D_chk_idx_info_t *idx_info); +static hbool_t H5D_bt2_idx_is_space_alloc(const H5O_storage_chunk_t *storage); +static herr_t H5D_bt2_idx_insert(const H5D_chk_idx_info_t *idx_info, + H5D_chunk_ud_t *udata); +static herr_t H5D_bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, + H5D_chunk_ud_t *udata); +static int H5D_bt2_idx_iterate(const H5D_chk_idx_info_t *idx_info, + H5D_chunk_cb_func_t chunk_cb, void *chunk_udata); +static herr_t H5D_bt2_idx_remove(const H5D_chk_idx_info_t *idx_info, + H5D_chunk_common_ud_t *udata); +static herr_t H5D_bt2_idx_delete(const H5D_chk_idx_info_t *idx_info); +static herr_t H5D_bt2_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src, + const H5D_chk_idx_info_t *idx_info_dst); +static herr_t H5D_bt2_idx_copy_shutdown(H5O_storage_chunk_t *storage_src, + H5O_storage_chunk_t *storage_dst, hid_t dxpl_id); +static herr_t H5D_bt2_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *size); +static herr_t H5D_bt2_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr); +static herr_t H5D_bt2_idx_dump(const H5O_storage_chunk_t *storage, + FILE *stream); +static herr_t H5D_bt2_idx_dest(const H5D_chk_idx_info_t *idx_info); + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Chunked dataset I/O ops for v2 B-tree indexing */ +const H5D_chunk_ops_t H5D_COPS_BT2[1] = {{ + FALSE, + NULL, + H5D_bt2_idx_create, + H5D_bt2_idx_is_space_alloc, + H5D_bt2_idx_insert, + H5D_bt2_idx_get_addr, + NULL, + H5D_bt2_idx_iterate, + H5D_bt2_idx_remove, + H5D_bt2_idx_delete, + H5D_bt2_idx_copy_setup, + H5D_bt2_idx_copy_shutdown, + H5D_bt2_idx_size, + H5D_bt2_idx_reset, + NULL, + NULL, + H5D_bt2_idx_dump, + H5D_bt2_idx_dest +}}; + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/* v2 B-tree class for indexing non-filtered chunked datasets */ +const H5B2_class_t H5D_BT2[1] = {{ /* B-tree class information */ + H5B2_CDSET_ID, /* Type of B-tree */ + "H5B2_CDSET_ID", /* Name of B-tree class */ + sizeof(H5D_bt2_rec_t), /* Size of native record */ + H5D_bt2_crt_context, /* Create client callback context */ + H5D_bt2_dst_context, /* Destroy client callback context */ + H5D_bt2_store, /* Record storage callback */ + H5D_bt2_compare, /* Record comparison callback */ + H5D_bt2_encode, /* Record encoding callback */ + H5D_bt2_decode, /* Record decoding callback */ + H5D_bt2_debug, /* Record debugging callback */ + H5D_bt2_crt_dbg_context, /* Create debugging context */ + H5D_bt2_dst_dbg_context /* Destroy debugging context */ +}}; + +/* v2 B-tree class for indexing filtered chunked datasets */ +const H5B2_class_t H5D_BT2_FILT[1] = {{ /* B-tree class information */ + H5B2_CDSET_FILT_ID, /* Type of B-tree */ + "H5B2_CDSET_FILT_ID", /* Name of B-tree class */ + sizeof(H5D_bt2_filt_rec_t), /* Size of native record */ + H5D_bt2_crt_context, /* Create client callback context */ + H5D_bt2_dst_context, /* Destroy client callback context */ + H5D_bt2_filt_store, /* Record storage callback */ + H5D_bt2_filt_compare, /* Record comparison callback */ + H5D_bt2_filt_encode, /* Record encoding callback */ + H5D_bt2_filt_decode, /* Record decoding callback */ + H5D_bt2_filt_debug, /* Record debugging callback */ + H5D_bt2_crt_dbg_context, /* Create debugging context */ + H5D_bt2_dst_dbg_context /* Destroy debugging context */ +}}; + +/* Declare a free list to manage the H5D_bt2_ctx_t struct */ +H5FL_DEFINE_STATIC(H5D_bt2_ctx_t); +/* Declare a free list to manage the H5D_bt2_ctx_ud_t struct */ +H5FL_DEFINE_STATIC(H5D_bt2_ctx_ud_t); + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_crt_context + * + * Purpose: Create client callback context + * + * Return: Success: non-NULL + * Failure: NULL + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static void * +H5D_bt2_crt_context(void *_udata) +{ + H5D_bt2_ctx_ud_t *udata = (H5D_bt2_ctx_ud_t *)_udata; /* User data for building callback context */ + H5D_bt2_ctx_t *ctx; /* Callback context structure */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_crt_context) + + /* Sanity check */ + HDassert(udata); + HDassert(udata->f); + HDassert(udata->ndims > 0 && udata->ndims < H5O_LAYOUT_NDIMS); + + /* Allocate callback context */ + if(NULL == (ctx = H5FL_MALLOC(H5D_bt2_ctx_t))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, NULL, "can't allocate callback context") + + /* Determine the size of addresses and # of dimensions for the dataset */ + ctx->sizeof_addr = H5F_SIZEOF_ADDR(udata->f); + ctx->ndims = udata->ndims; + + /* + * Compute the size required for encoding the size of a chunk, + * allowing for an extra byte, in case the filter makes the chunk larger. + */ + ctx->chunk_size_len = 1 + ((H5V_log2_gen((uint64_t)udata->chunk_size) + 8) / 8); + if(ctx->chunk_size_len > 8) + ctx->chunk_size_len = 8; + + /* Set return value */ + ret_value = ctx; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_crt_context() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_dst_context + * + * Purpose: Destroy client callback context + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_dst_context(void *_ctx) +{ + H5D_bt2_ctx_t *ctx = (H5D_bt2_ctx_t *)_ctx; /* Callback context structure */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_dst_context) + + /* Sanity check */ + HDassert(ctx); + + /* Release callback context */ + ctx = H5FL_FREE(H5D_bt2_ctx_t, ctx); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_dst_context() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_store + * + * Purpose: Store native information into record for v2 B-tree + * (non-filtered) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_store(void *record, const void *_udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_store) + + const H5D_bt2_find_ud_t *udata = (const H5D_bt2_find_ud_t *)_udata; /* User data */ + + *(H5D_bt2_rec_t *)record = *(const H5D_bt2_rec_t *)udata->rec; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_store() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_filt_store + * + * Purpose: Store native information into record for v2 B-tree + * (filtered) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_filt_store(void *record, const void *_udata) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_filt_store) + + const H5D_bt2_find_ud_t *udata = (const H5D_bt2_find_ud_t *)_udata; /* User data */ + + *(H5D_bt2_filt_rec_t *)record = *(const H5D_bt2_filt_rec_t *)udata->rec; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_filt_store() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_compare + * + * Purpose: Compare two native information records, according to some key + * (non-filtered) + * + * Return: <0 if rec1 < rec2 + * =0 if rec1 == rec2 + * >0 if rec1 > rec2 + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_compare(const void *_udata, const void *_rec2) +{ + const H5D_bt2_find_ud_t *udata = (const H5D_bt2_find_ud_t *)_udata; /* User data */ + + const H5D_bt2_rec_t *rec1 = (const H5D_bt2_rec_t *)udata->rec; /* The native record */ + const H5D_bt2_rec_t *rec2 = (const H5D_bt2_rec_t *)_rec2; /* The native record */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_compare) + + HDassert(rec1); + HDassert(rec2); + + /* Compare the offsets but ignore the other fields */ + ret_value = H5V_vector_cmp_u(udata->ndims, rec1->offset, rec2->offset); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_compare() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_filt_compare + * + * Purpose: Compare two native information records, according to some key + * (filtered) + * + * Return: <0 if rec1 < rec2 + * =0 if rec1 == rec2 + * >0 if rec1 > rec2 + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_filt_compare(const void *_udata, const void *_rec2) +{ + const H5D_bt2_find_ud_t *udata = (const H5D_bt2_find_ud_t *)_udata; /* User data */ + + const H5D_bt2_filt_rec_t *rec1 = (const H5D_bt2_filt_rec_t *)udata->rec; /* The native record */ + const H5D_bt2_filt_rec_t *rec2 = (const H5D_bt2_filt_rec_t *)_rec2; /* The native record */ + herr_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_filt_compare) + + HDassert(rec1); + HDassert(rec2); + + /* Compare the offsets but ignore the other fields */ + ret_value = H5V_vector_cmp_u(udata->ndims, rec1->offset, rec2->offset); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_filt_compare() */ + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_encode + * + * Purpose: Encode native information into raw form for storing on disk + * (non-filtered) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_encode(uint8_t *raw, const void *_record, void *_ctx) +{ + H5D_bt2_ctx_t *ctx = (H5D_bt2_ctx_t *)_ctx; /* Callback context structure */ + const H5D_bt2_rec_t *record = (const H5D_bt2_rec_t *)_record; /* The native record */ + unsigned i; /* Local index varible */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_encode) + + /* Sanity check */ + HDassert(ctx); + + /* Encode the record's fields */ + H5F_addr_encode_len(ctx->sizeof_addr, &raw, record->addr); + for(i = 0; i < ctx->ndims; i++) + UINT64ENCODE(raw, record->offset[i]); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_encode() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_filt_encode + * + * Purpose: Encode native information into raw form for storing on disk + * (filtered) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_filt_encode(uint8_t *raw, const void *_record, void *_ctx) +{ + H5D_bt2_ctx_t *ctx = (H5D_bt2_ctx_t *)_ctx; /* Callback context structure */ + const H5D_bt2_filt_rec_t *record = (const H5D_bt2_filt_rec_t *)_record; /* The native record */ + unsigned i; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_filt_encode) + + /* Sanity check */ + HDassert(ctx); + + /* Encode the record's fields */ + H5F_addr_encode_len(ctx->sizeof_addr, &raw, record->addr); + UINT64ENCODE_VAR(raw, record->nbytes, ctx->chunk_size_len); + UINT32ENCODE(raw, record->filter_mask); + for(i = 0; i < ctx->ndims; i++) + UINT64ENCODE(raw, record->offset[i]); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_filt_encode() */ + + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_decode + * + * Purpose: Decode raw disk form of record into native form + * (non-filtered) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_decode(const uint8_t *raw, void *_record, void *_ctx) +{ + H5D_bt2_ctx_t *ctx = (H5D_bt2_ctx_t *)_ctx; /* Callback context structure */ + H5D_bt2_rec_t *record = (H5D_bt2_rec_t *)_record; /* The native record */ + unsigned i; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_decode) + + /* Sanity check */ + HDassert(ctx); + + /* Decode the record's fields */ + H5F_addr_decode_len(ctx->sizeof_addr, &raw, &record->addr); + for(i = 0; i < ctx->ndims; i++) + UINT64DECODE(raw, record->offset[i]); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_filt_decode + * + * Purpose: Decode raw disk form of record into native form + * (filtered) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_filt_decode(const uint8_t *raw, void *_record, void *_ctx) +{ + H5D_bt2_ctx_t *ctx = (H5D_bt2_ctx_t *)_ctx; /* Callback context structure */ + H5D_bt2_filt_rec_t *record = (H5D_bt2_filt_rec_t *)_record; /* The native record */ + unsigned i; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_filt_decode) + + /* Sanity check */ + HDassert(ctx); + + /* Decode the record's fields */ + H5F_addr_decode_len(ctx->sizeof_addr, &raw, &record->addr); + UINT64DECODE_VAR(raw, record->nbytes, ctx->chunk_size_len); + UINT32DECODE(raw, record->filter_mask); + for(i = 0; i < ctx->ndims; i++) + UINT64DECODE(raw, record->offset[i]); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_filt_decode() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_debug + * + * Purpose: Debug native form of record (non-filtered) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_record, const void *_u_ctx) +{ + const H5D_bt2_rec_t *record = (const H5D_bt2_rec_t *)_record; /* The native record */ + const H5D_bt2_ctx_ud_t *u_ctx = (const H5D_bt2_ctx_ud_t *)_u_ctx; /* User data for creating callback context */ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_debug) + + HDassert(record); + + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Chunk address:", (unsigned)record->addr); + HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Logical offset:"); + for(u = 0; u < u_ctx->ndims; u++) + HDfprintf(stream, "%s%Hd", u?", ":"", record->offset[u]); + HDfputs("}\n", stream); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_debug() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_filt_debug + * + * Purpose: Debug native form of record (filterd) + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_filt_debug(FILE *stream, const H5F_t UNUSED *f, hid_t UNUSED dxpl_id, + int indent, int fwidth, const void *_record, const void *_u_ctx) +{ + const H5D_bt2_filt_rec_t *record = (const H5D_bt2_filt_rec_t *)_record; /* The native record */ + const H5D_bt2_ctx_ud_t *u_ctx = (const H5D_bt2_ctx_ud_t *)_u_ctx; /* User data for creating callback context */ + unsigned u; /* Local index variable */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_filt_debug) + + HDassert(record); + + HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Chunk address:", (unsigned)record->addr); + HDfprintf(stream, "%*s%-*s %u bytes\n", indent, "", fwidth, "Chunk size:", (unsigned)record->nbytes); + HDfprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth, "Filter mask:", record->filter_mask); + + HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Logical offset:"); + for(u = 0; u < u_ctx->ndims; u++) + HDfprintf(stream, "%s%Hd", u?", ":"", record->offset[u]); + HDfputs("}\n", stream); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_filt_debug() */ + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_crt_dbg_context + * + * Purpose: Create user data for debugged callback context + * + * Return: Success: non-NULL + * Failure: NULL + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static void * +H5D_bt2_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t obj_addr) +{ + H5D_bt2_ctx_ud_t *u_ctx; /* User data for creating callback context */ + H5O_loc_t obj_loc; /* Pointer to an object's location */ + hbool_t obj_opened = FALSE; /* Flag to indicate that the object header was opened */ + H5O_layout_t layout; /* Layout message */ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_crt_dbg_context) + + /* Sanity check */ + HDassert(f); + HDassert(H5F_addr_defined(obj_addr)); + + /* Set up the object header location info */ + H5O_loc_reset(&obj_loc); + obj_loc.file = f; + obj_loc.addr = obj_addr; + + /* Open the object header where the layout message resides */ + if(H5O_open(&obj_loc) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "can't open object header") + obj_opened = TRUE; + + /* Read the layout message */ + if(NULL == H5O_msg_read(&obj_loc, H5O_LAYOUT_ID, &layout, dxpl_id)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't get layout info") + + /* close the object header */ + if(H5O_close(&obj_loc) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, NULL, "can't close object header") + + /* Allocate structure for storing user data to create callback context */ + if(NULL == (u_ctx = H5FL_MALLOC(H5D_bt2_ctx_ud_t))) + HGOTO_ERROR(H5E_HEAP, H5E_CANTALLOC, NULL, "can't allocate user data context structure ") + + /* Set information for context structure */ + u_ctx->f = f; + u_ctx->chunk_size = layout.u.chunk.size; + u_ctx->ndims = layout.u.chunk.ndims - 1; + + /* Set return value */ + ret_value = u_ctx; + +done: + /* Cleanup on error */ + if(ret_value == NULL) { + /* Release context structure */ + if(u_ctx) + u_ctx = H5FL_FREE(H5D_bt2_ctx_ud_t, u_ctx); + + /* Close object header */ + if(obj_opened) { + if(H5O_close(&obj_loc) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, NULL, "can't close object header") + } /* end if */ + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_crt_dbg_context() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_dst_dbg_context + * + * Purpose: Destroy client callback context + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_dst_dbg_context(void *_u_ctx) +{ + H5D_bt2_ctx_ud_t *u_ctx = (H5D_bt2_ctx_ud_t *)_u_ctx; /* User data for creating callback context */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_dst_dbg_context) + + /* Sanity check */ + HDassert(u_ctx); + + /* Release user data for creating callback context */ + u_ctx = H5FL_FREE(H5D_bt2_ctx_ud_t, u_ctx); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_dst_dbg_context() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_open() + * + * Purpose: Opens an existing v2 B-tree. + * + * Note: This information is passively initialized from each index + * operation callback because those abstract chunk index operations + * are designed to work with the v2 B-tree chunk indices also, + * which don't require an 'open' for the data structure. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_open(const H5D_chk_idx_info_t *idx_info) +{ + H5D_bt2_ctx_ud_t u_ctx; /* user data for creating context */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_open) + + /* Check args */ + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(H5D_CHUNK_IDX_BT2 == idx_info->layout->idx_type); + HDassert(idx_info->storage); + HDassert(H5F_addr_defined(idx_info->storage->idx_addr)); + HDassert(NULL == idx_info->storage->u.btree2.bt2); + + /* Set up the user data */ + u_ctx.f = idx_info->f; + u_ctx.ndims = idx_info->layout->ndims - 1; + u_ctx.chunk_size = idx_info->layout->size; + + /* Open v2 B-tree for the chunk index */ + if(NULL == (idx_info->storage->u.btree2.bt2 = H5B2_open(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr , &u_ctx))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open v2 B-tree for tracking chunked dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_open() */ + + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_create + * + * Purpose: Create the v2 B-tree for tracking dataset chunks + * + * Return: SUCCEED/FAIL + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_create(const H5D_chk_idx_info_t *idx_info) +{ + H5B2_create_t bt2_cparam; /* v2 B-tree creation parameters */ + H5D_bt2_ctx_ud_t u_ctx; /* data for context call */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_create) + + /* Check args */ + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(idx_info->storage); + HDassert(!H5F_addr_defined(idx_info->storage->idx_addr)); + + bt2_cparam.rrec_size = H5F_SIZEOF_ADDR(idx_info->f) /* Address of chunk */ + + (idx_info->layout->ndims - 1) * 8; /* # of dimensions x 64-bit chunk offsets */ + + if(idx_info->pline->nused > 0) { + unsigned chunk_size_len; /* Size of encoded chunk size */ + /* + * Compute the size required for encoding the size of a chunk, + * allowing for an extra byte, in case the filter makes the chunk larger. + */ + chunk_size_len = 1 + ((H5V_log2_gen((uint64_t)idx_info->layout->size) + 8) / 8); + if(chunk_size_len > 8) + chunk_size_len = 8; + + bt2_cparam.rrec_size += chunk_size_len + 4; /* Size of encoded chunk size & filter mask */ + bt2_cparam.cls = H5D_BT2_FILT; + } else + bt2_cparam.cls = H5D_BT2; + + bt2_cparam.node_size = idx_info->layout->u.btree2.cparam.node_size; + bt2_cparam.split_percent = idx_info->layout->u.btree2.cparam.split_percent; + bt2_cparam.merge_percent = idx_info->layout->u.btree2.cparam.merge_percent; + + u_ctx.f = idx_info->f; + u_ctx.ndims = idx_info->layout->ndims - 1; + u_ctx.chunk_size = idx_info->layout->size; + + /* Create the v2 B-tree for the chunked dataset */ + if(NULL == (idx_info->storage->u.btree2.bt2 = H5B2_create(idx_info->f, idx_info->dxpl_id, &bt2_cparam, &u_ctx))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCREATE, FAIL, "can't create v2 B-tree for tracking chunked dataset") + + /* Retrieve the v2 B-tree's address in the file */ + if(H5B2_get_addr(idx_info->storage->u.btree2.bt2, &(idx_info->storage->idx_addr)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get v2 B-tree address for tracking chunked dataset") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_is_space_alloc + * + * Purpose: Query if space is allocated for index method + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static hbool_t +H5D_bt2_idx_is_space_alloc(const H5O_storage_chunk_t *storage) +{ + hbool_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_idx_is_space_alloc) + + /* Check args */ + HDassert(storage); + + /* Set return value */ + ret_value = (hbool_t)H5F_addr_defined(storage->idx_addr); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_is_space_alloc() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_found_cb + * + * Purpose: Retrieve record (non-filtered) for dataset chunk when it is found + * in the v2 B-tree. + * This is the callback for H5B2_find() which is called in + * H5D_bt2_idx_get_addr() and H5D_bt2_idx_insert(). + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_found_cb(const void *nrecord, void *op_data) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_found_cb) + + *(H5D_bt2_rec_t *)op_data = *(const H5D_bt2_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_found_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_filt_found_cb + * + * Purpose: Retrieve record (filtered) for dataset chunk when it is found + * in the v2 B-tree. + * This is the callback for H5B2_find() which is called in + * H5D_bt2_idx_get_addr() and H5D_bt2_idx_insert(). + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_filt_found_cb(const void *nrecord, void *op_data) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_filt_found_cb) + + *(H5D_bt2_filt_rec_t *)op_data = *(const H5D_bt2_filt_rec_t *)nrecord; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* H5D_bt2_filt_found_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_mod_filt_cb + * + * Purpose: Modify record (filtered) for dataset chunk when it is found + * in the v2 B-tree. + * This is the callback for H5B2_modify() which is called in + * H5D_bt2_idx_insert(). + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_mod_filt_cb(void *_record, void *_op_data, hbool_t *changed) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_mod_filt_cb) + + *(H5D_bt2_filt_rec_t *)_record = *(H5D_bt2_filt_rec_t *)_op_data; + + /* Note that the record changed */ + *changed = TRUE; + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5D_bt2_mod_filt_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_insert + * + * Purpose: A non-filtered chunk: + * Should not exist + * Allocate the chunk and pass chunk address back up + * A filtered chunk: + * If it was not found, create the chunk and pass chunk address back up + * If it was found but its size changed, reallocate the chunk and pass chunk address back up + * If it was found but its size was the same, pass chunk address back up + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_insert(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata) +{ + H5B2_t *bt2_cdset = NULL; /* v2 B-tree handle for indexing chunks */ + H5D_bt2_find_ud_t bt2_udata; + unsigned u; /* local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_insert) + + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(idx_info->storage); + HDassert(H5F_addr_defined(idx_info->storage->idx_addr)); + HDassert(udata); + + if(NULL == idx_info->storage->u.btree2.bt2) { + /* Open existing v2 B-tree */ + if(H5D_bt2_idx_open(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open v2 B-tree") + } /* end if */ + + bt2_cdset = idx_info->storage->u.btree2.bt2; + + /* Check for filters on chunks */ + if(idx_info->pline->nused > 0) { /* filtered chunk */ + unsigned allow_chunk_size_len; /* Allowed size of encoded chunk size */ + unsigned new_chunk_size_len; /* Size of encoded chunk size */ + H5D_bt2_filt_rec_t rec; /* Record for searching object */ + H5D_bt2_filt_rec_t found_rec; /* Record found from searching for object */ + + /* + * Compute the size required for encoding the size of a chunk, + * allowing for an extra byte, in case the filter makes the chunk larger. + */ + allow_chunk_size_len = 1 + ((H5V_log2_gen((uint64_t)idx_info->layout->size) + 8) / 8); + if(allow_chunk_size_len > 8) + allow_chunk_size_len = 8; + + /* Compute encoded size of chunk */ + new_chunk_size_len = (H5V_log2_gen((uint64_t)udata->nbytes) + 8) / 8; + if(new_chunk_size_len > 8) + HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "encoded chunk size is more than 8 bytes?!?") + + /* Check if the chunk became too large to be encoded */ + if(new_chunk_size_len > allow_chunk_size_len) + HGOTO_ERROR(H5E_DATASET, H5E_BADRANGE, FAIL, "chunk size can't be encoded") + + /* Initialize record information */ + rec.nbytes = udata->nbytes; + rec.filter_mask = udata->filter_mask; + for(u = 0; u < (idx_info->layout->ndims - 1); u++) + rec.offset[u] = udata->common.offset[u]; + + found_rec.addr = HADDR_UNDEF; + found_rec.nbytes = 0; + found_rec.filter_mask = 0; + + /* Prepare user data for compare callback */ + bt2_udata.rec = &rec; + bt2_udata.ndims = idx_info->layout->ndims - 1; + + /* Try to find the chunked record */ + if(H5B2_find(bt2_cdset, idx_info->dxpl_id, &bt2_udata, H5D_bt2_filt_found_cb, &found_rec) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") + + /* Check for previous chunk */ + if(H5F_addr_defined(found_rec.addr)) { /* Found it */ + /* Sanity check */ + HDassert(!H5F_addr_defined(udata->addr) || H5F_addr_eq(udata->addr, found_rec.addr)); + + /* Check for chunk being same size */ + if(udata->nbytes != found_rec.nbytes) { + + H5_CHECK_OVERFLOW(found_rec.nbytes, uint32_t, hsize_t); + + /* Free the original chunk */ + if(H5MF_xfree(idx_info->f, H5FD_MEM_DRAW, idx_info->dxpl_id, found_rec.addr, (hsize_t)found_rec.nbytes) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to free chunk") + + /* Allocate a new chunk */ + H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t); + rec.addr = udata->addr = H5MF_alloc(idx_info->f, H5FD_MEM_DRAW, idx_info->dxpl_id, (hsize_t)udata->nbytes); + + if(!H5F_addr_defined(udata->addr)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk") + + /* Modify record for object in v2 B-tree */ + if(H5B2_modify(bt2_cdset, idx_info->dxpl_id, &bt2_udata, H5D_bt2_mod_filt_cb, &rec) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "unable to modify record in v2 B-tree") + + } else + /* Don't need to reallocate chunk, but send its address back up */ + udata->addr = found_rec.addr; + } else { /* Not found */ + H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t); + + /* Allocate a new chunk */ + rec.addr = udata->addr = H5MF_alloc(idx_info->f, H5FD_MEM_DRAW, idx_info->dxpl_id, (hsize_t)udata->nbytes); + if(!H5F_addr_defined(udata->addr)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk") + + /* Insert record for object in v2 B-tree */ + if(H5B2_insert(bt2_cdset, idx_info->dxpl_id, &bt2_udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "couldn't insert record in v2 B-tree") + } + } else { /* non-filtered chunk */ + H5D_bt2_rec_t rec; + + /* The record should not be there */ + HDassert(!H5F_addr_defined(udata->addr)); + HDassert(udata->nbytes == idx_info->layout->size); + + /* Prepare user data for compare callback */ + bt2_udata.rec = &rec; + bt2_udata.ndims = idx_info->layout->ndims - 1; + + for(u = 0; u < (idx_info->layout->ndims - 1); u++) + rec.offset[u] = udata->common.offset[u]; + + /* Allocate storage for the new chunk */ + H5_CHECK_OVERFLOW(udata->nbytes, uint32_t, hsize_t); + rec.addr = udata->addr = H5MF_alloc(idx_info->f, H5FD_MEM_DRAW, idx_info->dxpl_id, (hsize_t)udata->nbytes); + + if(!H5F_addr_defined(udata->addr)) + HGOTO_ERROR(H5E_DATASET, H5E_CANTALLOC, FAIL, "unable to allocate chunk") + + /* Insert record for object in v2 B-tree */ + if(H5B2_insert(bt2_cdset, idx_info->dxpl_id, &bt2_udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, FAIL, "couldn't insert record in v2 B-tree") + } /* end else */ + HDassert(H5F_addr_defined(udata->addr)); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_idx_insert() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_get_addr + * + * Purpose: Get the file address of a chunk if file space has been + * assigned. Save the retrieved information in the udata + * supplied. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_get_addr(const H5D_chk_idx_info_t *idx_info, H5D_chunk_ud_t *udata) +{ + H5B2_t *bt2_cdset = NULL; /* v2 B-tree handle for indexing chunks */ + unsigned u; /* Local index variable */ + H5D_bt2_find_ud_t bt2_udata; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_get_addr) + + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(idx_info->layout->ndims > 0); + HDassert(idx_info->storage); + HDassert(H5F_addr_defined(idx_info->storage->idx_addr)); + HDassert(udata); + + if(NULL == idx_info->storage->u.btree2.bt2) { + /* Open existing v2 B-tree */ + if(H5D_bt2_idx_open(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open v2 B-tree") + } /* end if */ + + bt2_cdset = idx_info->storage->u.btree2.bt2; + + /* Check for filters on chunks */ + if(idx_info->pline->nused > 0) { /* filtered chunk */ + H5D_bt2_filt_rec_t search_rec; /* Record for searching object */ + H5D_bt2_filt_rec_t found_rec; /* Record found from searching for object */ + + /* Set the chunk offset to be searched for */ + for(u = 0; u < (idx_info->layout->ndims - 1); u++) + search_rec.offset[u] = udata->common.offset[u]; + + found_rec.addr = HADDR_UNDEF; + found_rec.nbytes = 0; + found_rec.filter_mask = 0; + + /* Prepare user data for compare callback */ + bt2_udata.rec = &search_rec; + bt2_udata.ndims = idx_info->layout->ndims - 1; + + /* Go get chunk information from v2 B-tree */ + if(H5B2_find(bt2_cdset, idx_info->dxpl_id, &bt2_udata, H5D_bt2_filt_found_cb, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") + + /* Set info for the chunk */ + udata->addr = found_rec.addr; + udata->nbytes = found_rec.nbytes; + udata->filter_mask = found_rec.filter_mask; + } else { /* non-filtered chunk */ + H5D_bt2_rec_t search_rec; /* Record for searching object */ + H5D_bt2_rec_t found_rec; /* Record found from searching for object */ + + /* Set the chunk offset to be searched for */ + for(u = 0; u < (idx_info->layout->ndims - 1); u++) + search_rec.offset[u] = udata->common.offset[u]; + + search_rec.addr = HADDR_UNDEF; + found_rec.addr = HADDR_UNDEF; + + /* Prepare user data for compare callback */ + bt2_udata.rec = &search_rec; + bt2_udata.ndims = idx_info->layout->ndims - 1; + + /* Go get chunk information from v2 B-tree */ + if(H5B2_find(bt2_cdset, idx_info->dxpl_id, &bt2_udata, H5D_bt2_found_cb, &found_rec) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "can't find object in v2 B-tree") + + udata->addr = found_rec.addr; + + /* Update the other (constant) information for the chunk */ + udata->nbytes = idx_info->layout->size; + udata->filter_mask = 0; + } + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_idx_get_addr() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_iterate_cb + * + * Purpose: Translate the B-tree specific chunk record into a generic + * form and make the callback to the generic chunk callback + * routine. + * This is the callback for H5B2_iterate() which is called in + * H5D_bt2_idx_iterate(). + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +/* ARGSUSED */ +static int +H5D_bt2_idx_iterate_cb(const void *_record, void *_udata) +{ + H5D_bt2_it_ud_t *udata = (H5D_bt2_it_ud_t *)_udata; /* User data */ + unsigned u; /* Local index variable */ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOERR(H5D_bt2_idx_iterate_cb, -) + + /* Compose generic chunk record for callback */ + if(udata->filtered) { /* filtered record */ + const H5D_bt2_filt_rec_t *filt_rec = (const H5D_bt2_filt_rec_t *)_record; + + udata->chunk_rec.chunk_addr = filt_rec->addr; + udata->chunk_rec.nbytes = filt_rec->nbytes; + udata->chunk_rec.filter_mask = filt_rec->filter_mask; + for(u = 0; u < (udata->common.layout->ndims - 1); u++) + udata->chunk_rec.offset[u] = filt_rec->offset[u]; + } else { /* non-filtered record */ + const H5D_bt2_rec_t *rec = (const H5D_bt2_rec_t *)_record; + + udata->chunk_rec.chunk_addr = rec->addr; + udata->chunk_rec.nbytes = udata->common.layout->size; + udata->chunk_rec.filter_mask = 0; + for(u = 0; u < (udata->common.layout->ndims - 1); u++) + udata->chunk_rec.offset[u] = rec->offset[u]; + } + + /* Make "generic chunk" callback */ + if((ret_value = (udata->cb)(&udata->chunk_rec, udata->udata)) < 0) + HERROR(H5E_DATASET, H5E_CALLBACK, "failure in generic chunk iterator callback"); + + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_idx_iterate_cb() */ + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_iterate + * + * Purpose: Iterate over the chunks in an index, making a callback + * for each one. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static int +H5D_bt2_idx_iterate(const H5D_chk_idx_info_t *idx_info, + H5D_chunk_cb_func_t chunk_cb, void *chunk_udata) +{ + H5D_bt2_it_ud_t udata; /* User data for B-tree iterator callback */ + H5B2_t *bt2_cdset = NULL; /* v2 B-tree handle for indexing chunks */ + int ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_iterate) + + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(idx_info->storage); + HDassert(H5F_addr_defined(idx_info->storage->idx_addr)); + HDassert(chunk_cb); + HDassert(chunk_udata); + + /* Initialize user data */ + HDmemset(&udata, 0, sizeof udata); + udata.common.layout = idx_info->layout; + udata.common.storage = idx_info->storage; + udata.filtered = idx_info->pline->nused > 0; + HDmemset(&udata.chunk_rec, 0, sizeof(udata.chunk_rec)); + + if(NULL == idx_info->storage->u.btree2.bt2) { + /* Open existing v2 B-tree */ + if(H5D_bt2_idx_open(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open v2 B-tree") + } /* end if */ + + bt2_cdset = idx_info->storage->u.btree2.bt2; + + udata.cb = chunk_cb; + udata.udata = chunk_udata; + + /* Iterate over the records in the v2 B-tree */ + if((ret_value = H5B2_iterate(bt2_cdset, idx_info->dxpl_id, H5D_bt2_idx_iterate_cb, &udata)) < 0) + HERROR(H5E_DATASET, H5E_BADITER, "unable to iterate over v2 B-tree for dataset chunks"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_iterate() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_remove_cb() + * + * Purpose: Free space for 'dataset chunk' object as v2 B-tree + * is being deleted or v2 B-tree node is removed. + * This is the callback for H5B2_remove() and H5B2_delete() which + * which are called in H5D_bt2_idx_remove() and H5D_bt2_idx_delete(). + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_remove_cb(const void *record, void *_udata) +{ + H5D_bt2_remove_ud_t *udata = (H5D_bt2_remove_ud_t *)_udata; /* User data for removal callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_remove_cb) + + /* Free the space in the file for the object being removed */ + H5_CHECK_OVERFLOW(udata->unfilt_size, uint32_t, hsize_t); + if(H5MF_xfree(udata->f, H5FD_MEM_DRAW, udata->dxpl_id, ((const H5D_bt2_rec_t *)record)->addr, (hsize_t)udata->unfilt_size) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "unable to free chunk") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_remove_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_filt_remove_cb + * + * Purpose: Free space for 'filtered dataset chunk' object as v2 B-tree + * is being deleted or v2 B-tree node is removed + * This is the callback for H5B2_remove() and H5B2_delete() which + * which are called in H5D_bt2_idx_remove() and H5D_bt2_idx_delete(). + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_filt_remove_cb(const void *_record, void *_udata) +{ + H5D_bt2_remove_ud_t *udata = (H5D_bt2_remove_ud_t *)_udata; /* User data for removal callback */ + const H5D_bt2_filt_rec_t *record = (const H5D_bt2_filt_rec_t *)_record; /* The native record */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_filt_remove_cb) + + /* Free the space in the file for the object being removed */ + H5_CHECK_OVERFLOW(record->nbytes, uint32_t, hsize_t); + if(H5MF_xfree(udata->f, H5FD_MEM_DRAW, udata->dxpl_id, record->addr, (hsize_t)record->nbytes) < 0) + HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free chunk") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_filt_remove_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_remove + * + * Purpose: Remove chunk from index. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_remove(const H5D_chk_idx_info_t *idx_info, H5D_chunk_common_ud_t *udata) +{ + H5D_bt2_remove_ud_t remove_udata; /* User data for removal callback */ + H5B2_t *bt2_cdset = NULL; /* v2 B-tree handle for indexing chunks */ + H5D_bt2_find_ud_t bt2_udata; + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_remove) + + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(idx_info->storage); + HDassert(H5F_addr_defined(idx_info->storage->idx_addr)); + HDassert(udata); + + if(NULL == idx_info->storage->u.btree2.bt2) { + /* Open existing v2 B-tree */ + if(H5D_bt2_idx_open(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open v2 B-tree") + } /* end if */ + + bt2_cdset = idx_info->storage->u.btree2.bt2; + + /* Initialize user data for removal callback */ + remove_udata.f = idx_info->f; + remove_udata.dxpl_id = idx_info->dxpl_id; + + /* Remove the record for the "dataset chunk" object from the v2 B-tree */ + /* (space in the file for the object is freed in the 'remove' callback) */ + if(idx_info->pline->nused > 0) { /* filtered chunk */ + H5D_bt2_filt_rec_t search_rec; /* Record for searching for object */ + + /* Initialize the record to search for */ + for(u = 0; u < (idx_info->layout->ndims - 1); u++) + search_rec.offset[u] = udata->offset[u]; + + bt2_udata.rec = &search_rec; + bt2_udata.ndims = idx_info->layout->ndims - 1; + + if(H5B2_remove(bt2_cdset, idx_info->dxpl_id, &bt2_udata, H5D_bt2_filt_remove_cb, &remove_udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") + } else { /* non-filtered chunk */ + H5D_bt2_rec_t search_rec; /* Record for searching for object */ + + remove_udata.unfilt_size = idx_info->layout->size; + + /* Initialize the record to search for */ + for(u = 0; u < (idx_info->layout->ndims - 1); u++) + search_rec.offset[u] = udata->offset[u]; + + bt2_udata.rec = &search_rec; + bt2_udata.ndims = idx_info->layout->ndims - 1; + + if(H5B2_remove(bt2_cdset, idx_info->dxpl_id, &bt2_udata, H5D_bt2_remove_cb, &remove_udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREMOVE, FAIL, "can't remove object from B-tree") + } /* end else */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5D_bt2_idx_remove() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_delete + * + * Purpose: Delete index and raw data storage for entire dataset + * (i.e. all chunks) + * + * Return: Success: Non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_delete(const H5D_chk_idx_info_t *idx_info) +{ + H5D_bt2_remove_ud_t remove_udata; /* User data for removal callback */ + H5B2_remove_t remove_op; /* The removal callback */ + H5D_bt2_ctx_ud_t u_ctx; /* data for context call */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_delete) + + /* Sanity checks */ + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(idx_info->storage); + + /* Check if the index data structure has been allocated */ + if(H5F_addr_defined(idx_info->storage->idx_addr)) { + + /* Set up user data for creating context */ + u_ctx.f = idx_info->f; + u_ctx.ndims = idx_info->layout->ndims - 1; + u_ctx.chunk_size = idx_info->layout->size; + + /* Initialize user data for removal callback */ + remove_udata.f = idx_info->f; + remove_udata.dxpl_id = idx_info->dxpl_id; + + remove_op = idx_info->pline->nused > 0 ? H5D_bt2_filt_remove_cb : H5D_bt2_remove_cb; + + /* Delete the v2 B-tree */ + /*(space in the file for each object is freed in the 'remove' callback) */ + if(H5B2_delete(idx_info->f, idx_info->dxpl_id, idx_info->storage->idx_addr, &u_ctx, remove_op, &remove_udata) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTDELETE, FAIL, "can't delete v2 B-tree") + + idx_info->storage->idx_addr = HADDR_UNDEF; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_delete() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_copy_setup + * + * Purpose: Set up any necessary information for copying chunks + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_copy_setup(const H5D_chk_idx_info_t *idx_info_src, + const H5D_chk_idx_info_t *idx_info_dst) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_copy_setup) + + /* Source file */ + HDassert(idx_info_src); + HDassert(idx_info_src->f); + HDassert(idx_info_src->pline); + HDassert(idx_info_src->layout); + HDassert(idx_info_src->storage); + + /* Destination file */ + HDassert(idx_info_dst); + HDassert(idx_info_dst->f); + HDassert(idx_info_dst->pline); + HDassert(idx_info_dst->layout); + HDassert(idx_info_dst->storage); + HDassert(!H5F_addr_defined(idx_info_dst->storage->idx_addr)); + + /* Check if the source v2 B-tree is open yet */ + if(NULL == idx_info_src->storage->u.btree2.bt2) { + if(H5D_bt2_idx_open(idx_info_src) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open v2 B-tree") + } /* end if */ + + /* Set copied metadata tag */ + H5_BEGIN_TAG(idx_info_dst->dxpl_id, H5AC__COPIED_TAG, FAIL); + + /* Create v2 B-tree that describes the chunked dataset in the destination file */ + if(H5D_bt2_idx_create(idx_info_dst) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize chunked storage") + HDassert(H5F_addr_defined(idx_info_dst->storage->idx_addr)); + + /* Reset metadata tag */ + H5_END_TAG(FAIL); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_copy_setup() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_copy_shutdown + * + * Purpose: Shutdown any information from copying chunks + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_copy_shutdown(H5O_storage_chunk_t *storage_src, + H5O_storage_chunk_t *storage_dst, hid_t UNUSED dxpl_id) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_copy_shutdown) + + /* Check args */ + HDassert(storage_src); + HDassert(storage_src->u.btree2.bt2); + HDassert(storage_dst); + HDassert(storage_dst->u.btree2.bt2); + + /* Close v2 B-tree for source file */ + if(H5B2_close(storage_src->u.btree2.bt2, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close v2 B-tree") + storage_src->u.btree2.bt2 = NULL; + + /* Close v2 B-tree for destination file */ + if(H5B2_close(storage_dst->u.btree2.bt2, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "unable to close v2 B-tree") + storage_dst->u.btree2.bt2 = NULL; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_copy_shutdown() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_size + * + * Purpose: Retrieve the amount of index storage for chunked dataset + * + * Return: Success: Non-negative + * Failure: negative + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_size(const H5D_chk_idx_info_t *idx_info, hsize_t *index_size) +{ + H5B2_t *bt2_cdset = NULL; /* Pointer to v2 B-tree structure */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_bt2_idx_size, FAIL) + + /* Check args */ + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->pline); + HDassert(idx_info->layout); + HDassert(idx_info->storage); + HDassert(H5F_addr_defined(idx_info->storage->idx_addr)); + HDassert(index_size); + + /* Open v2 B-tree */ + if(H5D_bt2_idx_open(idx_info) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "can't open v2 B-tree") + + /* Set convenience pointer to v2 B-tree structure */ + bt2_cdset = idx_info->storage->u.btree2.bt2; + + /* Get v2 B-tree size for indexing chunked dataset */ + if(H5B2_size(bt2_cdset, idx_info->dxpl_id, index_size) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve v2 B-tree storage info for chunked dataset") +done: + /* Close v2 B-tree index */ + if(bt2_cdset && H5B2_close(bt2_cdset, idx_info->dxpl_id) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "can't close v2 B-tree for tracking chunked dataset") + idx_info->storage->u.btree2.bt2 = NULL; + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_reset + * + * Purpose: Reset indexing information. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_idx_reset) + + HDassert(storage); + + /* Reset index info */ + if(reset_addr) + storage->idx_addr = HADDR_UNDEF; + storage->u.btree2.bt2 = NULL; + + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5D_bt2_idx_reset() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_dump + * + * Purpose: Dump indexing information to a stream. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_dump(const H5O_storage_chunk_t *storage, FILE *stream) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_bt2_idx_dump) + + HDassert(storage); + HDassert(stream); + + HDfprintf(stream, " Address: %a\n", storage->idx_addr); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5D_bt2_idx_dump() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_bt2_idx_dest + * + * Purpose: Release indexing information in memory. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Vailin Choi; June 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_bt2_idx_dest(const H5D_chk_idx_info_t *idx_info) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_bt2_idx_dest) + + /* Check args */ + HDassert(idx_info); + HDassert(idx_info->f); + HDassert(idx_info->storage); + + /* Check if the v2-btree is open */ + if(idx_info->storage->u.btree2.bt2) { + /* Close v2 B-tree */ + if(H5B2_close(idx_info->storage->u.btree2.bt2, idx_info->dxpl_id) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTCLOSEOBJ, FAIL, "can't close v2 B-tree") + idx_info->storage->u.btree2.bt2 = NULL; + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_bt2_idx_dest() */ + diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index 0deb578..e70a7b0 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -464,6 +464,10 @@ done: * Programmer: Robb Matzke * Monday, May 18, 1998 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -483,6 +487,8 @@ H5D_chunk_init(H5F_t *f, hid_t dxpl_id, const H5D_t *dset, hid_t dapl_id) H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); @@ -547,6 +553,10 @@ done: * Programmer: Quincey Koziol * Thursday, January 15, 2009 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ hbool_t @@ -562,6 +572,8 @@ H5D_chunk_is_space_alloc(const H5O_storage_t *storage) H5D_COPS_EARRAY == storage->u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == storage->u.chunk.idx_type && H5D_COPS_FARRAY == storage->u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == storage->u.chunk.idx_type && + H5D_COPS_BT2 == storage->u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == storage->u.chunk.idx_type && H5D_COPS_BTREE == storage->u.chunk.ops)); @@ -2044,6 +2056,10 @@ done: * Programmer: Quincey Koziol * Thursday, January 15, 2009 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -2060,6 +2076,8 @@ H5D_chunk_idx_reset(H5O_storage_chunk_t *storage, hbool_t reset_addr) H5D_COPS_EARRAY == storage->ops) || (H5D_CHUNK_IDX_FARRAY == storage->idx_type && H5D_COPS_FARRAY == storage->ops) || + (H5D_CHUNK_IDX_BT2 == storage->idx_type && + H5D_COPS_BT2 == storage->ops) || (H5D_CHUNK_IDX_BTREE == storage->idx_type && H5D_COPS_BTREE == storage->ops)); @@ -2201,6 +2219,10 @@ done: * Programmer: Quincey Koziol * Thursday, May 22, 2008 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -2219,6 +2241,8 @@ H5D_chunk_create(H5D_t *dset /*in,out*/, hid_t dxpl_id) H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); #ifndef NDEBUG @@ -2257,6 +2281,10 @@ done: * Programmer: Albert Cheng * June 27, 1998 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -2276,6 +2304,8 @@ H5D_chunk_lookup(const H5D_t *dset, hid_t dxpl_id, const hsize_t *chunk_offset, H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); HDassert(chunk_offset); @@ -2350,6 +2380,10 @@ done: * Programmer: Robb Matzke * Thursday, May 21, 1998 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -2368,6 +2402,8 @@ H5D_chunk_flush_entry(const H5D_t *dset, hid_t dxpl_id, const H5D_dxpl_cache_t * H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); HDassert(dxpl_cache); @@ -3279,6 +3315,10 @@ H5D_chunk_allocated_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) * Programmer: Quincey Koziol * Tuesday, May 20, 2008 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -3300,6 +3340,8 @@ H5D_chunk_allocated(H5D_t *dset, hid_t dxpl_id, hsize_t *nbytes) H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); @@ -3345,6 +3387,10 @@ done: * Programmer: Albert Cheng * June 26, 1998 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -3399,6 +3445,8 @@ H5D_chunk_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite, H5D_COPS_EARRAY == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == layout->storage.u.chunk.idx_type && H5D_COPS_FARRAY == layout->storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == layout->storage.u.chunk.idx_type && + H5D_COPS_BT2 == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == layout->storage.u.chunk.idx_type && H5D_COPS_BTREE == layout->storage.u.chunk.ops)); HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER)); @@ -3846,6 +3894,8 @@ H5D_chunk_update_old_edge_chunks(H5D_t *dset, hid_t dxpl_id, hsize_t old_dim[]) H5D_COPS_EARRAY == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == layout->storage.u.chunk.idx_type && H5D_COPS_FARRAY == layout->storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == layout->storage.u.chunk.idx_type && + H5D_COPS_BT2 == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == layout->storage.u.chunk.idx_type && H5D_COPS_BTREE == layout->storage.u.chunk.ops)); HDassert(TRUE == H5P_isa_class(dxpl_id, H5P_DATASET_XFER)); @@ -4214,6 +4264,9 @@ done: * To release the chunks, we traverse the B-tree to obtain a list of unused * allocated chunks, and then call H5B_remove() for each chunk. * + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -4264,6 +4317,8 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) H5D_COPS_EARRAY == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == layout->storage.u.chunk.idx_type && H5D_COPS_FARRAY == layout->storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == layout->storage.u.chunk.idx_type && + H5D_COPS_BT2 == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == layout->storage.u.chunk.idx_type && H5D_COPS_BTREE == layout->storage.u.chunk.ops)); HDassert(dxpl_cache); @@ -4441,7 +4496,7 @@ H5D_chunk_prune_by_extent(H5D_t *dset, hid_t dxpl_id, const hsize_t *old_dim) dims_outside_fill[i] = FALSE; carry = FALSE; - } /* end if */ + } /* end if */ while(!carry) { /* Calculate the index of this chunk */ @@ -4629,6 +4684,10 @@ done: * Programmer: Kent Yang * November 15, 2005 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -4647,6 +4706,8 @@ H5D_chunk_addrmap(const H5D_io_info_t *io_info, haddr_t chunk_addr[]) H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); HDassert(chunk_addr); @@ -4685,6 +4746,10 @@ done: * Programmer: Quincey Koziol * Thursday, March 20, 2003 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -4708,6 +4773,8 @@ H5D_chunk_delete(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5O_storage_t *storage) H5D_COPS_EARRAY == storage->u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == storage->u.chunk.idx_type && H5D_COPS_FARRAY == storage->u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == storage->u.chunk.idx_type && + H5D_COPS_BT2 == storage->u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == storage->u.chunk.idx_type && H5D_COPS_BTREE == storage->u.chunk.ops)); @@ -5049,6 +5116,9 @@ done: * Programmer: Peter Cao * August 20, 2005 * + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -5090,6 +5160,8 @@ H5D_chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src, H5D_COPS_EARRAY == storage_src->ops) || (H5D_CHUNK_IDX_FARRAY == storage_src->idx_type && H5D_COPS_FARRAY == storage_src->ops) || + (H5D_CHUNK_IDX_BT2 == storage_src->idx_type && + H5D_COPS_BT2 == storage_src->ops) || (H5D_CHUNK_IDX_BTREE == storage_src->idx_type && H5D_COPS_BTREE == storage_src->ops)); HDassert(layout_src); @@ -5099,6 +5171,8 @@ H5D_chunk_copy(H5F_t *f_src, H5O_storage_chunk_t *storage_src, H5D_COPS_EARRAY == storage_dst->ops) || (H5D_CHUNK_IDX_FARRAY == storage_dst->idx_type && H5D_COPS_FARRAY == storage_dst->ops) || + (H5D_CHUNK_IDX_BT2 == storage_dst->idx_type && + H5D_COPS_BT2 == storage_dst->ops) || (H5D_CHUNK_IDX_BTREE == storage_dst->idx_type && H5D_COPS_BTREE == storage_dst->ops)); HDassert(ds_extent_src); @@ -5324,6 +5398,10 @@ done: * Programmer: Vailin Choi * June 8, 2007 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -5342,6 +5420,8 @@ H5D_chunk_bh_info(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout, H5D_COPS_EARRAY == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == layout->storage.u.chunk.idx_type && H5D_COPS_FARRAY == layout->storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == layout->storage.u.chunk.idx_type && + H5D_COPS_BT2 == layout->storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == layout->storage.u.chunk.idx_type && H5D_COPS_BTREE == layout->storage.u.chunk.ops)); HDassert(pline); @@ -5421,6 +5501,10 @@ H5D_chunk_dump_index_cb(const H5D_chunk_rec_t *chunk_rec, void *_udata) * Programmer: Robb Matzke * Wednesday, April 28, 1999 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -5436,6 +5520,8 @@ H5D_chunk_dump_index(H5D_t *dset, hid_t dxpl_id, FILE *stream) H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); @@ -5481,6 +5567,10 @@ done: * Programmer: Robb Matzke * Thursday, May 21, 1998 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2-btree indexing + * *------------------------------------------------------------------------- */ herr_t @@ -5502,6 +5592,8 @@ H5D_chunk_dest(H5F_t *f, hid_t dxpl_id, H5D_t *dset) H5D_COPS_EARRAY == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_FARRAY == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_FARRAY == dset->shared->layout.storage.u.chunk.ops) || + (H5D_CHUNK_IDX_BT2 == dset->shared->layout.storage.u.chunk.idx_type && + H5D_COPS_BT2 == dset->shared->layout.storage.u.chunk.ops) || (H5D_CHUNK_IDX_BTREE == dset->shared->layout.storage.u.chunk.idx_type && H5D_COPS_BTREE == dset->shared->layout.storage.u.chunk.ops)); diff --git a/src/H5Dint.c b/src/H5Dint.c index 8c4d8cd..381323c 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1116,6 +1116,7 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't retrieve external file list") } /* end if */ + /* Set the latest version of the layout, pline & fill messages, if requested */ if(H5F_USE_LATEST_FORMAT(file)) { /* Set the latest version for the I/O pipeline message */ @@ -1129,7 +1130,11 @@ H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, /* Set the latest version for the layout message */ if(H5D_layout_set_latest_version(&new_dset->shared->layout, new_dset->shared->space) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest version of layout") - } /* end if */ + } else if(new_dset->shared->layout.version >= H5O_LAYOUT_VERSION_4) { + /* Use latest indexing type for layout message version >= 4 */ + if(H5D_layout_set_latest_indexing(&new_dset->shared->layout, new_dset->shared->space) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set latest indexing") + } /* Check if this dataset is going into a parallel file and set space allocation time */ if(IS_H5FD_MPI(file)) diff --git a/src/H5Dlayout.c b/src/H5Dlayout.c index 1505f0e..bc3a77f 100644 --- a/src/H5Dlayout.c +++ b/src/H5Dlayout.c @@ -71,6 +71,9 @@ * Programmer: Quincey Koziol * Thursday, March 20, 2008 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2 B-tree indexing. *------------------------------------------------------------------------- */ herr_t @@ -101,6 +104,10 @@ H5D_layout_set_io_ops(const H5D_t *dataset) dataset->shared->layout.storage.u.chunk.ops = H5D_COPS_BTREE; break; + case H5D_CHUNK_IDX_BT2: + dataset->shared->layout.storage.u.chunk.ops = H5D_COPS_BT2; + break; + case H5D_CHUNK_IDX_FARRAY: dataset->shared->layout.storage.u.chunk.ops = H5D_COPS_FARRAY; break; @@ -143,6 +150,10 @@ done: * Programmer: Raymond Lu * August 14, 2002 * + * Modifications: + * Vailin Choi; August 2010 + * Added v2 B-tree indexing. + * Removed v1 B-tree support for layout message version >= 4. *------------------------------------------------------------------------- */ size_t @@ -209,18 +220,19 @@ H5D_layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t include ret_value++; switch(layout->u.chunk.idx_type) { - case H5D_CHUNK_IDX_BTREE: /* Remove this when v2 B-tree indices added */ - /* Nothing to do */ + case H5D_CHUNK_IDX_BT2: + /* v2 B-tree creation parameters */ + ret_value += H5D_BT2_CREATE_PARAM_SIZE; break; case H5D_CHUNK_IDX_FARRAY: /* Fixed array creation parameters */ - ret_value += 1; + ret_value += H5D_FARRAY_CREATE_PARAM_SIZE; break; case H5D_CHUNK_IDX_EARRAY: /* Extensible array creation parameters */ - ret_value += 5; + ret_value += H5D_EARRAY_CREATE_PARAM_SIZE; break; default: @@ -244,6 +256,42 @@ done: * Function: H5D_layout_set_latest_version * * Purpose: Set the encoding for a layout to the latest version. + * Part of the coding in this routine is moved to + * H5D_layout_set_latest_indexing(). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Thursday, January 15, 2009 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_layout_set_latest_version(H5O_layout_t *layout, const H5S_t *space) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_layout_set_latest_version, FAIL) + + /* Sanity check */ + HDassert(layout); + + /* Set encoding of layout to latest version */ + layout->version = H5O_LAYOUT_VERSION_LATEST; + + /* Set the latest indexing type for the layout message */ + ret_value = H5D_layout_set_latest_indexing(layout, space); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_layout_set_latest_version() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_layout_set_latest_indexing + * + * Purpose: Set the latest indexing type for a layout message + * This is moved from H5D_layout_set_latest_version(). * * Return: Non-negative on success/Negative on failure * @@ -255,23 +303,22 @@ done: * Modified to use Fixed Array indexing for extendible chunked dataset. * (fixed max. dim. setting but exclude H5S_UNLIMITED) * + * Vailin Choi; August 2010 + * Added v2 B-tree indexing for chunked dataset >1 unlimited dimensions. *------------------------------------------------------------------------- */ herr_t -H5D_layout_set_latest_version(H5O_layout_t *layout, const H5S_t *space) +H5D_layout_set_latest_indexing(H5O_layout_t *layout, const H5S_t *space) { int sndims; /* Rank of dataspace */ unsigned ndims; /* Rank of dataspace */ herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5D_layout_set_latest_version, FAIL) + FUNC_ENTER_NOAPI(H5D_layout_set_latest_indexing, FAIL) /* Sanity check */ HDassert(layout); - /* Set encoding of layout to latest version */ - layout->version = H5O_LAYOUT_VERSION_LATEST; - /* Query the dimensionality of the dataspace */ if((sndims = H5S_GET_EXTENT_NDIMS(space)) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "invalid dataspace rank") @@ -299,6 +346,7 @@ H5D_layout_set_latest_version(H5O_layout_t *layout, const H5S_t *space) HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "dataset with unlimited dimensions is not chunked") if(1 == unlim_count) { /* Chunked dataset with only 1 unlimited dimension */ + /* Set the chunk index type to an extensible array */ layout->u.chunk.idx_type = H5D_CHUNK_IDX_EARRAY; layout->storage.u.chunk.idx_type = H5D_CHUNK_IDX_EARRAY; layout->storage.u.chunk.ops = H5D_COPS_EARRAY; @@ -313,8 +361,16 @@ H5D_layout_set_latest_version(H5O_layout_t *layout, const H5S_t *space) layout->u.chunk.u.earray.cparam.data_blk_min_elmts = H5D_EARRAY_DATA_BLK_MIN_ELMTS; layout->u.chunk.u.earray.cparam.max_dblk_page_nelmts_bits = H5D_EARRAY_MAX_DBLOCK_PAGE_NELMTS_BITS; } else { /* Chunked dataset with > 1 unlimited dimensions */ - /* Add setup to use v2 B-tree chunk indices here */ - } + /* Set the chunk index type to v2 B-tree */ + layout->u.chunk.idx_type = H5D_CHUNK_IDX_BT2; + layout->storage.u.chunk.idx_type = H5D_CHUNK_IDX_BT2; + layout->storage.u.chunk.ops = H5D_COPS_BT2; + + /* Set the v2 B-tree creation parameters */ + layout->u.chunk.u.btree2.cparam.node_size = H5D_BT2_NODE_SIZE; + layout->u.chunk.u.btree2.cparam.split_percent = H5D_BT2_SPLIT_PERC; + layout->u.chunk.u.btree2.cparam.merge_percent = H5D_BT2_MERGE_PERC; + } } else if(layout->type == H5D_CHUNKED) { /* Chunked dataset with fixed dimensions (with or without max. dimension setting) */ /* Set the chunk index type to Fixed Array */ @@ -332,7 +388,7 @@ H5D_layout_set_latest_version(H5O_layout_t *layout, const H5S_t *space) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_layout_set_latest_version() */ +} /* end H5D_layout_set_latest_indexing() */ /*------------------------------------------------------------------------- diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 63cc010..fa7eacf 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -34,6 +34,7 @@ /* Other private headers needed by this file */ #include "H5ACprivate.h" /* Metadata cache */ #include "H5Gprivate.h" /* Groups */ +#include "H5B2private.h" /* v2 B-trees */ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatypes */ @@ -66,17 +67,25 @@ #define H5D_CHUNK_HASH(D, ADDR) H5F_addr_hash(ADDR, (D)->cache.chunk.nslots) /* Default creation parameters for chunk index data structures */ +/* See H5O_layout_chunk_t */ /* Fixed array creation values */ -#define H5D_FARRAY_MAX_DBLK_PAGE_NELMTS_BITS 10 /* i.e. 1024 elements per data block page */ +#define H5D_FARRAY_CREATE_PARAM_SIZE 1 /* Size of the creation parameters in bytes */ +#define H5D_FARRAY_MAX_DBLK_PAGE_NELMTS_BITS 10 /* i.e. 1024 elements per data block page */ /* Extensible array creation values */ -#define H5D_EARRAY_MAX_NELMTS_BITS 32 /* i.e. 4 giga-elements */ -#define H5D_EARRAY_IDX_BLK_ELMTS 4 -#define H5D_EARRAY_SUP_BLK_MIN_DATA_PTRS 4 -#define H5D_EARRAY_DATA_BLK_MIN_ELMTS 16 -#define H5D_EARRAY_MAX_DBLOCK_PAGE_NELMTS_BITS 10 /* i.e. 1024 elements per data block page */ - +#define H5D_EARRAY_CREATE_PARAM_SIZE 5 /* Size of the creation parameters in bytes */ +#define H5D_EARRAY_MAX_NELMTS_BITS 32 /* i.e. 4 giga-elements */ +#define H5D_EARRAY_IDX_BLK_ELMTS 4 +#define H5D_EARRAY_SUP_BLK_MIN_DATA_PTRS 4 +#define H5D_EARRAY_DATA_BLK_MIN_ELMTS 16 +#define H5D_EARRAY_MAX_DBLOCK_PAGE_NELMTS_BITS 10 /* i.e. 1024 elements per data block page */ + +/* v2 B-tree creation values for raw meta_size */ +#define H5D_BT2_CREATE_PARAM_SIZE 6 /* Size of the creation parameters in bytes */ +#define H5D_BT2_NODE_SIZE 512 +#define H5D_BT2_SPLIT_PERC 100 +#define H5D_BT2_MERGE_PERC 40 /****************************/ /* Package Private Typedefs */ @@ -554,6 +563,12 @@ H5_DLLVAR const H5D_layout_ops_t H5D_LOPS_CHUNK[1]; H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BTREE[1]; H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_EARRAY[1]; H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_FARRAY[1]; +H5_DLLVAR const H5D_chunk_ops_t H5D_COPS_BT2[1]; + +/* The v2 B-tree class for indexing chunked datasets with >1 unlimited dimensions */ +H5_DLLVAR const H5B2_class_t H5D_BT2[1]; +H5_DLLVAR const H5B2_class_t H5D_BT2_FILT[1]; + /******************************/ @@ -606,6 +621,8 @@ H5_DLL size_t H5D_layout_meta_size(const H5F_t *f, const H5O_layout_t *layout, hbool_t include_compact_data); H5_DLL herr_t H5D_layout_set_latest_version(H5O_layout_t *layout, const H5S_t *space); +H5_DLL herr_t H5D_layout_set_latest_indexing(H5O_layout_t *layout, + const H5S_t *space); H5_DLL herr_t H5D_layout_oh_create(H5F_t *file, hid_t dxpl_id, H5O_t *oh, H5D_t *dset, hid_t dapl_id); H5_DLL herr_t H5D_layout_oh_read(H5D_t *dset, hid_t dxpl_id, hid_t dapl_id, diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 972b33b..f4c62c9 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -53,9 +53,10 @@ typedef enum H5D_layout_t { /* Types of chunk index data structures */ typedef enum H5D_chunk_index_t { - H5D_CHUNK_IDX_BTREE = 0, /* v1 B-tree index (default) */ + H5D_CHUNK_IDX_BTREE = 0, /* v1 B-tree index (default) */ H5D_CHUNK_IDX_FARRAY = 1, /* Fixed array (for 0 unlimited dims) */ H5D_CHUNK_IDX_EARRAY = 2, /* Extensible array (for 1 unlimited dim) */ + H5D_CHUNK_IDX_BT2 = 3, /* v2 B-tree index (for >1 unlimited dims) */ H5D_CHUNK_IDX_NTYPES /*this one must be last! */ } H5D_chunk_index_t; diff --git a/src/H5HFbtree2.c b/src/H5HFbtree2.c index 3f208e7..bce58b7 100644 --- a/src/H5HFbtree2.c +++ b/src/H5HFbtree2.c @@ -287,7 +287,6 @@ H5HF_huge_bt2_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED add /* Sanity check */ HDassert(f); - HDassert(H5F_addr_defined(addr)); /* Allocate callback context */ if(NULL == (ctx = H5FL_MALLOC(H5HF_huge_bt2_ctx_t))) diff --git a/src/H5Olayout.c b/src/H5Olayout.c index debc169..bbebb8e 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -96,6 +96,11 @@ H5FL_DEFINE(H5O_layout_t); * Programmer: Robb Matzke * Wednesday, October 8, 1997 * + * Modifications: + * Vailin Choi; Aug 2010 + * Added v2 B-tree index. + * Removed v1 B-tree support for layout message version > 4. + * *------------------------------------------------------------------------- */ static void * @@ -306,8 +311,10 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, mesg->storage.u.chunk.idx_type = mesg->u.chunk.idx_type; switch(mesg->u.chunk.idx_type) { - case H5D_CHUNK_IDX_BTREE: /* Remove this when v2 B-tree indices added */ - /* Nothing to do */ + case H5D_CHUNK_IDX_BT2: /* v2 B-tree index */ + UINT32DECODE(p, mesg->u.chunk.u.btree2.cparam.node_size); + mesg->u.chunk.u.btree2.cparam.split_percent = *p++; + mesg->u.chunk.u.btree2.cparam.merge_percent = *p++; break; case H5D_CHUNK_IDX_FARRAY: @@ -394,6 +401,10 @@ done: * Added version number 4 case to allow different kinds of indices for * looking up chunks. * + * Vailin Choi; Aug 2010 + * Added v2 B-tree index. + * Removed v1 B-tree support for layout message version > 4. + * *------------------------------------------------------------------------- */ static herr_t @@ -480,8 +491,10 @@ H5O_layout_encode(H5F_t *f, hbool_t UNUSED disable_shared, uint8_t *p, const voi *p++ = (uint8_t)mesg->u.chunk.idx_type; switch(mesg->u.chunk.idx_type) { - case H5D_CHUNK_IDX_BTREE: /* Remove this when v2 B-tree indices added */ - /* Nothing to do */ + case H5D_CHUNK_IDX_BT2: /* v2 B-tree index */ + UINT32ENCODE(p, mesg->u.chunk.u.btree2.cparam.node_size); + *p++ = mesg->u.chunk.u.btree2.cparam.split_percent; + *p++ = mesg->u.chunk.u.btree2.cparam.merge_percent; break; case H5D_CHUNK_IDX_FARRAY: @@ -887,6 +900,8 @@ done: * Wednesday, October 8, 1997 * * Modifications: + * Vailin Choi; Aug 2010 + * Added v2 B-tree index. * *------------------------------------------------------------------------- */ @@ -929,6 +944,11 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, "Index Type:", "v1 B-tree"); break; + case H5D_CHUNK_IDX_BT2: + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Index Type:", "v2 B-tree"); + break; + case H5D_CHUNK_IDX_FARRAY: HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Index Type:", "Fixed Array"); diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index b062b95..a736e7c 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -396,6 +396,13 @@ typedef struct H5O_storage_chunk_btree_t { } H5O_storage_chunk_btree_t; /* Forward declaration of structs used below */ +struct H5B2_t; /* Defined in H5B2pkg.h */ + +typedef struct H5O_storage_chunk_bt2_t { + struct H5B2_t *bt2; +} H5O_storage_chunk_bt2_t; + +/* Forward declaration of structs used below */ struct H5FA_t; /* Defined in H5FAprivate.h */ typedef struct H5O_storage_chunk_farray_t { @@ -416,6 +423,7 @@ typedef struct H5O_storage_chunk_t { const struct H5D_chunk_ops_t *ops; /* Pointer to chunked storage operations */ union { H5O_storage_chunk_btree_t btree; /* Information for v1 B-tree index */ + H5O_storage_chunk_bt2_t btree2; /* Information for v2 B-tree index */ H5O_storage_chunk_farray_t farray; /* Information for fixed array index */ H5O_storage_chunk_earray_t earray; /* Information for extensible array index */ } u; @@ -436,6 +444,15 @@ typedef struct H5O_storage_t { } u; } H5O_storage_t; +typedef struct H5O_layout_chunk_bt2_t { + /* Creation parameters for v2 B-tree data structure */ + struct { + uint32_t node_size; /* Size of each node (in bytes) */ + uint8_t split_percent; /* % full to split nodes */ + uint8_t merge_percent; /* % full to merge nodes */ + } cparam; +} H5O_layout_chunk_bt2_t; + typedef struct H5O_layout_chunk_farray_t { /* Creation parameters for fixed array data structure */ struct { @@ -475,6 +492,7 @@ typedef struct H5O_layout_chunk_t { union { H5O_layout_chunk_farray_t farray; /* Information for fixed array index */ H5O_layout_chunk_earray_t earray; /* Information for extensible array index */ + H5O_layout_chunk_bt2_t btree2; /* Information for v2 B-tree index */ } u; } H5O_layout_chunk_t; diff --git a/src/H5Ostorage.c b/src/H5Ostorage.c index f6891d7..2995e47 100644 --- a/src/H5Ostorage.c +++ b/src/H5Ostorage.c @@ -103,6 +103,11 @@ H5FL_DEFINE_STATIC(H5O_storage_t); * Programmer: Quincey Koziol * Wednesday, July 29, 2009 * + * Modifications: + * Vailin Choi; Aug 2010 + * Added v2 B-tree index. + * Removed v1 B-tree support. + * *------------------------------------------------------------------------- */ static void * @@ -173,9 +178,9 @@ H5O_storage_decode(H5F_t *f, hid_t UNUSED dxpl_id, H5O_t UNUSED *open_oh, /* Chunk index type */ mesg->u.chunk.idx_type = (H5D_chunk_index_t)*p++; switch(mesg->u.chunk.idx_type) { - case H5D_CHUNK_IDX_BTREE: /* Remove this when v2 B-tree indices added */ + case H5D_CHUNK_IDX_BT2: /* v2 B-tree index */ /* Set the chunk operations */ - mesg->u.chunk.ops = H5D_COPS_BTREE; + mesg->u.chunk.ops = H5D_COPS_BT2; break; case H5D_CHUNK_IDX_FARRAY: @@ -603,6 +608,10 @@ done: * Programmer: Quincey Koziol * Thursday, July 30, 2009 * + * Modifications: + * Vailin Choi; Aug 2010 + * Added v2 B-tree index. + * *------------------------------------------------------------------------- */ static herr_t @@ -634,6 +643,11 @@ H5O_storage_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, "Index Type:", "v1 B-tree"); break; + case H5D_CHUNK_IDX_BT2: + HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, + "Index Type:", "v2 B-tree"); + break; + case H5D_CHUNK_IDX_FARRAY: HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Index Type:", "Fixed Array"); diff --git a/src/H5SMbtree2.c b/src/H5SMbtree2.c index 95527f9..156a6c5 100755 --- a/src/H5SMbtree2.c +++ b/src/H5SMbtree2.c @@ -240,7 +240,6 @@ H5SM_bt2_crt_dbg_context(H5F_t *f, hid_t UNUSED dxpl_id, haddr_t UNUSED addr) /* Sanity check */ HDassert(f); - HDassert(H5F_addr_defined(addr)); /* Allocate callback context */ if(NULL == (ctx = H5FL_MALLOC(H5SM_bt2_ctx_t))) diff --git a/src/Makefile.am b/src/Makefile.am index 5dd6b36..6f93c4e 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,7 +46,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5AC.c H5B.c H5Bcache.c H5Bdbg.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c \ - H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ + H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \ H5Dio.c H5Dlayout.c H5Dmpio.c H5Doh.c H5Dproxy.c H5Dscatgath.c \ H5Dselect.c H5Dtest.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 1fa47ad..8dbba32 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -100,14 +100,14 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5Adeprec.lo H5Aint.lo H5Atest.lo H5AC.lo H5B.lo H5Bcache.lo \ H5Bdbg.lo H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2hdr.lo \ H5B2int.lo H5B2stat.lo H5B2test.lo H5C.lo H5CS.lo H5D.lo \ - H5Dbtree.lo H5Dchunk.lo H5Dcompact.lo H5Dcontig.lo H5Ddbg.lo \ - H5Ddeprec.lo H5Dearray.lo H5Defl.lo H5Dfarray.lo H5Dfill.lo \ - H5Dint.lo H5Dio.lo H5Dlayout.lo H5Dmpio.lo H5Doh.lo \ - H5Dproxy.lo H5Dscatgath.lo H5Dselect.lo H5Dtest.lo H5E.lo \ - H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo H5EAdbg.lo \ - H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo H5EAiblock.lo \ - H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo H5F.lo \ - H5Faccum.lo H5Fdbg.lo H5Fdeprec.lo H5Ffake.lo H5Fio.lo \ + H5Dbtree.lo H5Dbtree2.lo H5Dchunk.lo H5Dcompact.lo \ + H5Dcontig.lo H5Ddbg.lo H5Ddeprec.lo H5Dearray.lo H5Defl.lo \ + H5Dfarray.lo H5Dfill.lo H5Dint.lo H5Dio.lo H5Dlayout.lo \ + H5Dmpio.lo H5Doh.lo H5Dproxy.lo H5Dscatgath.lo H5Dselect.lo \ + H5Dtest.lo H5E.lo H5Edeprec.lo H5Eint.lo H5EA.lo H5EAcache.lo \ + H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo H5EAhdr.lo \ + H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo H5EAtest.lo \ + H5F.lo H5Faccum.lo H5Fdbg.lo H5Fdeprec.lo H5Ffake.lo H5Fio.lo \ H5Fmount.lo H5Fmpi.lo H5Fquery.lo H5Fsfile.lo H5Fsuper.lo \ H5Fsuper_cache.lo H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo \ H5FAdblock.lo H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo \ @@ -468,7 +468,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5AC.c H5B.c H5Bcache.c H5Bdbg.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2hdr.c H5B2int.c H5B2stat.c H5B2test.c \ H5C.c H5CS.c \ - H5D.c H5Dbtree.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ + H5D.c H5Dbtree.c H5Dbtree2.c H5Dchunk.c H5Dcompact.c H5Dcontig.c H5Ddbg.c \ H5Ddeprec.c H5Dearray.c H5Defl.c H5Dfarray.c H5Dfill.c H5Dint.c \ H5Dio.c H5Dlayout.c H5Dmpio.c H5Doh.c H5Dproxy.c H5Dscatgath.c \ H5Dselect.c H5Dtest.c \ @@ -694,6 +694,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5CS.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5D.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dbtree.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dbtree2.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dchunk.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dcompact.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dcontig.Plo@am__quote@ diff --git a/test/dsets.c b/test/dsets.c index 3d42efc..ae23e7e 100644 --- a/test/dsets.c +++ b/test/dsets.c @@ -130,7 +130,6 @@ const char *FILENAME[] = { #define DSET_FIXED_MAX "DSET_FIXED_MAX" #define DSET_FIXED_NOMAX "DSET_FIXED_NOMAX" #define DSET_FIXED_BIG "DSET_FIXED_BIG" - #define POINTS 72 #define POINTS_BIG 2500 @@ -183,9 +182,11 @@ const char *FILENAME[] = { /* Names for zero-dim test */ #define ZERODIM_DATASET "zerodim" +#define ZERODIM_DATASET2 "zerodim2" /* Parameters for zero-dim test */ #define MISSING_CHUNK_DATASET "missing_chunk" +#define MISSING_CHUNK_DATASET2 "missing_chunk2" #define MISSING_CHUNK_DIM 100 /* Names for random chunks test */ @@ -210,6 +211,10 @@ const char *FILENAME[] = { /* Parameters for testing bypassing chunk cache */ #define BYPASS_DATASET1 "Dset1" #define BYPASS_DATASET2 "Dset2" + +#define T_BYPASS_DATASET1 "T_Dset1" +#define T_BYPASS_DATASET2 "T_Dset2" + #define BYPASS_DIM 1000 #define BYPASS_CHUNK_DIM 500 #define BYPASS_FILL_VALUE 7 @@ -923,8 +928,8 @@ error: /* Close file */ H5Sclose(space); H5Pclose(plist); - H5Fclose(file); H5Dclose(dataset); + H5Fclose(file); } H5E_END_TRY; return -1; @@ -6411,22 +6416,43 @@ error: * Programmer: Quincey Koziol * Tuesday, July 27, 2004 * + * Modifications: + * Vailin Choi; June 2010 + * Added dataset with > 1 unlimited dimensions to the test. + * *------------------------------------------------------------------------- */ static herr_t test_zero_dims(hid_t file) { hid_t s=-1, d=-1, dcpl=-1; - hsize_t dsize=0, dmax=H5S_UNLIMITED, csize=5; + hid_t s2 = -1, d2 = -1, dcpl2 = -1; + hsize_t dsize = 0, dmax = H5S_UNLIMITED, csize = 5; + hsize_t dsize2[2] = {0, 0}; + hsize_t dmax2[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hsize_t csize2[2] = {5, 5}; + hid_t fapl; /* File access property list */ + H5D_chunk_index_t idx_type; /* Dataset chunk index type */ + H5F_libver_t low; /* File format low bound */ herr_t ret; TESTING("I/O on datasets with zero-sized dims"); - if((s = H5Screate_simple(1, &dsize, &dmax)) < 0) FAIL_STACK_ERROR + /* Get the file's file access property list */ + if((fapl = H5Fget_access_plist(file)) < 0) TEST_ERROR; - /* Try creating chunked dataset with zero-sized chunk dimensions */ - if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR + /* Get library format */ + if(H5Pget_libver_bounds(fapl, &low, NULL) < 0) TEST_ERROR; + + /* + * One-dimensional dataset + */ + if((s = H5Screate_simple(1, &dsize, &dmax)) < 0) TEST_ERROR; + + /* Try creating chunked dataset with undefined chunk dimensions */ + if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR; if(H5Pset_layout(dcpl, H5D_CHUNKED) < 0) FAIL_STACK_ERROR + H5E_BEGIN_TRY { d = H5Dcreate2(file, ZERODIM_DATASET, H5T_NATIVE_INT, s, H5P_DEFAULT, dcpl, H5P_DEFAULT); } H5E_END_TRY; @@ -6435,6 +6461,7 @@ test_zero_dims(hid_t file) FAIL_PUTS_ERROR("created dataset with undefined chunk dimensions") } /* end if */ + /* Try creating chunked dataset with zero-sized chunk dimensions */ H5E_BEGIN_TRY { ret = H5Pset_chunk(dcpl, 1, &dsize); } H5E_END_TRY; @@ -6443,17 +6470,78 @@ test_zero_dims(hid_t file) if(H5Pclose(dcpl) < 0) FAIL_STACK_ERROR + /* Create the zero-sized extendible dataset */ if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR if(H5Pset_chunk(dcpl, 1, &csize) < 0) FAIL_STACK_ERROR if((d = H5Dcreate2(file, ZERODIM_DATASET, H5T_NATIVE_INT, s, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + /* Get the chunk index type */ + if(H5D_layout_idx_type_test(d, &idx_type) < 0) TEST_ERROR; + + /* Verify index type */ + if(low == H5F_LIBVER_LATEST) { + if(idx_type != H5D_CHUNK_IDX_EARRAY) + FAIL_PUTS_ERROR("should be using extensible array as index"); + } else if(idx_type != H5D_CHUNK_IDX_BTREE) + FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + + /* Just a no-op */ if(H5Dwrite(d, H5T_NATIVE_INT, s, s, H5P_DEFAULT, (void*)911) < 0) FAIL_STACK_ERROR if(H5Dclose(d) < 0) FAIL_STACK_ERROR if(H5Pclose(dcpl) < 0) FAIL_STACK_ERROR - if(H5Sclose(s) < 0) FAIL_STACK_ERROR + /* + * Two-dimensional dataset + */ + if((s2 = H5Screate_simple(2, dsize2, dmax2)) < 0) TEST_ERROR; + + /* Try creating chunked dataset with undefined chunk dimensions */ + if((dcpl2 = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR; + if(H5Pset_layout(dcpl2, H5D_CHUNKED) < 0) FAIL_STACK_ERROR + + H5E_BEGIN_TRY { + d2 = H5Dcreate2(file, ZERODIM_DATASET2, H5T_NATIVE_INT, s2, H5P_DEFAULT, dcpl2, H5P_DEFAULT); + } H5E_END_TRY; + if(d2 > 0) { + H5Dclose(d2); + FAIL_PUTS_ERROR("created dataset with undefined chunk dimensions") + } /* end if */ + + /* Try creating chunked dataset with zero-sized chunk dimensions */ + H5E_BEGIN_TRY { + ret = H5Pset_chunk(dcpl2, 2, dsize2); + } H5E_END_TRY; + if(ret > 0) + FAIL_PUTS_ERROR("set zero-sized chunk dimensions") + + if(H5Pclose(dcpl2) < 0) FAIL_STACK_ERROR + + /* Write to the zero-sized extendible dataset */ + if((dcpl2 = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR + if(H5Pset_chunk(dcpl2, 2, csize2) < 0) FAIL_STACK_ERROR + + /* Create the dataset */ + if((d2 = H5Dcreate2(file, ZERODIM_DATASET2, H5T_NATIVE_INT, s2, H5P_DEFAULT, dcpl2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + + /* Get the chunk index type */ + if(H5D_layout_idx_type_test(d2, &idx_type) < 0) TEST_ERROR; + + /* Verify index type */ + if(low == H5F_LIBVER_LATEST) { + if(idx_type != H5D_CHUNK_IDX_BT2) + FAIL_PUTS_ERROR("should be using v2 B-tree as index"); + } else if(idx_type != H5D_CHUNK_IDX_BTREE) + FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + + /* Just a no-op */ + if(H5Dwrite(d2, H5T_NATIVE_INT, s2, s2, H5P_DEFAULT, (void*)911) < 0) FAIL_STACK_ERROR + + if(H5Dclose(d2) < 0) FAIL_STACK_ERROR + if(H5Pclose(dcpl2) < 0) FAIL_STACK_ERROR + if(H5Sclose(s2) < 0) FAIL_STACK_ERROR + PASSED(); return 0; @@ -6462,6 +6550,10 @@ error: H5Pclose(dcpl); H5Dclose(d); H5Sclose(s); + + H5Pclose(dcpl2); + H5Dclose(d2); + H5Sclose(s2); } H5E_END_TRY; return -1; } /* end test_zero_dims() */ @@ -6481,46 +6573,98 @@ error: * Tuesday, August 25, 2004 * * Modifications: + * Vailin Choi; June 2010 + * Added dataset with >1 unlimited dimensions to the test. * *------------------------------------------------------------------------- */ static herr_t test_missing_chunk(hid_t file) { - hid_t s=-1, d=-1, dcpl=-1; - hsize_t hs_start[1]; - hsize_t hs_stride[1], - hs_count[1], - hs_block[1]; + hid_t d = -1, did2 = -1, dcpl=-1, dcpl2 = -1; /* Dataset & dataset creation property IDs */ + hid_t s = -1, sid2 = -1; /* Dataspace ID */ + hsize_t hs_start[1], hs_stride[1], hs_count[1], hs_block[1]; /* Hyperslab setting */ + hsize_t hs_start2[2], hs_stride2[2], hs_count2[2], hs_block2[2];/* Hyperslab setting */ + + /* Buffers for reading/writing dataset */ int wdata[MISSING_CHUNK_DIM], rdata[MISSING_CHUNK_DIM]; - hsize_t dsize=100, dmax=H5S_UNLIMITED, csize=5; - size_t u; + int wdata2[MISSING_CHUNK_DIM][MISSING_CHUNK_DIM], + rdata2[MISSING_CHUNK_DIM][MISSING_CHUNK_DIM]; + + /* Setting for 1-D dataset */ + hsize_t dsize=100, dmax=H5S_UNLIMITED; + hsize_t csize=5; + + /* Setting for 2-D dataset */ + hsize_t dsize2[2] = {100, 100}, dmax2[2] = {H5S_UNLIMITED, H5S_UNLIMITED}; + hsize_t csize2[2] = {5, 5}; + size_t u, i, j; /* Local Index variable */ + + hid_t fapl; /* File access property list */ + H5F_libver_t low; /* File format low bound */ + H5D_chunk_index_t idx_type, idx_type2; /* Dataset chunk index types */ TESTING("Read dataset with unwritten chunk & undefined fill value"); - /* Initialize data */ - for(u=0; u<MISSING_CHUNK_DIM; u++) { - wdata[u]=(int)u; - rdata[u]=911; + /* Get the file's file access property list */ + if((fapl = H5Fget_access_plist(file)) < 0) TEST_ERROR; + + /* Get library format */ + if(H5Pget_libver_bounds(fapl, &low, NULL) < 0) TEST_ERROR; + + /* Initialize data for 1-D dataset */ + for(u = 0; u < MISSING_CHUNK_DIM; u++) { + wdata[u] = (int)u; + rdata[u] = 911; + } /* end for */ + + /* Initialize data for 2-D dataset */ + for(i = 0; i < MISSING_CHUNK_DIM; i++) { + for(j = 0; j < MISSING_CHUNK_DIM; j++) { + wdata2[i][j] = (int)j + (i * MISSING_CHUNK_DIM); + rdata2[i][j] = 911; + } } /* end for */ /* Create dataspace */ if((s = H5Screate_simple(1, &dsize, &dmax)) < 0) TEST_ERROR; + if((sid2 = H5Screate_simple(2, dsize2, dmax2)) < 0) TEST_ERROR; /* Create dataset creation property list */ if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR; + if((dcpl2 = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR; /* Set to chunked */ if(H5Pset_chunk(dcpl, 1, &csize) < 0) TEST_ERROR; + if(H5Pset_chunk(dcpl2, 2, csize2) < 0) TEST_ERROR; /* Undefine fill value */ if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, NULL) < 0) TEST_ERROR; + if(H5Pset_fill_value(dcpl2, H5T_NATIVE_INT, NULL) < 0) TEST_ERROR; - /* Create dataset */ + /* Create the 1-D & 2-D datasets */ if((d = H5Dcreate2(file, MISSING_CHUNK_DATASET, H5T_NATIVE_INT, s, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) TEST_ERROR; + if((did2 = H5Dcreate2(file, MISSING_CHUNK_DATASET2, H5T_NATIVE_INT, sid2, H5P_DEFAULT, dcpl2, H5P_DEFAULT)) < 0) TEST_ERROR; + + /* Get the chunk index types */ + if(H5D_layout_idx_type_test(d, &idx_type) < 0) TEST_ERROR; + if(H5D_layout_idx_type_test(did2, &idx_type2) < 0) TEST_ERROR; + + /* Verify index type */ + if(low == H5F_LIBVER_LATEST) { + if(idx_type != H5D_CHUNK_IDX_EARRAY) + FAIL_PUTS_ERROR("should be using Extensible Array as index"); + if(idx_type2 != H5D_CHUNK_IDX_BT2) + FAIL_PUTS_ERROR("should be using v2 B-tree as index"); + } else { + if(idx_type != H5D_CHUNK_IDX_BTREE) + FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + if(idx_type2 != H5D_CHUNK_IDX_BTREE) + FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + } - /* Select elements in every other chunk */ + /* Select elements in every other chunk for 1-D dataset */ hs_start[0]=0; hs_stride[0]=10; hs_count[0]=10; @@ -6528,13 +6672,23 @@ test_missing_chunk(hid_t file) if(H5Sselect_hyperslab(s, H5S_SELECT_SET, hs_start, hs_stride, hs_count, hs_block) < 0) TEST_ERROR; - /* Write selected data */ + /* Select elements in every other chunk for 2-D dataset */ + hs_start2[0] = hs_start2[1] = 0; + hs_stride2[0] = hs_stride2[1] = 10; + hs_count2[0] = hs_count2[1] = 10; + hs_block2[0] = hs_block2[1] = 5; + if(H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_start2, hs_stride2, hs_count2, + hs_block2) < 0) TEST_ERROR; + + /* Write selected data to the datasets */ if(H5Dwrite(d, H5T_NATIVE_INT, s, s, H5P_DEFAULT, wdata) < 0) TEST_ERROR; + if(H5Dwrite(did2, H5T_NATIVE_INT, sid2, sid2, H5P_DEFAULT, wdata2) < 0) TEST_ERROR; - /* Read all data */ + /* Read all data from the datasets */ if(H5Dread(d, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata) < 0) TEST_ERROR; + if(H5Dread(did2, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata2) < 0) TEST_ERROR; - /* Validata values read */ + /* Validata values read for the 1-D dataset */ for(u=0; u<MISSING_CHUNK_DIM; u++) { if((u%10)>=5) { if(rdata[u]!=911) { @@ -6550,10 +6704,34 @@ test_missing_chunk(hid_t file) } /* end else */ } /* end for */ + /* Validata values read for the 2-D dataset */ + for(i = 0; i < MISSING_CHUNK_DIM; i++) { + for(j = 0; j < MISSING_CHUNK_DIM; j++) { + + if((i % 10) >= 5 || (j % 10) >= 5) { + if(rdata2[i][j] != 911) { + printf(" Line %d: Incorrect value, rdata2[%u][%u] = %d\n", + __LINE__,(unsigned)i, (unsigned)j, rdata2[i][j]); + TEST_ERROR; + } /* end if */ + } /* end if */ + else { + if(rdata2[i][j] != wdata2[i][j]) { + printf(" Line %d: Incorrect value, wdata2[%u][%u] = %d, rdata2[%u][%u] = %d\n", + __LINE__,(unsigned)i, (unsigned)j, wdata2[i][j],(unsigned)i, (unsigned)j, rdata2[i][j]); + TEST_ERROR; + } /* end if */ + } /* end else */ + } /* end for */ + } /* end for */ + /* Close everything */ if(H5Pclose(dcpl) < 0) TEST_ERROR; + if(H5Pclose(dcpl2) < 0) TEST_ERROR; if(H5Sclose(s) < 0) TEST_ERROR; + if(H5Sclose(sid2) < 0) TEST_ERROR; if(H5Dclose(d) < 0) TEST_ERROR; + if(H5Dclose(did2) < 0) TEST_ERROR; PASSED(); return 0; @@ -6561,8 +6739,11 @@ test_missing_chunk(hid_t file) error: H5E_BEGIN_TRY { H5Pclose(dcpl); + H5Pclose(dcpl2); H5Dclose(d); + H5Dclose(did2); H5Sclose(s); + H5Sclose(sid2); } H5E_END_TRY; return -1; } /* end test_missing_chunk() */ @@ -6583,6 +6764,8 @@ error: * Monday, March 26, 2007 * * Modifications: + * Vailin Choi; June 2010 + * Added dataset with >1 unlimited dimensions to the test. * *------------------------------------------------------------------------- */ @@ -6600,6 +6783,8 @@ test_random_chunks(hid_t fapl) const char dname[]="dataset"; int chunk_row, chunk_col; size_t i, j; + H5D_chunk_index_t idx_type; /* Dataset chunk index type */ + H5F_libver_t low; /* File format low bound */ TESTING("Write/read on randomly selected chunks"); @@ -6609,7 +6794,7 @@ test_random_chunks(hid_t fapl) h5_fixname(FILENAME[6], fapl, filename, sizeof filename); /* Create file for first test */ - if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; /* Create dataspace */ if((s = H5Screate_simple(2, dsize, NULL)) < 0) TEST_ERROR; @@ -6693,7 +6878,9 @@ test_random_chunks(hid_t fapl) /* Create file for second test */ - if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; + if(H5Pget_libver_bounds(fapl, &low, NULL) < 0) TEST_ERROR; + + if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; /* Create dataspace with unlimited maximum dimensions */ if((s = H5Screate_simple(2, dsize, dmax)) < 0) TEST_ERROR; @@ -6710,6 +6897,16 @@ test_random_chunks(hid_t fapl) /* Create dataset */ if((d = H5Dcreate2(file, dname, H5T_NATIVE_INT, s, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) TEST_ERROR; + /* Get the chunk index type */ + if(H5D_layout_idx_type_test(d, &idx_type) < 0) TEST_ERROR; + + /* Verify index type */ + if(low == H5F_LIBVER_LATEST) { + if(idx_type != H5D_CHUNK_IDX_BT2) + FAIL_PUTS_ERROR("should be using v2 B-tree as index"); + } else if(idx_type != H5D_CHUNK_IDX_BTREE) + FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + /* Extend both dimensions of the dataset */ if(H5Dset_extent(d, nsize) < 0) TEST_ERROR; @@ -7345,29 +7542,45 @@ error: * Programmer: Raymond Lu * 11 Feb 2009 * + * Modifications: + * Vailin Choi; June 2010 + * Added 2-D dataset with unlimited dimensions to the test. *------------------------------------------------------------------------- */ static herr_t test_big_chunks_bypass_cache(hid_t fapl) { char filename[FILENAME_BUF_SIZE]; - hid_t fid = -1; /* File ID */ - hid_t fapl_local = -1; /* File access property list ID */ - hid_t dcpl = -1; /* Dataset creation property list ID */ - hid_t sid = -1; /* Dataspace ID */ - hid_t dsid = -1; /* Dataset ID */ - hsize_t dim, chunk_dim; /* Dataset and chunk dimensions */ - size_t rdcc_nelmts, rdcc_nbytes; - int fvalue = BYPASS_FILL_VALUE; - hsize_t count, stride, offset, block; + hid_t fid = -1; /* File ID */ + hid_t fapl_local = -1; /* File access property list ID */ + hid_t dcpl = -1, t_dcpl = -1; /* Dataset creation property list ID */ + hid_t sid = -1, t_sid = -1; /* Dataspace ID */ + hid_t mid; /* Memory space ID */ + hid_t dsid = -1, t_dsid = -1; /* Dataset ID */ + hsize_t dim, chunk_dim; /* Dataset and chunk dimensions */ + hsize_t t_dim[2], t_max[2], t_chunk_dim[2]; /* Dataset and chunk dimensions */ + size_t rdcc_nelmts, rdcc_nbytes; /* Chunk cache parameters */ + int fvalue = BYPASS_FILL_VALUE; /* Fill value */ + hsize_t count, stride, offset, block; /* Setting for hyperslab (1-D) */ + hsize_t t_count[2], t_stride[2], t_offset[2], t_block[2]; /* Setting for hyperslab (2-D) */ + /* Buffer for reading and writing data (1-D) */ static int wdata[BYPASS_CHUNK_DIM/2], rdata1[BYPASS_DIM], - rdata2[BYPASS_CHUNK_DIM/2]; - int i, j; + rdata2[BYPASS_CHUNK_DIM/2]; + /* Buffer for reading and writing data (2-D) */ + static int t_wdata[BYPASS_CHUNK_DIM/2][BYPASS_CHUNK_DIM/2], t_rdata1[BYPASS_DIM][BYPASS_DIM], + t_rdata2[BYPASS_CHUNK_DIM/2][BYPASS_CHUNK_DIM/2]; + int i, j; /* Local index variables */ + H5F_libver_t low; /* File format low bound */ + H5D_chunk_index_t idx_type, t_idx_type; /* Dataset chunk index types */ + TESTING("big chunks bypassing the cache"); h5_fixname(FILENAME[9], fapl, filename, sizeof filename); + /* Check if we are using the latest version of the format */ + if(H5Pget_libver_bounds(fapl, &low, NULL) < 0) FAIL_STACK_ERROR + /* Copy fapl passed to this function (as we will be modifying it) */ if((fapl_local = H5Pcopy(fapl)) < 0) FAIL_STACK_ERROR @@ -7379,52 +7592,101 @@ test_big_chunks_bypass_cache(hid_t fapl) /* Create file */ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_local)) < 0) FAIL_STACK_ERROR - /* Create 1-D dataspace */ - dim = BYPASS_DIM; + /* Create 1-D & 2-D dataspace */ + dim = t_dim[0] = t_dim[1] = BYPASS_DIM; + t_max[0] = t_max[1] = H5S_UNLIMITED; if((sid = H5Screate_simple(1, &dim, NULL)) < 0) FAIL_STACK_ERROR + if((t_sid = H5Screate_simple(2, t_dim, t_max)) < 0) FAIL_STACK_ERROR - /* Create dataset creation property list */ + /* Create 1-D & 2-D dataset creation property list */ if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR + if((t_dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR - /* Define chunk size. There will be only 2 chunks in the dataset. */ - chunk_dim = BYPASS_CHUNK_DIM; + /* Define chunk size. */ + /* There will be 2 chunks in 1-D dataset & 4 chunks in the 2-D dataset */ + chunk_dim = t_chunk_dim[0] = t_chunk_dim[1] = BYPASS_CHUNK_DIM; if(H5Pset_chunk(dcpl, 1, &chunk_dim) < 0) FAIL_STACK_ERROR + if(H5Pset_chunk(t_dcpl, 2, t_chunk_dim) < 0) FAIL_STACK_ERROR /* Define fill value, fill time, and chunk allocation time */ if(H5Pset_fill_value(dcpl, H5T_NATIVE_INT, &fvalue) < 0) FAIL_STACK_ERROR + if(H5Pset_fill_value(t_dcpl, H5T_NATIVE_INT, &fvalue) < 0) FAIL_STACK_ERROR + if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_IFSET) < 0) FAIL_STACK_ERROR + if(H5Pset_fill_time(t_dcpl, H5D_FILL_TIME_IFSET) < 0) FAIL_STACK_ERROR + if(H5Pset_alloc_time(dcpl, H5D_ALLOC_TIME_INCR) < 0) FAIL_STACK_ERROR + if(H5Pset_alloc_time(t_dcpl, H5D_ALLOC_TIME_INCR) < 0) FAIL_STACK_ERROR - /* Create a first dataset */ + /* Create the first 1-D dataset */ if((dsid = H5Dcreate2(fid, BYPASS_DATASET1, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + /* Create the first 2-D dataset */ + if((t_dsid = H5Dcreate2(fid, T_BYPASS_DATASET1, H5T_NATIVE_INT, t_sid, H5P_DEFAULT, t_dcpl, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + + /* Get the chunk index types for 1-D and 2-d datasets */ + if(H5D_layout_idx_type_test(dsid, &idx_type) < 0) FAIL_STACK_ERROR + if(H5D_layout_idx_type_test(t_dsid, &t_idx_type) < 0) FAIL_STACK_ERROR + + /* Chunk index type expected depends on whether we are using the latest version of the format */ + if(low == H5F_LIBVER_LATEST) { + /* Verify index type */ + if(idx_type != H5D_CHUNK_IDX_FARRAY) FAIL_PUTS_ERROR("should be using Fixed Array as index"); + if(t_idx_type != H5D_CHUNK_IDX_BT2) FAIL_PUTS_ERROR("should be using v2 B-tree as index"); + } else { + /* Verify index type */ + if(idx_type != H5D_CHUNK_IDX_BTREE) FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + if(t_idx_type != H5D_CHUNK_IDX_BTREE) FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + } /* end else */ + /* Select first chunk to write the data */ - offset = 0; - count = 1; - stride = 1; - block = BYPASS_CHUNK_DIM / 2; + offset = t_offset[0] = t_offset[1] = 0; + count = t_count[0] = t_count[1] = 1; + stride = t_stride[0] = t_stride[1] = 1; + block = t_block[0] = t_block[1] = BYPASS_CHUNK_DIM / 2; if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, &offset, &stride, &count, &block) < 0) FAIL_STACK_ERROR - /* Initialize data to write */ + if(H5Sselect_hyperslab(t_sid, H5S_SELECT_SET, t_offset, t_stride, t_count, t_block) < 0) + FAIL_STACK_ERROR + + /* Initialize data to write for 1-D dataset */ for(i = 0; i < BYPASS_CHUNK_DIM / 2; i++) wdata[i] = i; + /* Initialize data to write for 2-D dataset */ + for(i = 0; i < BYPASS_CHUNK_DIM / 2; i++) + for(j = 0; j < BYPASS_CHUNK_DIM / 2; j++) + t_wdata[i][j] = j; + + /* Set up memory space for the 2-D dataset */ + mid = H5Screate_simple(2, t_block, NULL); + + /* Write to the first 1-D & 2-D datasets */ /* This write should go through the cache because fill value is used. */ if(H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, sid, H5P_DEFAULT, wdata) < 0) FAIL_STACK_ERROR + if(H5Dwrite(t_dsid, H5T_NATIVE_INT, mid, t_sid, H5P_DEFAULT, t_wdata) < 0) + FAIL_STACK_ERROR + /* Close the first 1-D & 2-D datasets */ if(H5Dclose(dsid) < 0) FAIL_STACK_ERROR + if(H5Dclose(t_dsid) < 0) FAIL_STACK_ERROR - /* Reopen the dataset */ + /* Reopen the first 1-D & 2-D datasets */ if((dsid = H5Dopen2(fid, BYPASS_DATASET1, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((t_dsid = H5Dopen2(fid, T_BYPASS_DATASET1, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR /* Reads both 2 chunks. Reading the second chunk should bypass the cache because the * chunk is bigger than the cache size and it isn't allocated on disk. */ if(H5Dread(dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata1) < 0) FAIL_STACK_ERROR + if(H5Dread(t_dsid, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, t_rdata1) < 0) + FAIL_STACK_ERROR + /* Verify data for the first 1-D dataset */ for(i = 0; i < BYPASS_CHUNK_DIM / 2; i++) if(rdata1[i] != i) { printf(" Read different values than written in the 1st chunk.\n"); @@ -7439,41 +7701,88 @@ test_big_chunks_bypass_cache(hid_t fapl) TEST_ERROR } /* end if */ - /* Close the first dataset */ + /* Verify data for the first 2-D dataset */ + for(i = 0; i < BYPASS_CHUNK_DIM / 2; i++) + for(j = 0; j < BYPASS_CHUNK_DIM / 2; j++) + if(t_rdata1[i][j] != j) { + printf(" Read different values than written in the 1st chunk.\n"); + printf(" At line %d and index (%d, %d), t_rdata1 = %d. It should be %d.\n", + __LINE__, i, j, t_rdata1[i][j], j); + TEST_ERROR + } /* end if */ + + for(i = BYPASS_CHUNK_DIM / 2; i < BYPASS_DIM; i++) + for(j = BYPASS_CHUNK_DIM / 2; j < BYPASS_DIM; j++) + if(t_rdata1[i][j] != fvalue) { + printf(" Read different values than written in the 2nd chunk.\n"); + printf(" At line %d and index (%d, %d), t_rdata1 = %d. It should be %d.\n", + __LINE__, i, j, t_rdata1[i][j], fvalue); + TEST_ERROR + } /* end if */ + + /* Close the first 1-D & 2-D datasets */ if(H5Dclose(dsid) < 0) FAIL_STACK_ERROR + if(H5Dclose(t_dsid) < 0) FAIL_STACK_ERROR /* Create a second dataset without fill value. This time, both write * and read should bypass the cache because the chunk is bigger than the * cache size and it's not allocated on disk. */ if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) FAIL_STACK_ERROR + if(H5Pset_fill_time(t_dcpl, H5D_FILL_TIME_NEVER) < 0) FAIL_STACK_ERROR + /* Create a second 1-D & 2-D dataset */ if((dsid = H5Dcreate2(fid, BYPASS_DATASET2, H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((t_dsid = H5Dcreate2(fid, T_BYPASS_DATASET2, H5T_NATIVE_INT, t_sid, H5P_DEFAULT, t_dcpl, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + /* Write to the second 1-D & 2-D dataset */ if(H5Dwrite(dsid, H5T_NATIVE_INT, H5S_ALL, sid, H5P_DEFAULT, wdata) < 0) FAIL_STACK_ERROR + if(H5Dwrite(t_dsid, H5T_NATIVE_INT, mid, t_sid, H5P_DEFAULT, t_wdata) < 0) + FAIL_STACK_ERROR + /* Close the second 1-D & 2-D dataset */ if(H5Dclose(dsid) < 0) FAIL_STACK_ERROR + if(H5Dclose(t_dsid) < 0) FAIL_STACK_ERROR - /* Reopen the dataset */ + /* Reopen the second 1-d dataset and 2-d dataset */ if((dsid = H5Dopen2(fid, BYPASS_DATASET2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((t_dsid = H5Dopen2(fid, T_BYPASS_DATASET2, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR /* Read back only the part that was written to the file. Reading the * half chunk should bypass the cache because the chunk is bigger than * the cache size. */ if(H5Dread(dsid, H5T_NATIVE_INT, H5S_ALL, sid, H5P_DEFAULT, rdata2) < 0) + FAIL_STACK_ERROR + if(H5Dread(t_dsid, H5T_NATIVE_INT, mid, t_sid, H5P_DEFAULT, t_rdata2) < 0) + FAIL_STACK_ERROR + /* Verify data for the second 1-D dataset */ for(i = 0; i < BYPASS_CHUNK_DIM / 2; i++) - if(rdata2[i] != i) { + if(rdata2[i] != i) { printf(" Read different values than written in the chunk.\n"); printf(" At line %d and index %d, rdata2 = %d. It should be %d.\n", __LINE__, i, rdata2[i], i); TEST_ERROR } /* end if */ + /* Verify data for the second 2-D dataset */ + for(i = 0; i < BYPASS_CHUNK_DIM / 2; i++) + for(j = 0; j < BYPASS_CHUNK_DIM / 2; j++) + if(t_rdata2[i][j] != j) { + printf(" Read different values than written in the chunk.\n"); + printf(" At line %d and index (%d, %d), t_rdata2 = %d. It should be %d.\n", + __LINE__, i, j, t_rdata2[i][j], j); + TEST_ERROR + } /* end if */ + /* Close IDs */ if(H5Sclose(sid) < 0) FAIL_STACK_ERROR + if(H5Sclose(t_sid) < 0) FAIL_STACK_ERROR if(H5Dclose(dsid) < 0) FAIL_STACK_ERROR + if(H5Dclose(t_dsid) < 0) FAIL_STACK_ERROR if(H5Pclose(dcpl) < 0) FAIL_STACK_ERROR + if(H5Pclose(t_dcpl) < 0) FAIL_STACK_ERROR if(H5Pclose(fapl_local) < 0) FAIL_STACK_ERROR if(H5Fclose(fid) < 0) FAIL_STACK_ERROR @@ -7483,9 +7792,12 @@ test_big_chunks_bypass_cache(hid_t fapl) error: H5E_BEGIN_TRY { H5Pclose(dcpl); + H5Pclose(t_dcpl); H5Pclose(fapl_local); H5Dclose(dsid); + H5Dclose(t_dsid); H5Sclose(sid); + H5Sclose(t_sid); H5Fclose(fid); } H5E_END_TRY; return -1; @@ -8025,26 +8337,32 @@ filter_expand(unsigned int flags, size_t UNUSED cd_nelmts, * Programmer: Quincey Koziol * Tuesday, March 31, 2009 * + * Modifications: + * Vailin Choi; June 2010 + * Added 2-D dataset with unlimited dimensions to the test. + * *------------------------------------------------------------------------- */ static herr_t test_chunk_expand(hid_t fapl) { char filename[FILENAME_BUF_SIZE]; - hid_t fid = -1; /* File ID */ - hid_t dcpl = -1; /* Dataset creation property list ID */ - hid_t sid = -1; /* Dataspace ID */ - hid_t scalar_sid = -1;/* Scalar dataspace ID */ - hid_t dsid = -1; /* Dataset ID */ - hsize_t dim, max_dim, chunk_dim; /* Dataset and chunk dimensions */ - H5D_chunk_index_t idx_type; /* Dataset chunk index type */ - H5F_libver_t low, high; /* File format bounds */ - hsize_t hs_offset; /* Hyperslab offset */ - hsize_t hs_size; /* Hyperslab size */ - H5D_alloc_time_t alloc_time; /* Storage allocation time */ - unsigned write_elem, read_elem; /* Element written/read */ - unsigned u; /* Local index variable */ - herr_t status; /* Generic return value */ + hid_t fid = -1; /* File ID */ + hid_t dcpl = -1, dcpl2 = -1; /* Dataset creation property list ID */ + hid_t sid = -1, sid2 = -1; /* Dataspace ID */ + hid_t scalar_sid = -1; /* Scalar dataspace ID */ + hid_t dsid = -1, dsid2 = -1; /* Dataset ID */ + hsize_t dim, max_dim, chunk_dim; /* Dataset and chunk dimensions */ + hsize_t dim2[2], max_dim2[2], chunk_dim2[2]; /* Dataset and chunk dimensions */ + H5D_chunk_index_t idx_type, idx_type2; /* Dataset chunk index type */ + H5F_libver_t low, high; /* File format bounds */ + hsize_t hs_offset, hs_offset2[2]; /* Hyperslab offset */ + hsize_t hs_size, hs_size2[2]; /* Hyperslab size */ + H5D_alloc_time_t alloc_time; /* Storage allocation time */ + unsigned write_elem, read_elem; /* Element written/read */ + unsigned write_elem2, read_elem2; /* Element written/read */ + unsigned u; /* Local index variable */ + herr_t status; /* Generic return value */ TESTING("filter expanding chunks too much"); @@ -8066,34 +8384,41 @@ test_chunk_expand(hid_t fapl) /* Loop over storage allocation time */ for(alloc_time = H5D_ALLOC_TIME_EARLY; alloc_time <= H5D_ALLOC_TIME_INCR; alloc_time++) { + /* Create file */ if((fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) FAIL_STACK_ERROR /* Create dataset creation property list */ if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR + if((dcpl2 = H5Pcreate(H5P_DATASET_CREATE)) < 0) FAIL_STACK_ERROR /* Set chunking */ - chunk_dim = 10; + chunk_dim = chunk_dim2[0] = chunk_dim2[1] = 10; if(H5Pset_chunk(dcpl, 1, &chunk_dim) < 0) FAIL_STACK_ERROR + if(H5Pset_chunk(dcpl2, 2, chunk_dim2) < 0) FAIL_STACK_ERROR /* Set fill time */ if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) FAIL_STACK_ERROR + if(H5Pset_fill_time(dcpl2, H5D_FILL_TIME_ALLOC) < 0) FAIL_STACK_ERROR /* Set allocation time */ if(H5Pset_alloc_time(dcpl, alloc_time) < 0) FAIL_STACK_ERROR + if(H5Pset_alloc_time(dcpl2, alloc_time) < 0) FAIL_STACK_ERROR /* Set "expand" filter */ if(H5Pset_filter(dcpl, H5Z_FILTER_EXPAND, 0, (size_t)0, NULL) < 0) FAIL_STACK_ERROR + if(H5Pset_filter(dcpl2, H5Z_FILTER_EXPAND, 0, (size_t)0, NULL) < 0) FAIL_STACK_ERROR /* Create scalar dataspace */ if((scalar_sid = H5Screate(H5S_SCALAR)) < 0) FAIL_STACK_ERROR - /* Create 1-D dataspace */ - dim = 100; - max_dim = H5S_UNLIMITED; + /* Create 1-D and 2-D dataspace */ + dim = dim2[0] = dim2[1] = 100; + max_dim = max_dim2[0] = max_dim2[1] = H5S_UNLIMITED; if((sid = H5Screate_simple(1, &dim, &max_dim)) < 0) FAIL_STACK_ERROR + if((sid2 = H5Screate_simple(2, dim2, max_dim2)) < 0) FAIL_STACK_ERROR - /* Create chunked dataset */ + /* Create 1-D & 2-D chunked datasets */ if(H5D_ALLOC_TIME_EARLY == alloc_time) { /* Make the expansion factor large enough to cause failure right away */ filter_expand_factor_g = 8; @@ -8102,202 +8427,272 @@ test_chunk_expand(hid_t fapl) dsid = H5Dcreate2(fid, "dset", H5T_NATIVE_UINT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT); } H5E_END_TRY; if(dsid >= 0) FAIL_PUTS_ERROR("should fail to create dataset when allocation time is early"); + + H5E_BEGIN_TRY { + dsid2 = H5Dcreate2(fid, "dset2", H5T_NATIVE_UINT, sid2, H5P_DEFAULT, dcpl2, H5P_DEFAULT); + } H5E_END_TRY; + if(dsid2 >= 0) FAIL_PUTS_ERROR("should fail to create dataset when allocation time is early"); + } /* end if */ else { if((dsid = H5Dcreate2(fid, "dset", H5T_NATIVE_UINT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((dsid2 = H5Dcreate2(fid, "dset2", H5T_NATIVE_UINT, sid2, H5P_DEFAULT, dcpl2, H5P_DEFAULT)) < 0) + FAIL_STACK_ERROR + /* Get the chunk index type */ if(H5D_layout_idx_type_test(dsid, &idx_type) < 0) FAIL_STACK_ERROR + if(H5D_layout_idx_type_test(dsid2, &idx_type2) < 0) FAIL_STACK_ERROR - /* Chunk index tyepe expected depends on whether we are using the latest version of the format */ + /* Chunk index type expected depends on whether we are using the latest version of the format */ if(low == H5F_LIBVER_LATEST) { /* Verify index type */ if(idx_type != H5D_CHUNK_IDX_EARRAY) FAIL_PUTS_ERROR("should be using extensible array as index"); + if(idx_type2 != H5D_CHUNK_IDX_BT2) FAIL_PUTS_ERROR("should be using v2 B-tree as index"); } /* end if */ else { /* Verify index type */ if(idx_type != H5D_CHUNK_IDX_BTREE) FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + if(idx_type2 != H5D_CHUNK_IDX_BTREE) FAIL_PUTS_ERROR("should be using v1 B-tree as index"); } /* end else */ /* Fill elements */ - hs_size = 1; + hs_size = hs_size2[0] = hs_size2[1] = 1; for(u = 0; u < 100; u++) { - /* Select a single element in the dataset */ - hs_offset = u; + + hs_offset = hs_offset2[0] = hs_offset2[1] = u; + + /* Select a single element in the 1-D dataset */ if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, &hs_offset, NULL, &hs_size, NULL) < 0) FAIL_STACK_ERROR + /* Select a single element in the 2-D dataset; NOT every element is selected */ + if(H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_offset2, NULL, hs_size2, NULL) < 0) FAIL_STACK_ERROR + /* Read (unwritten) element from dataset */ - read_elem = 1; + read_elem = read_elem2 = 1; if(H5Dread(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &read_elem) < 0) FAIL_STACK_ERROR + if(H5Dread(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &read_elem2) < 0) FAIL_STACK_ERROR /* Verify unwritten element is fill value (0) */ if(read_elem != 0) FAIL_PUTS_ERROR("invalid unwritten element read"); + if(read_elem2 != 0) FAIL_PUTS_ERROR("invalid unwritten element read"); /* Don't expand chunks yet */ filter_expand_factor_g = 0; - /* Write element to dataset */ - write_elem = u; + /* Write element to the datasets */ + write_elem = write_elem2 = u; if(H5Dwrite(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &write_elem) < 0) FAIL_STACK_ERROR + if(H5Dwrite(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &write_elem2) < 0) FAIL_STACK_ERROR - /* Read element from dataset */ + /* Read element from the datasets */ read_elem = write_elem + 1; + read_elem2 = write_elem2 + 1; if(H5Dread(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &read_elem) < 0) FAIL_STACK_ERROR + if(H5Dread(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &read_elem2) < 0) FAIL_STACK_ERROR /* Verify written element is read in */ if(read_elem != write_elem) FAIL_PUTS_ERROR("invalid written element read"); + if(read_elem2 != write_elem2) FAIL_PUTS_ERROR("invalid written element read"); /* Expand chunks now */ filter_expand_factor_g = 8; - /* Write element to dataset */ - write_elem = u; + /* Write element to the datasets */ + write_elem = write_elem2 = u; H5E_BEGIN_TRY { status = H5Dwrite(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &write_elem); } H5E_END_TRY; if(status >= 0) FAIL_PUTS_ERROR("should fail to write to dataset when allocation time is not early"); + + H5E_BEGIN_TRY { + status = H5Dwrite(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &write_elem2); + } H5E_END_TRY; + if(status >= 0) FAIL_PUTS_ERROR("should fail to write to dataset when allocation time is not early"); } /* end for */ /* Incrementally extend dataset and verify write/reads */ while(dim < 1000) { - /* Extend dataset */ + /* Extend the datasets */ dim += 100; + dim2[0] += 100; + dim2[1] += 100; if(H5Dset_extent(dsid, &dim) < 0) FAIL_STACK_ERROR + if(H5Dset_extent(dsid2, dim2) < 0) FAIL_STACK_ERROR /* Close old dataspace */ if(H5Sclose(sid) < 0) FAIL_STACK_ERROR + if(H5Sclose(sid2) < 0) FAIL_STACK_ERROR - /* Get dataspace for dataset now */ + /* Get dataspace for the datasets now */ if((sid = H5Dget_space(dsid)) < 0) FAIL_STACK_ERROR + if((sid2 = H5Dget_space(dsid2)) < 0) FAIL_STACK_ERROR /* Fill new elements */ - hs_size = 1; + hs_size = hs_size2[0] = hs_size2[1] = 1; for(u = 0; u < 100; u++) { - /* Select a single element in the dataset */ + /* Select a single element in the datasets */ hs_offset = (dim + u) - 100; + hs_offset2[0] = (dim2[0] + u) - 100; + hs_offset2[1] = (dim2[1] + u) - 100; if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, &hs_offset, NULL, &hs_size, NULL) < 0) FAIL_STACK_ERROR + if(H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_offset2, NULL, hs_size2, NULL) < 0) FAIL_STACK_ERROR - /* Read (unwritten) element from dataset */ - read_elem = 1; + /* Read (unwritten) element from the datasets */ + read_elem = read_elem2 = 1; if(H5Dread(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &read_elem) < 0) FAIL_STACK_ERROR + if(H5Dread(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &read_elem2) < 0) FAIL_STACK_ERROR /* Verify unwritten element is fill value (0) */ if(read_elem != 0) FAIL_PUTS_ERROR("invalid unwritten element read"); + if(read_elem2 != 0) FAIL_PUTS_ERROR("invalid unwritten element read"); /* Don't expand chunks yet */ filter_expand_factor_g = 0; - /* Write element to dataset */ - write_elem = u; + /* Write element to the datasets */ + write_elem = write_elem2 = u; if(H5Dwrite(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &write_elem) < 0) FAIL_STACK_ERROR + if(H5Dwrite(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &write_elem2) < 0) FAIL_STACK_ERROR - /* Read element from dataset */ + /* Read element from the datasets */ read_elem = write_elem + 1; + read_elem2 = write_elem2 + 1; if(H5Dread(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &read_elem) < 0) FAIL_STACK_ERROR + if(H5Dread(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &read_elem2) < 0) FAIL_STACK_ERROR /* Verify written element is read in */ if(read_elem != write_elem) FAIL_PUTS_ERROR("invalid written element read"); + if(read_elem2 != write_elem2) FAIL_PUTS_ERROR("invalid written element read"); /* Expand chunks now */ filter_expand_factor_g = 8; - /* Write element to dataset */ - write_elem = u; + /* Write element to the datasets */ + write_elem = write_elem2 = u; H5E_BEGIN_TRY { status = H5Dwrite(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &write_elem); } H5E_END_TRY; if(status >= 0) FAIL_PUTS_ERROR("should fail to write to dataset when allocation time is not early"); + + H5E_BEGIN_TRY { + status = H5Dwrite(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &write_elem2); + } H5E_END_TRY; + if(status >= 0) FAIL_PUTS_ERROR("should fail to write to dataset when allocation time is not early"); } /* end for */ } /* end while */ - /* Close dataset */ + /* Close the datasets */ if(H5Dclose(dsid) < 0) FAIL_STACK_ERROR + if(H5Dclose(dsid2) < 0) FAIL_STACK_ERROR } /* end else */ /* Close everything */ if(H5Sclose(sid) < 0) FAIL_STACK_ERROR + if(H5Sclose(sid2) < 0) FAIL_STACK_ERROR if(H5Sclose(scalar_sid) < 0) FAIL_STACK_ERROR if(H5Pclose(dcpl) < 0) FAIL_STACK_ERROR + if(H5Pclose(dcpl2) < 0) FAIL_STACK_ERROR if(H5Fclose(fid) < 0) FAIL_STACK_ERROR /* If the dataset was created, do some extra testing */ if(H5D_ALLOC_TIME_EARLY != alloc_time) { - /* Re-open file & dataset */ + /* Re-open file & datasets */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR - /* Open dataset */ + /* Open the datasets */ if((dsid = H5Dopen2(fid, "dset", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR + if((dsid2 = H5Dopen2(fid, "dset2", H5P_DEFAULT)) < 0) FAIL_STACK_ERROR - /* Get the chunk index type */ + /* Get the chunk index type for the two datasets */ if(H5D_layout_idx_type_test(dsid, &idx_type) < 0) FAIL_STACK_ERROR + if(H5D_layout_idx_type_test(dsid2, &idx_type2) < 0) FAIL_STACK_ERROR - /* Chunk index tyepe expected depends on whether we are using the latest version of the format */ + /* Chunk index type expected depends on whether we are using the latest version of the format */ if(low == H5F_LIBVER_LATEST) { /* Verify index type */ if(idx_type != H5D_CHUNK_IDX_EARRAY) FAIL_PUTS_ERROR("should be using extensible array as index"); + if(idx_type2 != H5D_CHUNK_IDX_BT2) FAIL_PUTS_ERROR("should be using v2 B-tree as index"); } /* end if */ else { /* Verify index type */ if(idx_type != H5D_CHUNK_IDX_BTREE) FAIL_PUTS_ERROR("should be using v1 B-tree as index"); + if(idx_type2 != H5D_CHUNK_IDX_BTREE) FAIL_PUTS_ERROR("should be using v1 B-tree as index"); } /* end else */ /* Create scalar dataspace */ if((scalar_sid = H5Screate(H5S_SCALAR)) < 0) FAIL_STACK_ERROR - /* Get dataspace for dataset now */ + /* Get dataspace for the datasets now */ if((sid = H5Dget_space(dsid)) < 0) FAIL_STACK_ERROR + if((sid2 = H5Dget_space(dsid2)) < 0) FAIL_STACK_ERROR /* Read elements */ - hs_size = 1; + hs_size = hs_size2[0] = hs_size2[1] = 1; for(u = 0; u < 1000; u++) { - /* Select a single element in the dataset */ - hs_offset = u; + /* Select a single element in the datasets */ + hs_offset = hs_offset2[0] = hs_offset2[1] = u; if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, &hs_offset, NULL, &hs_size, NULL) < 0) FAIL_STACK_ERROR + if(H5Sselect_hyperslab(sid2, H5S_SELECT_SET, hs_offset2, NULL, hs_size2, NULL) < 0) FAIL_STACK_ERROR - /* Read element from dataset */ - read_elem = u + 1; + /* Read element from the datasets */ + read_elem = read_elem2 = u + 1; if(H5Dread(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &read_elem) < 0) FAIL_STACK_ERROR + if(H5Dread(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &read_elem2) < 0) FAIL_STACK_ERROR /* Verify unwritten element is proper value */ if(read_elem != (u % 100)) FAIL_PUTS_ERROR("invalid element read"); + if(read_elem2 != (u % 100)) FAIL_PUTS_ERROR("invalid element read"); /* Don't expand chunks yet */ filter_expand_factor_g = 0; - /* Write element to dataset */ - write_elem = u % 100; + /* Write element to the datasets */ + write_elem = write_elem2 = u % 100; if(H5Dwrite(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &write_elem) < 0) FAIL_STACK_ERROR + if(H5Dwrite(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &write_elem2) < 0) FAIL_STACK_ERROR - /* Read element from dataset */ + /* Read element from the datasets */ read_elem = write_elem + 1; + read_elem2 = write_elem2 + 1; if(H5Dread(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &read_elem) < 0) FAIL_STACK_ERROR + if(H5Dread(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &read_elem2) < 0) FAIL_STACK_ERROR /* Verify written element is read in */ if(read_elem != write_elem) FAIL_PUTS_ERROR("invalid written element read"); + if(read_elem2 != write_elem2) FAIL_PUTS_ERROR("invalid written element read"); /* Expand chunks now */ filter_expand_factor_g = 8; - /* Write element to dataset */ - write_elem = u % 100; + /* Write element to the datasets */ + write_elem = write_elem2 = u % 100; H5E_BEGIN_TRY { status = H5Dwrite(dsid, H5T_NATIVE_UINT, scalar_sid, sid, H5P_DEFAULT, &write_elem); } H5E_END_TRY; if(status >= 0) FAIL_PUTS_ERROR("should fail to write to dataset when allocation time is not early"); + + H5E_BEGIN_TRY { + status = H5Dwrite(dsid2, H5T_NATIVE_UINT, scalar_sid, sid2, H5P_DEFAULT, &write_elem2); + } H5E_END_TRY; + if(status >= 0) FAIL_PUTS_ERROR("should fail to write to dataset when allocation time is not early"); } /* end for */ /* Close everything */ if(H5Sclose(sid) < 0) FAIL_STACK_ERROR + if(H5Sclose(sid2) < 0) FAIL_STACK_ERROR if(H5Sclose(scalar_sid) < 0) FAIL_STACK_ERROR if(H5Dclose(dsid) < 0) FAIL_STACK_ERROR + if(H5Dclose(dsid2) < 0) FAIL_STACK_ERROR if(H5Fclose(fid) < 0) FAIL_STACK_ERROR /* Re-open file */ if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0) FAIL_STACK_ERROR - /* Delete dataset */ + /* Delete the datasets */ if(H5Ldelete(fid, "dset", H5P_DEFAULT) < 0) FAIL_STACK_ERROR + if(H5Ldelete(fid, "dset2", H5P_DEFAULT) < 0) FAIL_STACK_ERROR /* Close everything */ if(H5Fclose(fid) < 0) FAIL_STACK_ERROR @@ -8318,8 +8713,11 @@ test_chunk_expand(hid_t fapl) error: H5E_BEGIN_TRY { H5Pclose(dcpl); + H5Pclose(dcpl2); H5Dclose(dsid); + H5Dclose(dsid2); H5Sclose(sid); + H5Sclose(sid2); H5Sclose(scalar_sid); H5Fclose(fid); } H5E_END_TRY; @@ -8522,8 +8920,7 @@ test_fixed_array(hid_t fapl) if(low == H5F_LIBVER_LATEST) { if(idx_type != H5D_CHUNK_IDX_FARRAY) FAIL_PUTS_ERROR("should be using Fixed Array as index"); - } /* end if */ - else { + } else { if(idx_type != H5D_CHUNK_IDX_BTREE) FAIL_PUTS_ERROR("should be using v1 B-tree as index"); } /* end else */ @@ -8712,6 +9109,7 @@ error: return -1; } /* end test_fixed_array() */ + /*------------------------------------------------------------------------- * * test_idx_compatible(): diff --git a/test/objcopy.c b/test/objcopy.c index edeca09..941d113 100755 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -3062,7 +3062,8 @@ test_copy_dataset_no_edge_filt(hid_t fcpl_src, hid_t fcpl_dst, hid_t fapl) /* open the destination dataset */ if((did2 = H5Dopen2(fid_dst, NAME_DATASET_CHUNKED, H5P_DEFAULT)) < 0) TEST_ERROR - if(compare_idx_type(fapl, did2, H5D_CHUNK_IDX_FARRAY, H5D_CHUNK_IDX_BTREE) != TRUE) + /* H5Pset_chunk_opts() will set layout version to 4 which will use latest indexing available */ + if(compare_idx_type(fapl, did2, H5D_CHUNK_IDX_FARRAY, H5D_CHUNK_IDX_FARRAY) != TRUE) TEST_ERROR /* Check if the datasets are equal */ diff --git a/test/set_extent.c b/test/set_extent.c index 8de5649..b99d1c3 100644 --- a/test/set_extent.c +++ b/test/set_extent.c @@ -2765,7 +2765,8 @@ static int test_random_rank4( hid_t fapl, hid_t dcpl, hbool_t do_fillvalue, /*!FIXME Skip the test if a fixed array index is requested, as resizing * fixed arrays is broken now. Extensible arrays are also broken. Remove * these lines as appropriate when these problems are fixed. */ - if(index_type == RANK4_INDEX_FARRAY || index_type == RANK4_INDEX_EARRAY) + /* Fixed Array index type is now fixed */ + if(index_type == RANK4_INDEX_EARRAY) return 0; /* create a new file */ diff --git a/tools/h5dump/h5dumpgentest.c b/tools/h5dump/h5dumpgentest.c index e8c888c..196e5e9 100644 --- a/tools/h5dump/h5dumpgentest.c +++ b/tools/h5dump/h5dumpgentest.c @@ -6786,13 +6786,18 @@ gent_fs_strategy_threshold(void) } /* - * Create a file with new format. - * Create one dataset with (set_chunk, fixed dimension) + * Create a file with new format: + * Create one dataset with (set_chunk, fixed dims, null max. dims) * so that Fixed Array indexing will be used. - * Create one dataset with (set_chunk, fixed dimension, filter) + * Create one dataset with (set_chunk, fixed dims, null max. dims, filter) * so that Fixed Array indexing will be used. - * Create one dataset with (set_chunk, non-fixed dimension) - * so that B-tree indexing will be used. + * Create one dataset with (set_chunk, fixed dims, fixed max. dims) + * so that Fixed Array indexing will be used. + * + * Modifications: + * Fixed Array indexing will be used for chunked dataset + * with fixed max. dims setting. + * */ static void gent_dataset_idx(void) diff --git a/tools/misc/h5debug.c b/tools/misc/h5debug.c index 50d81d0..ff8cdf0 100644 --- a/tools/misc/h5debug.c +++ b/tools/misc/h5debug.c @@ -24,6 +24,7 @@ *------------------------------------------------------------------------- */ #define H5A_PACKAGE /*suppress error about including H5Apkg */ +#define H5D_PACKAGE /*suppress error about including H5Dpkg */ #define H5B2_PACKAGE /*suppress error about including H5B2pkg */ #define H5B2_TESTING /*suppress warning about H5B2 testing funcs*/ #define H5EA_PACKAGE /*suppress error about including H5EApkg */ @@ -39,7 +40,7 @@ #include "H5private.h" /* Generic Functions */ #include "H5Apkg.h" /* Attributes */ #include "H5B2pkg.h" /* v2 B-trees */ -#include "H5Dprivate.h" /* Datasets */ +#include "H5Dpkg.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5EApkg.h" /* Extensible Arrays */ #include "H5FApkg.h" /* Fixed Arrays */ @@ -71,7 +72,10 @@ * koziol@hdfgroup.org * Sep 11 2008 * - *------------------------------------------------------------------------- + * Modifications: + * Vailin Choi; August 2010 + * Added v2 B-tree indexing for chunked dataset >1 unlimited dimensions. + *--------------------------------------------------------------------------- */ static const H5B2_class_t * get_H5B2_class(const uint8_t *sig) @@ -120,6 +124,14 @@ get_H5B2_class(const uint8_t *sig) cls = H5A_BT2_CORDER; break; + case H5B2_CDSET_ID: + cls = H5D_BT2; + break; + + case H5B2_CDSET_FILT_ID: + cls = H5D_BT2_FILT; + break; + default: fprintf(stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype)); HDexit(4); @@ -228,6 +240,9 @@ get_H5FA_class(const uint8_t *sig) * matzke@llnl.gov * Jul 18 1997 * + * Modifications: + * Vailin Choi; August 2010 + * Modified to handle v2 B-tree indexing for chunked dataset >1 unlimited dimensions. *------------------------------------------------------------------------- */ int @@ -235,7 +250,7 @@ main(int argc, char *argv[]) { hid_t fid, fapl, dxpl; H5F_t *f; - haddr_t addr = 0, extra = 0, extra2 = 0, extra3 = 0; + haddr_t addr = 1, extra = 0, extra2 = 0, extra3 = 0, extra4 = 0; uint8_t sig[H5F_SIGNATURE_LEN]; size_t u; herr_t status = SUCCEED; @@ -290,6 +305,8 @@ main(int argc, char *argv[]) extra2 = (haddr_t)HDstrtoll(argv[4], NULL, 0); if(argc > 5) extra3 = (haddr_t)HDstrtoll(argv[5], NULL, 0); + if(argc > 6) + extra4 = (haddr_t)HDstrtoll(argv[6], NULL, 0); /* * Read the signature at the specified file position. @@ -376,7 +393,15 @@ main(int argc, char *argv[]) */ const H5B2_class_t *cls = get_H5B2_class(sig); HDassert(cls); - status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls); + + if((cls == H5D_BT2 || cls == H5D_BT2_FILT) && extra == 0) { + fprintf(stderr, "ERROR: Need v2 B-tree header address and object header address containing the layout message in order to dump header\n"); + fprintf(stderr, "v2 B-tree hdr usage:\n"); + fprintf(stderr, "\th5debug <filename> <v2 B-tree header address> <object header address>\n"); + HDexit(4); + } + + status = H5B2_hdr_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, (haddr_t)extra); } else if(!HDmemcmp(sig, H5B2_INT_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* @@ -386,7 +411,16 @@ main(int argc, char *argv[]) HDassert(cls); /* Check for enough valid parameters */ - if(extra == 0 || extra2 == 0 || extra3 == 0) { + if((cls == H5D_BT2 || cls == H5D_BT2_FILT) && + (extra == 0 || extra2 == 0 || extra3 == 0 || extra4 == 0)) { + + fprintf(stderr, "ERROR: Need v2 B-tree header address, the node's number of records, depth, and object header address containing the layout message in order to dump internal node\n"); + fprintf(stderr, "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n"); + fprintf(stderr, "v2 B-tree internal node usage:\n"); + fprintf(stderr, "\th5debug <filename> <internal node address> <v2 B-tree header address> <number of records> <depth> <object header address>\n"); + HDexit(4); + + } else if(extra == 0 || extra2 == 0 || extra3 == 0) { fprintf(stderr, "ERROR: Need v2 B-tree header address and the node's number of records and depth in order to dump internal node\n"); fprintf(stderr, "NOTE: Leaf nodes are depth 0, the internal nodes above them are depth 1, etc.\n"); fprintf(stderr, "v2 B-tree internal node usage:\n"); @@ -394,7 +428,7 @@ main(int argc, char *argv[]) HDexit(4); } /* end if */ - status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (unsigned)extra3); + status = H5B2_int_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (unsigned)extra3, (haddr_t)extra4); } else if(!HDmemcmp(sig, H5B2_LEAF_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* @@ -404,14 +438,22 @@ main(int argc, char *argv[]) HDassert(cls); /* Check for enough valid parameters */ - if(extra == 0 || extra2 == 0) { + if((cls == H5D_BT2 || cls == H5D_BT2_FILT) && + (extra == 0 || extra2 == 0 || extra3 == 0 )) { + + fprintf(stderr, "ERROR: Need v2 B-tree header address, number of records, and object header address containing the layout message in order to dump leaf node\n"); + fprintf(stderr, "v2 B-tree leaf node usage:\n"); + fprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records> <object header address>\n"); + HDexit(4); + + } else if(extra == 0 || extra2 == 0) { fprintf(stderr, "ERROR: Need v2 B-tree header address and number of records in order to dump leaf node\n"); fprintf(stderr, "v2 B-tree leaf node usage:\n"); fprintf(stderr, "\th5debug <filename> <leaf node address> <v2 B-tree header address> <number of records>\n"); HDexit(4); } /* end if */ - status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2); + status = H5B2_leaf_debug(f, H5P_DATASET_XFER_DEFAULT, addr, stdout, 0, VCOL, cls, extra, (unsigned)extra2, (haddr_t)extra3); } else if(!HDmemcmp(sig, H5HF_HDR_MAGIC, (size_t)H5_SIZEOF_MAGIC)) { /* diff --git a/tools/testfiles/tdset_idx.h5 b/tools/testfiles/tdset_idx.h5 Binary files differindex 809aee6..d1d910b 100644 --- a/tools/testfiles/tdset_idx.h5 +++ b/tools/testfiles/tdset_idx.h5 |