summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-11-07 03:13:53 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-11-07 03:13:53 (GMT)
commit08910385629d5cbfde5aa43cef0bcba17f7995b1 (patch)
treec47c355e63c972adac3e025e6bdd4a4dc67c0a47 /src
parent23e994958b6190715aefb698b55dad70deb72049 (diff)
downloadhdf5-08910385629d5cbfde5aa43cef0bcba17f7995b1.zip
hdf5-08910385629d5cbfde5aa43cef0bcba17f7995b1.tar.gz
hdf5-08910385629d5cbfde5aa43cef0bcba17f7995b1.tar.bz2
[svn-r11686] Purpose:
New feature Description: Add in baseline "object copy" code from Peter [in the form of a new API routine: H5Gcopy()]. There's still some work to do (like handling variable- length datatypes and possibly support for references) and it hasn't been tested on mounted files yet, but the core functionality is there and working correctly. I've also got a set of patches to update the 1.6 branch with tweaks to keep the branches mostly in sync, but Elena will kill me if I import them before the 1.6.5 release is out... :-) Platforms tested: FreeBSD 4.11 (sleipnir) h5committested
Diffstat (limited to 'src')
-rw-r--r--src/H5Apkg.h7
-rw-r--r--src/H5B.c444
-rw-r--r--src/H5B2.c31
-rw-r--r--src/H5B2private.h4
-rw-r--r--src/H5BPcache.c4
-rw-r--r--src/H5Bcache.c417
-rw-r--r--src/H5Bpkg.h23
-rw-r--r--src/H5Bprivate.h42
-rw-r--r--src/H5D.c4
-rw-r--r--src/H5Distore.c619
-rw-r--r--src/H5Dpkg.h2
-rw-r--r--src/H5Dpublic.h24
-rw-r--r--src/H5G.c110
-rw-r--r--src/H5Gnode.c136
-rw-r--r--src/H5Gpkg.h18
-rw-r--r--src/H5Gpublic.h6
-rw-r--r--src/H5Gstab.c47
-rw-r--r--src/H5O.c531
-rw-r--r--src/H5Oattr.c101
-rw-r--r--src/H5Obogus.c4
-rw-r--r--src/H5Ocont.c54
-rw-r--r--src/H5Odtype.c4
-rw-r--r--src/H5Oefl.c87
-rw-r--r--src/H5Ofill.c8
-rw-r--r--src/H5Olayout.c127
-rw-r--r--src/H5Omtime.c8
-rw-r--r--src/H5Oname.c4
-rw-r--r--src/H5Onull.c4
-rw-r--r--src/H5Opkg.h9
-rw-r--r--src/H5Opline.c4
-rw-r--r--src/H5Oprivate.h20
-rw-r--r--src/H5Osdspace.c4
-rw-r--r--src/H5Oshared.c63
-rw-r--r--src/H5Ostab.c99
-rw-r--r--src/H5S.c101
-rw-r--r--src/H5Shyper.c18
-rw-r--r--src/H5Spublic.h1
-rw-r--r--src/H5T.c3
-rwxr-xr-xsrc/Makefile.am3
-rw-r--r--src/Makefile.in12
40 files changed, 2354 insertions, 853 deletions
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 976340d..753ad64 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -38,6 +38,7 @@
#include "H5Aprivate.h"
/* Other private headers needed by this file */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5Sprivate.h" /* Dataspace */
#include "H5Tprivate.h" /* Datatype functions */
@@ -54,6 +55,12 @@ struct H5A_t {
size_t data_size; /* Size of data on disk */
};
+/* Declare extern the free list for H5A_t's */
+H5FL_EXTERN(H5A_t);
+
+/* Declare extern a free list to manage blocks of type conversion data */
+H5FL_BLK_EXTERN(attr_buf);
+
/* Function prototypes for H5A package scope */
H5_DLL H5A_t *H5A_copy(H5A_t *new_attr, const H5A_t *old_attr, unsigned update_flags);
H5_DLL herr_t H5A_free(H5A_t *attr);
diff --git a/src/H5B.c b/src/H5B.c
index c5775d8..700ae48 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -14,7 +14,7 @@
/*-------------------------------------------------------------------------
*
- * Created: hdf5btree.c
+ * Created: H5B.c
* Jul 10 1997
* Robb Matzke <matzke@llnl.gov>
*
@@ -89,41 +89,47 @@
* that type of B-tree.
*
*
- * Modifications:
- *
- * Robb Matzke, 4 Aug 1997
- * Added calls to H5E.
- *
*-------------------------------------------------------------------------
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5B_PACKAGE /*suppress error about including H5Bpkg */
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
-/* private headers */
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
#include "H5ACprivate.h" /* Metadata cache */
#include "H5Bpkg.h" /* B-link trees */
#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
-#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
-/* Local macros */
+/****************/
+/* Local Macros */
+/****************/
#define H5B_SIZEOF_HDR(F) \
(H5B_SIZEOF_MAGIC + /*magic number */ \
4 + /*type, level, num entries */ \
2*H5F_SIZEOF_ADDR(F)) /*left and right sibling addresses */
#define H5B_NKEY(b,shared,idx) ((b)->native+(shared)->nkey[(idx)])
-/* Local typedefs */
+/******************/
+/* Local Typedefs */
+/******************/
-/* PRIVATE PROTOTYPES */
+/********************/
+/* Local Prototypes */
+/********************/
static H5B_ins_t H5B_insert_helper(H5F_t *f, hid_t dxpl_id, haddr_t addr,
const H5B_class_t *type,
uint8_t *lt_key,
@@ -139,40 +145,34 @@ static herr_t H5B_split(H5F_t *f, hid_t dxpl_id, H5B_t *old_bt,
unsigned *old_bt_flags, haddr_t old_addr,
unsigned idx, void *udata, haddr_t *new_addr/*out*/);
static H5B_t * H5B_copy(const H5B_t *old_bt);
-static herr_t H5B_serialize(const H5F_t *f, const H5B_t *bt);
#ifdef H5B_DEBUG
static herr_t H5B_assert(H5F_t *f, hid_t dxpl_id, haddr_t addr, const H5B_class_t *type,
void *udata);
#endif
-/* Metadata cache callbacks */
-static H5B_t *H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata);
-static herr_t H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *b);
-static herr_t H5B_dest(H5F_t *f, H5B_t *b);
-static herr_t H5B_clear(H5F_t *f, H5B_t *b, hbool_t destroy);
-static herr_t H5B_compute_size(const H5F_t *f, const H5B_t *bt, size_t *size_ptr);
-
-/* H5B inherits cache-like properties from H5AC */
-static const H5AC_class_t H5AC_BT[1] = {{
- H5AC_BT_ID,
- (H5AC_load_func_t)H5B_load,
- (H5AC_flush_func_t)H5B_flush,
- (H5AC_dest_func_t)H5B_dest,
- (H5AC_clear_func_t)H5B_clear,
- (H5AC_size_func_t)H5B_compute_size,
-}};
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* Declare a free list to manage the haddr_t sequence information */
+H5FL_SEQ_DEFINE(haddr_t);
/* Declare a PQ free list to manage the native block information */
-H5FL_BLK_DEFINE_STATIC(native_block);
+H5FL_BLK_DEFINE(native_block);
-/* Declare a free list to manage the haddr_t sequence information */
-H5FL_SEQ_DEFINE_STATIC(haddr_t);
+/* Declare a free list to manage the H5B_t struct */
+H5FL_DEFINE(H5B_t);
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
/* Declare a free list to manage the H5B_shared_t struct */
H5FL_DEFINE(H5B_shared_t);
-/* Declare a free list to manage the H5B_t struct */
-H5FL_DEFINE_STATIC(H5B_t);
+/*******************/
+/* Local Variables */
+/*******************/
/*-------------------------------------------------------------------------
@@ -263,377 +263,7 @@ done:
}
FUNC_LEAVE_NOAPI(ret_value)
-} /*lint !e818 Can't make udata a pointer to const */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B_load
- *
- * Purpose: Loads a B-tree node from the disk.
- *
- * Return: Success: Pointer to a new B-tree node.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jun 23 1997
- *
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *-------------------------------------------------------------------------
- */
-static H5B_t *
-H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
-{
- const H5B_class_t *type = (const H5B_class_t *) _type;
- H5B_t *bt = NULL;
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- uint8_t *p; /* Pointer into raw data buffer */
- uint8_t *native; /* Pointer to native keys */
- unsigned u; /* Local index variable */
- H5B_t *ret_value;
-
- FUNC_ENTER_NOAPI(H5B_load, NULL)
-
- /* Check arguments */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(type);
- assert(type->get_shared);
-
- if (NULL==(bt = H5FL_MALLOC(H5B_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- HDmemset(&bt->cache_info,0,sizeof(H5AC_info_t));
- if((bt->rc_shared=(type->get_shared)(f, udata))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer")
- shared=H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
- if (NULL==(bt->native=H5FL_BLK_MALLOC(native_block,shared->sizeof_keys)) ||
- NULL==(bt->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)shared->two_k)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- if (H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page)<0)
- HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node")
-
- p = shared->page;
-
- /* magic number */
- if (HDmemcmp(p, H5B_MAGIC, (size_t)H5B_SIZEOF_MAGIC))
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree signature")
- p += 4;
-
- /* node type and level */
- if (*p++ != (uint8_t)type->id)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "incorrect B-tree node type")
- bt->level = *p++;
-
- /* entries used */
- UINT16DECODE(p, bt->nchildren);
-
- /* sibling pointers */
- H5F_addr_decode(f, (const uint8_t **) &p, &(bt->left));
- H5F_addr_decode(f, (const uint8_t **) &p, &(bt->right));
-
- /* the child/key pairs */
- native=bt->native;
- for (u = 0; u < bt->nchildren; u++) {
- /* Decode native key value */
- if ((type->decode) (f, bt, p, native) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key")
- p += shared->sizeof_rkey;
- native += type->sizeof_nkey;
-
- /* Decode address value */
- H5F_addr_decode(f, (const uint8_t **) &p, bt->child + u);
- }
-
- /* Decode final key */
- if(bt->nchildren>0) {
- /* Decode native key value */
- if ((type->decode) (f, bt, p, native) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key")
- } /* end if */
-
- /* Set return value */
- ret_value = bt;
-
-done:
- if (!ret_value && bt)
- (void)H5B_dest(f,bt);
- FUNC_LEAVE_NOAPI(ret_value)
-} /*lint !e818 Can't make udata a pointer to const */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B_serialize
- *
- * Purpose: Serialize the data structure for writing to disk or
- * storing on the SAP (for FPHDF5).
- *
- * Return: Success: SUCCEED
- * Failure: FAIL
- *
- * Programmer: Bill Wendling
- * wendling@ncsa.uiuc.edu
- * Sept. 15, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5B_serialize(const H5F_t *f, const H5B_t *bt)
-{
- H5B_shared_t *shared=NULL; /* Pointer to shared B-tree info */
- unsigned u;
- uint8_t *p; /* Pointer into raw data buffer */
- uint8_t *native; /* Pointer to native keys */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5B_serialize, FAIL)
-
- /* check arguments */
- assert(f);
- assert(bt);
- assert(bt->rc_shared);
- shared=H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
-
- p = shared->page;
-
- /* magic number */
- HDmemcpy(p, H5B_MAGIC, (size_t)H5B_SIZEOF_MAGIC);
- p += 4;
-
- /* node type and level */
- *p++ = (uint8_t)shared->type->id;
- H5_CHECK_OVERFLOW(bt->level, unsigned, uint8_t);
- *p++ = (uint8_t)bt->level;
-
- /* entries used */
- UINT16ENCODE(p, bt->nchildren);
-
- /* sibling pointers */
- H5F_addr_encode(f, &p, bt->left);
- H5F_addr_encode(f, &p, bt->right);
-
- /* child keys and pointers */
- native=bt->native;
- for (u = 0; u < bt->nchildren; ++u) {
- /* encode the key */
- if (shared->type->encode(f, bt, p, native) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
- p += shared->sizeof_rkey;
- native += shared->type->sizeof_nkey;
-
- /* encode the child address */
- H5F_addr_encode(f, &p, bt->child[u]);
- } /* end for */
- if(bt->nchildren>0) {
- /* Encode the final key */
- if (shared->type->encode(f, bt, p, native) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B_flush
- *
- * Purpose: Flushes a dirty B-tree node to disk.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jun 23 1997
- *
- * Modifications:
- * rky 980828
- * Only p0 writes metadata to disk.
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *
- * Bill Wendling, 2003-09-15
- * Separated out the bit of code that serializes the B-Tree
- * structure.
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt)
-{
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5B_flush, FAIL)
-
- /* check arguments */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(bt);
- shared=H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
- assert(shared->type);
- assert(shared->type->encode);
-
- if (bt->cache_info.is_dirty) {
- if (H5B_serialize(f, bt) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTSERIALIZE, FAIL, "unable to serialize B-tree")
-
- /*
- * Write the disk page. We always write the header, but we don't
- * bother writing data for the child entries that don't exist or
- * for the final unchanged children.
- */
- if (H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree node to disk")
-
- bt->cache_info.is_dirty = FALSE;
- } /* end if */
-
- if (destroy)
- if (H5B_dest(f,bt) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree node")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B_dest
- *
- * Purpose: Destroys a B-tree node in memory.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jan 15 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static herr_t
-H5B_dest(H5F_t UNUSED *f, H5B_t *bt)
-{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_dest)
-
- /*
- * Check arguments.
- */
- assert(bt);
- assert(bt->rc_shared);
-
- H5FL_SEQ_FREE(haddr_t,bt->child);
- H5FL_BLK_FREE(native_block,bt->native);
- H5RC_DEC(bt->rc_shared);
- H5FL_FREE(H5B_t,bt);
-
- FUNC_LEAVE_NOAPI(SUCCEED)
-} /* end H5B_dest() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B_clear
- *
- * Purpose: Mark a B-tree node in memory as non-dirty.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 20 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5B_clear(H5F_t *f, H5B_t *bt, hbool_t destroy)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5B_clear)
-
- /*
- * Check arguments.
- */
- assert(bt);
-
- /* Reset the dirty flag. */
- bt->cache_info.is_dirty = FALSE;
-
- if (destroy)
- if (H5B_dest(f, bt) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree node")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5B_clear() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5B_compute_size
- *
- * Purpose: Compute the size in bytes of the specified instance of
- * H5B_t on disk, and return it in *len_ptr. On failure,
- * the value of *len_ptr is undefined.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: John Mainzer
- * 5/13/04
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5B_compute_size(const H5F_t *f, const H5B_t *bt, size_t *size_ptr)
-{
- H5B_shared_t *shared; /* Pointer to shared B-tree info */
- size_t size;
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5B_compute_size)
-
- /* check arguments */
- HDassert(f);
- HDassert(bt);
- HDassert(bt->rc_shared);
- shared=H5RC_GET_OBJ(bt->rc_shared);
- HDassert(shared);
- HDassert(shared->type);
- HDassert(size_ptr);
-
- /* Check node's size */
- if ((size = H5B_nodesize(f, shared, NULL)) == 0)
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, "H5B_nodesize() failed")
-
- /* Set size value */
- *size_ptr = size;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5B_H5B_compute_size() */
+} /* end H5B_create() */ /*lint !e818 Can't make udata a pointer to const */
/*-------------------------------------------------------------------------
@@ -749,7 +379,7 @@ done:
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release node")
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5B_find() */
/*-------------------------------------------------------------------------
@@ -934,7 +564,7 @@ done:
HDONE_ERROR(H5E_BTREE, H5E_PROTECT, FAIL, "unable to release B-tree node")
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5B_split() */
/*-------------------------------------------------------------------------
@@ -1106,7 +736,7 @@ H5B_insert(H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, haddr_t addr,
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5B_insert() */
/*-------------------------------------------------------------------------
diff --git a/src/H5B2.c b/src/H5B2.c
index b7cbb5d..194cdb6 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -28,15 +28,23 @@
*-------------------------------------------------------------------------
*/
+/****************/
+/* Module Setup */
+/****************/
+
#define H5B2_PACKAGE /*suppress error about including H5B2pkg */
-/* Private headers */
+/***********/
+/* Headers */
+/***********/
#include "H5private.h" /* Generic Functions */
#include "H5B2pkg.h" /* v2 B-trees */
#include "H5Eprivate.h" /* Error handling */
#include "H5MFprivate.h" /* File memory management */
-/* Local macros */
+/****************/
+/* Local Macros */
+/****************/
/* Format overhead for each node (on disk) */
#define H5B2_OVERHEAD_SIZE (H5B2_SIZEOF_MAGIC+1) /* Signature + version # */
@@ -51,9 +59,13 @@
/* #define H5B2_DEBUG */
-/* Local typedefs */
+/******************/
+/* Local Typedefs */
+/******************/
-/* Local prototypes */
+/********************/
+/* Local Prototypes */
+/********************/
/* Helper functions */
static herr_t H5B2_create_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
@@ -113,7 +125,9 @@ static herr_t H5B2_assert_internal2(hsize_t parent_all_nrec, H5B2_shared_t *shar
#endif /* H5B2_DEBUG */
-/* Package variables */
+/*********************/
+/* Package Variables */
+/*********************/
/* Declare a free list to manage the H5B2_t struct */
H5FL_DEFINE(H5B2_t);
@@ -124,8 +138,13 @@ H5FL_DEFINE(H5B2_internal_t);
/* Declare a free list to manage the H5B2_leaf_t struct */
H5FL_DEFINE(H5B2_leaf_t);
+/*****************************/
+/* Library Private Variables */
+/*****************************/
-/* Static variables */
+/*******************/
+/* Local Variables */
+/*******************/
/* Declare a free list to manage B-tree node pages to/from disk */
H5FL_BLK_DEFINE_STATIC(node_page);
diff --git a/src/H5B2private.h b/src/H5B2private.h
index 3be4413..850eb50 100644
--- a/src/H5B2private.h
+++ b/src/H5B2private.h
@@ -96,6 +96,10 @@ typedef struct H5B2_class_t {
} H5B2_class_t;
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
/***************************************/
/* Library-private Function Prototypes */
/***************************************/
diff --git a/src/H5BPcache.c b/src/H5BPcache.c
index 57e1677..4580c38 100644
--- a/src/H5BPcache.c
+++ b/src/H5BPcache.c
@@ -551,7 +551,7 @@ H5BP_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5
/* Encode the record */
if((shared->type->encode)(f, leaf->rec_ptr[u], p, &rec_len) < 0)
- HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, NULL, "can't encode B+ tree record")
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "can't encode B+ tree record")
assert(rec_len > 0);
p += rec_len;
@@ -561,7 +561,7 @@ H5BP_cache_leaf_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5
} /* end if */
else {
HDfprintf(stderr,"%s: attempting to decode fixed-size records from leaf node\n",FUNC);
-HGOTO_ERROR(H5E_BTREE, H5E_UNSUPPORTED, NULL, "Can't decode records yet!")
+HGOTO_ERROR(H5E_BTREE, H5E_UNSUPPORTED, FAIL, "Can't decode records yet!")
} /* end else */
#ifdef LATER
diff --git a/src/H5Bcache.c b/src/H5Bcache.c
new file mode 100644
index 0000000..443b482
--- /dev/null
+++ b/src/H5Bcache.c
@@ -0,0 +1,417 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Bcache.c
+ * Oct 31 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Implement B-tree metadata cache methods.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5B_PACKAGE /*suppress error about including H5Bpkg */
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Bpkg.h" /* B-link trees */
+#include "H5Eprivate.h" /* Error handling */
+
+/****************/
+/* Local Macros */
+/****************/
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+/* General routines */
+static herr_t H5B_serialize(const H5F_t *f, const H5B_t *bt);
+
+/* Metadata cache callbacks */
+static H5B_t *H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata);
+static herr_t H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *b);
+static herr_t H5B_clear(H5F_t *f, H5B_t *b, hbool_t destroy);
+static herr_t H5B_compute_size(const H5F_t *f, const H5B_t *bt, size_t *size_ptr);
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+/* H5B inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_BT[1] = {{
+ H5AC_BT_ID,
+ (H5AC_load_func_t)H5B_load,
+ (H5AC_flush_func_t)H5B_flush,
+ (H5AC_dest_func_t)H5B_dest,
+ (H5AC_clear_func_t)H5B_clear,
+ (H5AC_size_func_t)H5B_compute_size,
+}};
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_serialize
+ *
+ * Purpose: Serialize the data structure for writing to disk or
+ * storing on the SAP (for FPHDF5).
+ *
+ * Return: Success: SUCCEED
+ * Failure: FAIL
+ *
+ * Programmer: Bill Wendling
+ * wendling@ncsa.uiuc.edu
+ * Sept. 15, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B_serialize(const H5F_t *f, const H5B_t *bt)
+{
+ H5B_shared_t *shared=NULL; /* Pointer to shared B-tree info */
+ unsigned u;
+ uint8_t *p; /* Pointer into raw data buffer */
+ uint8_t *native; /* Pointer to native keys */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B_serialize, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(bt);
+ HDassert(bt->rc_shared);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+
+ p = shared->page;
+
+ /* magic number */
+ HDmemcpy(p, H5B_MAGIC, (size_t)H5B_SIZEOF_MAGIC);
+ p += 4;
+
+ /* node type and level */
+ *p++ = (uint8_t)shared->type->id;
+ H5_CHECK_OVERFLOW(bt->level, unsigned, uint8_t);
+ *p++ = (uint8_t)bt->level;
+
+ /* entries used */
+ UINT16ENCODE(p, bt->nchildren);
+
+ /* sibling pointers */
+ H5F_addr_encode(f, &p, bt->left);
+ H5F_addr_encode(f, &p, bt->right);
+
+ /* child keys and pointers */
+ native=bt->native;
+ for (u = 0; u < bt->nchildren; ++u) {
+ /* encode the key */
+ if (shared->type->encode(f, bt, p, native) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
+ p += shared->sizeof_rkey;
+ native += shared->type->sizeof_nkey;
+
+ /* encode the child address */
+ H5F_addr_encode(f, &p, bt->child[u]);
+ } /* end for */
+ if(bt->nchildren>0) {
+ /* Encode the final key */
+ if (shared->type->encode(f, bt, p, native) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTENCODE, FAIL, "unable to encode B-tree key")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B_serialize() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_load
+ *
+ * Purpose: Loads a B-tree node from the disk.
+ *
+ * Return: Success: Pointer to a new B-tree node.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jun 23 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5B_t *
+H5B_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_type, void *udata)
+{
+ const H5B_class_t *type = (const H5B_class_t *) _type;
+ H5B_t *bt = NULL;
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ uint8_t *p; /* Pointer into raw data buffer */
+ uint8_t *native; /* Pointer to native keys */
+ unsigned u; /* Local index variable */
+ H5B_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5B_load, NULL)
+
+ /* Check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(type);
+ HDassert(type->get_shared);
+
+ if (NULL==(bt = H5FL_MALLOC(H5B_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemset(&bt->cache_info,0,sizeof(H5AC_info_t));
+ if((bt->rc_shared=(type->get_shared)(f, udata))==NULL)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "can't retrieve B-tree node buffer")
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ if (NULL==(bt->native=H5FL_BLK_MALLOC(native_block,shared->sizeof_keys)) ||
+ NULL==(bt->child=H5FL_SEQ_MALLOC(haddr_t,(size_t)shared->two_k)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ if (H5F_block_read(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page)<0)
+ HGOTO_ERROR(H5E_BTREE, H5E_READERROR, NULL, "can't read B-tree node")
+
+ p = shared->page;
+
+ /* magic number */
+ if (HDmemcmp(p, H5B_MAGIC, (size_t)H5B_SIZEOF_MAGIC))
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "wrong B-tree signature")
+ p += 4;
+
+ /* node type and level */
+ if (*p++ != (uint8_t)type->id)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTLOAD, NULL, "incorrect B-tree node type")
+ bt->level = *p++;
+
+ /* entries used */
+ UINT16DECODE(p, bt->nchildren);
+
+ /* sibling pointers */
+ H5F_addr_decode(f, (const uint8_t **) &p, &(bt->left));
+ H5F_addr_decode(f, (const uint8_t **) &p, &(bt->right));
+
+ /* the child/key pairs */
+ native=bt->native;
+ for (u = 0; u < bt->nchildren; u++) {
+ /* Decode native key value */
+ if ((type->decode) (f, bt, p, native) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key")
+ p += shared->sizeof_rkey;
+ native += type->sizeof_nkey;
+
+ /* Decode address value */
+ H5F_addr_decode(f, (const uint8_t **) &p, bt->child + u);
+ }
+
+ /* Decode final key */
+ if(bt->nchildren>0) {
+ /* Decode native key value */
+ if ((type->decode) (f, bt, p, native) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTDECODE, NULL, "unable to decode key")
+ } /* end if */
+
+ /* Set return value */
+ ret_value = bt;
+
+done:
+ if (!ret_value && bt)
+ (void)H5B_dest(f,bt);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B_load() */ /*lint !e818 Can't make udata a pointer to const */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_flush
+ *
+ * Purpose: Flushes a dirty B-tree node to disk.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Jun 23 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5B_t *bt)
+{
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5B_flush, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(bt);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ HDassert(shared->type);
+ HDassert(shared->type->encode);
+
+ if (bt->cache_info.is_dirty) {
+ if (H5B_serialize(f, bt) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTSERIALIZE, FAIL, "unable to serialize B-tree")
+
+ /*
+ * Write the disk page. We always write the header, but we don't
+ * bother writing data for the child entries that don't exist or
+ * for the final unchanged children.
+ */
+ if (H5F_block_write(f, H5FD_MEM_BTREE, addr, shared->sizeof_rnode, dxpl_id, shared->page) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFLUSH, FAIL, "unable to save B-tree node to disk")
+
+ bt->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if (destroy)
+ if (H5B_dest(f,bt) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_dest
+ *
+ * Purpose: Destroys a B-tree node in memory.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 15 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+/* ARGSUSED */
+herr_t
+H5B_dest(H5F_t UNUSED *f, H5B_t *bt)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5B_dest)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(bt);
+ HDassert(bt->rc_shared);
+
+ H5FL_SEQ_FREE(haddr_t,bt->child);
+ H5FL_BLK_FREE(native_block,bt->native);
+ H5RC_DEC(bt->rc_shared);
+ H5FL_FREE(H5B_t,bt);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5B_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_clear
+ *
+ * Purpose: Mark a B-tree node in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 20 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B_clear(H5F_t *f, H5B_t *bt, hbool_t destroy)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B_clear)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(bt);
+
+ /* Reset the dirty flag. */
+ bt->cache_info.is_dirty = FALSE;
+
+ if (destroy)
+ if (H5B_dest(f, bt) < 0)
+ HGOTO_ERROR(H5E_BTREE, H5E_CANTFREE, FAIL, "unable to destroy B-tree node")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5B_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_compute_size
+ *
+ * Purpose: Compute the size in bytes of the specified instance of
+ * H5B_t on disk, and return it in *len_ptr. On failure,
+ * the value of *len_ptr is undefined.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 5/13/04
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5B_compute_size(const H5F_t *f, const H5B_t *bt, size_t *size_ptr)
+{
+ H5B_shared_t *shared; /* Pointer to shared B-tree info */
+ size_t size;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5B_compute_size)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(bt);
+ HDassert(bt->rc_shared);
+ shared=H5RC_GET_OBJ(bt->rc_shared);
+ HDassert(shared);
+ HDassert(shared->type);
+ HDassert(size_ptr);
+
+ /* Check node's size */
+ if ((size = H5B_nodesize(f, shared, NULL)) == 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTGETSIZE, FAIL, "H5B_nodesize() failed")
+
+ /* Set size value */
+ *size_ptr = size;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5B_compute_size() */
diff --git a/src/H5Bpkg.h b/src/H5Bpkg.h
index 74fa393..e96161d 100644
--- a/src/H5Bpkg.h
+++ b/src/H5Bpkg.h
@@ -31,7 +31,7 @@
#include "H5Bprivate.h"
/* Other private headers needed by this file */
-#include "H5RCprivate.h" /* Reference counted object functions */
+#include "H5RCprivate.h" /* Reference counted objects */
/**************************/
/* Package Private Macros */
@@ -41,9 +41,7 @@
/* Package Private Typedefs */
/****************************/
-/*
- * The B-tree node as stored in memory...
- */
+/* The B-tree node as stored in memory... */
struct H5B_t {
H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */
/* first field in structure */
@@ -56,8 +54,25 @@ struct H5B_t {
haddr_t *child; /*2k child pointers */
};
+/*****************************/
+/* Package Private Variables */
+/*****************************/
+
+/* H5B header inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_BT[1];
+
+/* Declare a free list to manage the haddr_t sequence information */
+H5FL_SEQ_EXTERN(haddr_t);
+
+/* Declare a PQ free list to manage the native block information */
+H5FL_BLK_EXTERN(native_block);
+
+/* Declare a free list to manage the H5B_t struct */
+H5FL_EXTERN(H5B_t);
+
/******************************/
/* Package Private Prototypes */
/******************************/
+herr_t H5B_dest(H5F_t *f, H5B_t *b);
#endif /*_H5Bpkg_H*/
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 28494f7..246d0c5 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -34,8 +34,13 @@
#include "H5private.h" /* Generic Functions */
#include "H5ACprivate.h" /* Metadata cache */
#include "H5Fprivate.h" /* File access */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5RCprivate.h" /* Reference counted object functions */
+/**************************/
+/* Library Private Macros */
+/**************************/
+
/*
* Feature: Define this constant if you want to check B-tree consistency
* after each B-tree operation. Note that this slows down the
@@ -48,6 +53,19 @@
#define H5B_MAGIC "TREE" /*tree node magic number */
#define H5B_SIZEOF_MAGIC 4 /*size of magic number */
+/* Define return values from operator callback function for H5B_iterate */
+/* (Actually, any postive value will cause the iterator to stop and pass back
+ * that positive value to the function that called the iterator)
+ */
+#define H5B_ITER_ERROR (-1)
+#define H5B_ITER_CONT (0)
+#define H5B_ITER_STOP (1)
+
+/****************************/
+/* Library Private Typedefs */
+/****************************/
+
+/* Define return values from B-tree insertion callbacks */
typedef enum H5B_ins_t {
H5B_INS_ERROR = -1, /*error return value */
H5B_INS_NOOP = 0, /*insert made no changes */
@@ -58,14 +76,6 @@ typedef enum H5B_ins_t {
H5B_INS_REMOVE = 5 /*remove current node */
} H5B_ins_t;
-/* Define return values from operator callback function for H5B_iterate */
-/* (Actually, any postive value will cause the iterator to stop and pass back
- * that positive value to the function that called the iterator)
- */
-#define H5B_ITER_ERROR (-1)
-#define H5B_ITER_CONT (0)
-#define H5B_ITER_STOP (1)
-
/* Define the operator callback function pointer for H5B_iterate() */
typedef int (*H5B_operator_t)(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
const void *_rt_key, void *_udata);
@@ -97,7 +107,6 @@ typedef struct H5B_shared_t {
typedef struct H5B_class_t {
H5B_subid_t id; /*id as found in file*/
size_t sizeof_nkey; /*size of native (memory) key*/
- size_t (*get_sizeof_rkey)(const H5F_t*, const void*); /*raw key size */
H5RC_t * (*get_shared)(const H5F_t*, const void*); /*shared info for node */
herr_t (*new_node)(H5F_t*, hid_t, H5B_ins_t, void*, void*, void*, haddr_t*);
int (*cmp2)(H5F_t*, hid_t, void*, void*, void*); /*compare 2 keys */
@@ -120,12 +129,19 @@ typedef struct H5B_class_t {
herr_t (*decode)(const H5F_t*, const struct H5B_t*, const uint8_t*, void*);
herr_t (*encode)(const H5F_t*, const struct H5B_t*, uint8_t*, void*);
herr_t (*debug_key)(FILE*, H5F_t*, hid_t, int, int, const void*, const void*);
-
} H5B_class_t;
-/*
- * Library prototypes.
- */
+/*****************************/
+/* Library-private Variables */
+/*****************************/
+
+/* Declare a free list to manage the H5B_shared_t struct */
+H5FL_EXTERN(H5B_shared_t);
+
+
+/***************************************/
+/* Library-private Function Prototypes */
+/***************************************/
H5_DLL size_t H5B_nodesize(const H5F_t *f, const H5B_shared_t *shared,
size_t *total_nkey_size);
H5_DLL herr_t H5B_create (H5F_t *f, hid_t dxpl_id, const H5B_class_t *type, void *udata,
diff --git a/src/H5D.c b/src/H5D.c
index 8f73149..156b70d 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -87,6 +87,10 @@ static herr_t H5D_xfer_xform_close(const char* name, size_t size, void* value);
/* Define a "default" dataset transfer property list cache structure to use for default DXPLs */
H5D_dxpl_cache_t H5D_def_dxpl_cache;
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
/*******************/
/* Local Variables */
/*******************/
diff --git a/src/H5Distore.c b/src/H5Distore.c
index bf0c92e..b0d60d6 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -144,14 +144,57 @@ typedef struct H5D_istore_key_t {
unsigned filter_mask; /*excluded filters */
} H5D_istore_key_t;
-typedef struct H5D_istore_ud1_t {
+/*
+ * Common data exchange structure for indexed storage nodes. This structure is
+ * passed through the B-link tree layer to the methods for the objects
+ * to which the B-link tree points.
+ */
+typedef struct H5D_istore_bt_ud_common_t {
+ /* downward */
H5D_istore_key_t key; /*key values */
- haddr_t addr; /*file address of chunk */
const H5O_layout_t *mesg; /*layout message */
+} H5D_istore_bt_ud_common_t;
+
+/*
+ * Data exchange structure for indexed storage nodes. This structure is
+ * passed through the B-link tree layer to the methods for the objects
+ * to which the B-link tree points for operations which require no
+ * additional information.
+ *
+ * (Just an alias for the "common" info).
+ */
+typedef H5D_istore_bt_ud_common_t H5D_istore_ud0_t;
+
+typedef struct H5D_istore_ud1_t {
+ H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
+ haddr_t addr; /*file address of chunk */
+} H5D_istore_ud1_t;
+
+/* B-tree callback info for iteration to total allocated space */
+typedef struct H5D_istore_it_ud1_t {
+ H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
hsize_t total_storage; /*output from iterator */
+} H5D_istore_it_ud1_t;
+
+/* B-tree callback info for iteration to dump node's info */
+typedef struct H5D_istore_it_ud2_t {
+ H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
FILE *stream; /*debug output stream */
+ hbool_t header_displayed; /* Node's header is displayed? */
+} H5D_istore_it_ud2_t;
+
+/* B-tree callback info for iteration to prune chunks */
+typedef struct H5D_istore_it_ud3_t {
+ H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
hsize_t *dims; /*dataset dimensions */
-} H5D_istore_ud1_t;
+} H5D_istore_it_ud3_t;
+
+/* B-tree callback info for iteration to copy data */
+typedef struct H5D_istore_it_ud4_t {
+ H5D_istore_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
+ H5F_t *file_dst; /* Destination file for copy */
+ haddr_t addr_dst; /* Address of dest. B-tree */
+} H5D_istore_it_ud4_t;
/********************/
/* Local Prototypes */
@@ -169,9 +212,10 @@ static int H5D_istore_iter_dump(H5F_t *f, hid_t dxpl_id, const void *left_key, h
const void *right_key, void *_udata);
static int H5D_istore_prune_extent(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
const void *_rt_key, void *_udata);
+static int H5D_istore_iter_copy(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
+ const void *_rt_key, void *_udata);
/* B-tree callbacks */
-static size_t H5D_istore_sizeof_rkey(const H5F_t *f, const void *_udata);
static H5RC_t *H5D_istore_get_shared(const H5F_t *f, const void *_udata);
static herr_t H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t, void *_lt_key,
void *_udata, void *_rt_key,
@@ -202,7 +246,6 @@ static herr_t H5D_istore_debug_key(FILE *stream, H5F_t *f, hid_t dxpl_id,
H5B_class_t H5B_ISTORE[1] = {{
H5B_ISTORE_ID, /*id */
sizeof(H5D_istore_key_t), /*sizeof_nkey */
- H5D_istore_sizeof_rkey, /*get_sizeof_rkey */
H5D_istore_get_shared, /*get_shared */
H5D_istore_new_node, /*new */
H5D_istore_cmp2, /*cmp2 */
@@ -221,13 +264,14 @@ H5B_class_t H5B_ISTORE[1] = {{
/* Package Variables */
/*********************/
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
/*******************/
/* Local Variables */
/*******************/
-/* Declare a free list to manage the H5B_shared_t struct */
-H5FL_EXTERN(H5B_shared_t);
-
/* Declare a free list to manage H5F_rdcc_ent_t objects */
H5FL_DEFINE_STATIC(H5D_rdcc_ent_t);
@@ -245,43 +289,6 @@ H5FL_BLK_DEFINE_STATIC(chunk_page);
/*-------------------------------------------------------------------------
- * Function: H5D_istore_sizeof_rkey
- *
- * Purpose: Returns the size of a raw key for the specified UDATA. The
- * size of the key is dependent on the number of dimensions for
- * the object to which this B-tree points. The dimensionality
- * of the UDATA is the only portion that's referenced here.
- *
- * Return: Success: Size of raw key in bytes.
- *
- * Failure: abort()
- *
- * Programmer: Robb Matzke
- * Wednesday, October 8, 1997
- *
- *-------------------------------------------------------------------------
- */
-/* ARGSUSED */
-static size_t
-H5D_istore_sizeof_rkey(const H5F_t UNUSED *f, const void *_udata)
-{
- const H5D_istore_ud1_t *udata = (const H5D_istore_ud1_t *) _udata;
- size_t nbytes;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_sizeof_rkey)
-
- assert(udata);
- assert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
-
- nbytes = 4 + /*storage size */
- 4 + /*filter mask */
- udata->mesg->u.chunk.ndims*8; /*dimension indices */
-
- FUNC_LEAVE_NOAPI(nbytes)
-} /* end H5D_istore_sizeof_rkey() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5D_istore_get_shared
*
* Purpose: Returns the shared B-tree info for the specified UDATA.
@@ -299,13 +306,13 @@ H5D_istore_sizeof_rkey(const H5F_t UNUSED *f, const void *_udata)
static H5RC_t *
H5D_istore_get_shared(const H5F_t UNUSED *f, const void *_udata)
{
- const H5D_istore_ud1_t *udata = (const H5D_istore_ud1_t *) _udata;
+ const H5D_istore_ud0_t *udata = (const H5D_istore_ud0_t *) _udata;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_get_shared)
- assert(udata);
- assert(udata->mesg);
- assert(udata->mesg->u.chunk.btree_shared);
+ HDassert(udata);
+ HDassert(udata->mesg);
+ HDassert(udata->mesg->u.chunk.btree_shared);
/* Increment reference count on B-tree info */
H5RC_INC(udata->mesg->u.chunk.btree_shared);
@@ -413,26 +420,23 @@ H5D_istore_encode_key(const H5F_t UNUSED *f, const H5B_t *bt, uint8_t *raw, void
*/
/* ARGSUSED */
static herr_t
-H5D_istore_debug_key (FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, int indent, int fwidth,
+H5D_istore_debug_key(FILE *stream, H5F_t UNUSED *f, hid_t UNUSED dxpl_id, int indent, int fwidth,
const void *_key, const void *_udata)
{
const H5D_istore_key_t *key = (const H5D_istore_key_t *)_key;
- const H5D_istore_ud1_t *udata = (const H5D_istore_ud1_t *)_udata;
+ const H5D_istore_ud0_t *udata = (const H5D_istore_ud0_t *)_udata;
unsigned u;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_debug_key)
- assert (key);
+ HDassert(key);
- HDfprintf(stream, "%*s%-*s %Zd bytes\n", indent, "", fwidth,
- "Chunk size:", key->nbytes);
- HDfprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth,
- "Filter mask:", key->filter_mask);
- HDfprintf(stream, "%*s%-*s {", indent, "", fwidth,
- "Logical offset:");
- for (u=0; u<udata->mesg->u.chunk.ndims; u++)
- HDfprintf (stream, "%s%Hd", u?", ":"", key->offset[u]);
- HDfputs ("}\n", stream);
+ HDfprintf(stream, "%*s%-*s %Zd bytes\n", indent, "", fwidth, "Chunk size:", key->nbytes);
+ HDfprintf(stream, "%*s%-*s 0x%08x\n", indent, "", fwidth, "Filter mask:", key->filter_mask);
+ HDfprintf(stream, "%*s%-*s {", indent, "", fwidth, "Logical offset:");
+ for(u = 0; u < udata->mesg->u.chunk.ndims; u++)
+ HDfprintf(stream, "%s%Hd", u?", ":"", key->offset[u]);
+ HDfputs("}\n", stream);
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5D_istore_debug_key() */
@@ -464,15 +468,15 @@ H5D_istore_cmp2(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_uda
{
H5D_istore_key_t *lt_key = (H5D_istore_key_t *) _lt_key;
H5D_istore_key_t *rt_key = (H5D_istore_key_t *) _rt_key;
- H5D_istore_ud1_t *udata = (H5D_istore_ud1_t *) _udata;
+ H5D_istore_ud0_t *udata = (H5D_istore_ud0_t *) _udata;
int ret_value;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_cmp2)
- assert(lt_key);
- assert(rt_key);
- assert(udata);
- assert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(lt_key);
+ HDassert(rt_key);
+ HDassert(udata);
+ HDassert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
/* Compare the offsets but ignore the other fields */
ret_value = H5V_vector_cmp_u(udata->mesg->u.chunk.ndims, lt_key->offset, rt_key->offset);
@@ -515,15 +519,15 @@ H5D_istore_cmp3(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, void *_lt_key, void *_uda
{
H5D_istore_key_t *lt_key = (H5D_istore_key_t *) _lt_key;
H5D_istore_key_t *rt_key = (H5D_istore_key_t *) _rt_key;
- H5D_istore_ud1_t *udata = (H5D_istore_ud1_t *) _udata;
+ H5D_istore_ud0_t *udata = (H5D_istore_ud0_t *) _udata;
int ret_value = 0;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_cmp3)
- assert(lt_key);
- assert(rt_key);
- assert(udata);
- assert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(lt_key);
+ HDassert(rt_key);
+ HDassert(udata);
+ HDassert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
/* Special case for faster checks on 1-D chunks */
/* (Checking for ndims==2 because last dimension is the datatype size) */
@@ -580,22 +584,22 @@ H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
H5D_istore_key_t *rt_key = (H5D_istore_key_t *) _rt_key;
H5D_istore_ud1_t *udata = (H5D_istore_ud1_t *) _udata;
unsigned u;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_new_node)
/* check args */
- assert(f);
- assert(lt_key);
- assert(rt_key);
- assert(udata);
- assert(udata->mesg->u.chunk.ndims > 0 && udata->mesg->u.chunk.ndims < H5O_LAYOUT_NDIMS);
- assert(addr_p);
+ HDassert(f);
+ HDassert(lt_key);
+ HDassert(rt_key);
+ HDassert(udata);
+ HDassert(udata->common.mesg->u.chunk.ndims > 0 && udata->common.mesg->u.chunk.ndims < H5O_LAYOUT_NDIMS);
+ HDassert(addr_p);
/* Allocate new storage */
- assert (udata->key.nbytes > 0);
- H5_CHECK_OVERFLOW( udata->key.nbytes ,size_t, hsize_t);
- if (HADDR_UNDEF==(*addr_p=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->key.nbytes)))
+ HDassert(udata->common.key.nbytes > 0);
+ H5_CHECK_OVERFLOW(udata->common.key.nbytes ,size_t, hsize_t);
+ if(HADDR_UNDEF == (*addr_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->common.key.nbytes)))
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "couldn't allocate new file storage")
udata->addr = *addr_p;
@@ -603,10 +607,10 @@ H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
* The left key describes the storage of the UDATA chunk being
* inserted into the tree.
*/
- lt_key->nbytes = udata->key.nbytes;
- lt_key->filter_mask = udata->key.filter_mask;
- for (u=0; u<udata->mesg->u.chunk.ndims; u++)
- lt_key->offset[u] = udata->key.offset[u];
+ lt_key->nbytes = udata->common.key.nbytes;
+ lt_key->filter_mask = udata->common.key.filter_mask;
+ for (u=0; u<udata->common.mesg->u.chunk.ndims; u++)
+ lt_key->offset[u] = udata->common.key.offset[u];
/*
* The right key might already be present. If not, then add a zero-width
@@ -615,10 +619,10 @@ H5D_istore_new_node(H5F_t *f, hid_t dxpl_id, H5B_ins_t op,
if (H5B_INS_LEFT != op) {
rt_key->nbytes = 0;
rt_key->filter_mask = 0;
- for (u=0; u<udata->mesg->u.chunk.ndims; u++) {
- assert (udata->key.offset[u]+udata->mesg->u.chunk.dim[u] >
- udata->key.offset[u]);
- rt_key->offset[u] = udata->key.offset[u] + udata->mesg->u.chunk.dim[u];
+ for (u=0; u<udata->common.mesg->u.chunk.ndims; u++) {
+ HDassert(udata->common.key.offset[u]+udata->common.mesg->u.chunk.dim[u] >
+ udata->common.key.offset[u]);
+ rt_key->offset[u] = udata->common.key.offset[u] + udata->common.mesg->u.chunk.dim[u];
}
}
@@ -659,28 +663,28 @@ H5D_istore_found(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, haddr_t addr, const void
H5D_istore_ud1_t *udata = (H5D_istore_ud1_t *) _udata;
const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *) _lt_key;
unsigned u;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_found)
/* Check arguments */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(udata);
- assert(lt_key);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(udata);
+ HDassert(lt_key);
/* Is this *really* the requested chunk? */
- for (u=0; u<udata->mesg->u.chunk.ndims; u++)
- if (udata->key.offset[u] >= lt_key->offset[u]+udata->mesg->u.chunk.dim[u])
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ if(udata->common.key.offset[u] >= lt_key->offset[u] + udata->common.mesg->u.chunk.dim[u])
HGOTO_DONE(FAIL)
/* Initialize return values */
udata->addr = addr;
- udata->key.nbytes = lt_key->nbytes;
- udata->key.filter_mask = lt_key->filter_mask;
- assert (lt_key->nbytes>0);
- for (u = 0; u < udata->mesg->u.chunk.ndims; u++)
- udata->key.offset[u] = lt_key->offset[u];
+ udata->common.key.nbytes = lt_key->nbytes;
+ udata->common.key.filter_mask = lt_key->filter_mask;
+ HDassert(lt_key->nbytes>0);
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ udata->common.key.offset[u] = lt_key->offset[u];
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -734,30 +738,30 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_insert)
/* check args */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(lt_key);
- assert(lt_key_changed);
- assert(md_key);
- assert(udata);
- assert(rt_key);
- assert(new_node_p);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(lt_key);
+ HDassert(lt_key_changed);
+ HDassert(md_key);
+ HDassert(udata);
+ HDassert(rt_key);
+ HDassert(new_node_p);
cmp = H5D_istore_cmp3(f, dxpl_id, lt_key, udata, rt_key);
- assert(cmp <= 0);
+ HDassert(cmp <= 0);
if (cmp < 0) {
/* Negative indices not supported yet */
HGOTO_ERROR(H5E_STORAGE, H5E_UNSUPPORTED, H5B_INS_ERROR, "internal error")
- } else if (H5V_vector_eq_u (udata->mesg->u.chunk.ndims,
- udata->key.offset, lt_key->offset) &&
+ } else if (H5V_vector_eq_u (udata->common.mesg->u.chunk.ndims,
+ udata->common.key.offset, lt_key->offset) &&
lt_key->nbytes>0) {
/*
* Already exists. If the new size is not the same as the old size
* then we should reallocate storage.
*/
- if (lt_key->nbytes != udata->key.nbytes) {
+ if (lt_key->nbytes != udata->common.key.nbytes) {
/* Currently, the old chunk data is "thrown away" after the space is reallocated,
* so avoid data copy in H5MF_realloc() call by just free'ing the space and
* allocating new space.
@@ -768,19 +772,19 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
* QAK - 11/19/2002
*/
#ifdef OLD_WAY
- if (HADDR_UNDEF==(*new_node_p=H5MF_realloc(f, H5FD_MEM_DRAW, addr,
- (hsize_t)lt_key->nbytes, (hsize_t)udata->key.nbytes)))
- HGOTO_ERROR (H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "unable to reallocate chunk storage")
+ if(HADDR_UNDEF == (*new_node_p = H5MF_realloc(f, H5FD_MEM_DRAW, addr,
+ (hsize_t)lt_key->nbytes, (hsize_t)udata->common.key.nbytes)))
+ HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "unable to reallocate chunk storage")
#else /* OLD_WAY */
H5_CHECK_OVERFLOW( lt_key->nbytes ,size_t, hsize_t);
- if (H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes)<0)
+ if(H5MF_xfree(f, H5FD_MEM_DRAW, dxpl_id, addr, (hsize_t)lt_key->nbytes)<0)
HGOTO_ERROR(H5E_STORAGE, H5E_CANTFREE, H5B_INS_ERROR, "unable to free chunk")
- H5_CHECK_OVERFLOW( udata->key.nbytes ,size_t, hsize_t);
- if (HADDR_UNDEF==(*new_node_p=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->key.nbytes)))
+ H5_CHECK_OVERFLOW(udata->common.key.nbytes ,size_t, hsize_t);
+ if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->common.key.nbytes)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "unable to reallocate chunk")
#endif /* OLD_WAY */
- lt_key->nbytes = udata->key.nbytes;
- lt_key->filter_mask = udata->key.filter_mask;
+ lt_key->nbytes = udata->common.key.nbytes;
+ lt_key->filter_mask = udata->common.key.filter_mask;
*lt_key_changed = TRUE;
udata->addr = *new_node_p;
ret_value = H5B_INS_CHANGE;
@@ -789,28 +793,28 @@ H5D_istore_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key,
ret_value = H5B_INS_NOOP;
}
- } else if (H5V_hyper_disjointp(udata->mesg->u.chunk.ndims,
- lt_key->offset, udata->mesg->u.chunk.dim,
- udata->key.offset, udata->mesg->u.chunk.dim)) {
- assert(H5V_hyper_disjointp(udata->mesg->u.chunk.ndims,
- rt_key->offset, udata->mesg->u.chunk.dim,
- udata->key.offset, udata->mesg->u.chunk.dim));
+ } else if (H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
+ lt_key->offset, udata->common.mesg->u.chunk.dim,
+ udata->common.key.offset, udata->common.mesg->u.chunk.dim)) {
+ HDassert(H5V_hyper_disjointp(udata->common.mesg->u.chunk.ndims,
+ rt_key->offset, udata->common.mesg->u.chunk.dim,
+ udata->common.key.offset, udata->common.mesg->u.chunk.dim));
/*
* Split this node, inserting the new new node to the right of the
* current node. The MD_KEY is where the split occurs.
*/
- md_key->nbytes = udata->key.nbytes;
- md_key->filter_mask = udata->key.filter_mask;
- for (u=0; u<udata->mesg->u.chunk.ndims; u++) {
- assert(0 == udata->key.offset[u] % udata->mesg->u.chunk.dim[u]);
- md_key->offset[u] = udata->key.offset[u];
+ md_key->nbytes = udata->common.key.nbytes;
+ md_key->filter_mask = udata->common.key.filter_mask;
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++) {
+ HDassert(0 == udata->common.key.offset[u] % udata->common.mesg->u.chunk.dim[u]);
+ md_key->offset[u] = udata->common.key.offset[u];
}
/*
* Allocate storage for the new chunk
*/
- H5_CHECK_OVERFLOW( udata->key.nbytes ,size_t, hsize_t);
- if (HADDR_UNDEF==(*new_node_p=H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->key.nbytes)))
+ H5_CHECK_OVERFLOW(udata->common.key.nbytes ,size_t, hsize_t);
+ if(HADDR_UNDEF == (*new_node_p = H5MF_alloc(f, H5FD_MEM_DRAW, dxpl_id, (hsize_t)udata->common.key.nbytes)))
HGOTO_ERROR(H5E_STORAGE, H5E_NOSPACE, H5B_INS_ERROR, "file allocation failed")
udata->addr = *new_node_p;
ret_value = H5B_INS_RIGHT;
@@ -843,12 +847,12 @@ static int
H5D_istore_iter_allocated (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_lt_key, haddr_t UNUSED addr,
const void UNUSED *_rt_key, void *_udata)
{
- H5D_istore_ud1_t *bt_udata = (H5D_istore_ud1_t *)_udata;
+ H5D_istore_it_ud1_t *udata = (H5D_istore_it_ud1_t *)_udata;
const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_iter_allocated)
- bt_udata->total_storage += lt_key->nbytes;
+ udata->total_storage += lt_key->nbytes;
FUNC_LEAVE_NOAPI(H5B_ITER_CONT)
} /* H5D_istore_iter_allocated() */
@@ -874,35 +878,86 @@ static int
H5D_istore_iter_dump (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_lt_key, haddr_t UNUSED addr,
const void UNUSED *_rt_key, void *_udata)
{
- H5D_istore_ud1_t *bt_udata = (H5D_istore_ud1_t *)_udata;
+ H5D_istore_it_ud2_t *udata = (H5D_istore_it_ud2_t *)_udata;
const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key;
unsigned u;
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_iter_dump)
- if (bt_udata->stream) {
- if (0==bt_udata->total_storage) {
- fprintf(bt_udata->stream,
- " Flags Bytes Address Logical Offset\n");
- fprintf(bt_udata->stream,
- " ========== ======== ========== "
- "==============================\n");
- }
- HDfprintf(bt_udata->stream, " 0x%08x %8Zu %10a [",
- lt_key->filter_mask, lt_key->nbytes, addr);
- for (u=0; u<bt_udata->mesg->u.chunk.ndims; u++)
- HDfprintf(bt_udata->stream, "%s%Hd", u?", ":"", lt_key->offset[u]);
- HDfputs("]\n", bt_udata->stream);
-
- /* Use "total storage" information as flag for printing headers */
- bt_udata->total_storage++;
- }
+ if(udata->stream) {
+ if(!udata->header_displayed) {
+ HDfprintf(udata->stream, " Flags Bytes Address Logical Offset\n");
+ HDfprintf(udata->stream, " ========== ======== ========== ==============================\n");
+
+ /* Set flag that the headers has been printed */
+ udata->header_displayed = TRUE;
+ } /* end if */
+ HDfprintf(udata->stream, " 0x%08x %8Zu %10a [", lt_key->filter_mask, lt_key->nbytes, addr);
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims; u++)
+ HDfprintf(udata->stream, "%s%Hd", (u ? ", " : ""), lt_key->offset[u]);
+ HDfputs("]\n", udata->stream);
+ } /* end if */
FUNC_LEAVE_NOAPI(H5B_ITER_CONT)
} /* H5D_istore_iter_dump() */
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_iter_copy
+ *
+ * Purpose: copy chunked raw data from source file and insert to the
+ * B-tree node in the destination file
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * August 20, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5D_istore_iter_copy(H5F_t *f_src, hid_t dxpl_id, const void *_lt_key, haddr_t addr_src,
+ const void UNUSED *_rt_key, void *_udata)
+{
+ H5D_istore_it_ud4_t *udata = (H5D_istore_it_ud4_t *)_udata;
+ const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key;
+ void *chunk = NULL; /*the chunk data */
+ H5D_istore_ud1_t udata_dst;
+ int ret_value = H5B_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5D_istore_iter_copy)
+
+ /* Allocate memory for copying the chunk */
+ if(NULL == (chunk = H5MM_malloc(lt_key->nbytes)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5B_ITER_ERROR, "memory allocation failed for raw data chunk")
+
+ /* read chunk data from the source file */
+ if(H5F_block_read(f_src, H5FD_MEM_DRAW, addr_src, lt_key->nbytes, dxpl_id, chunk) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, H5B_ITER_ERROR, "unable to read raw data chunk")
+
+ /* Copy source chunk callback information for insertion */
+ HDmemset(&udata_dst, 0, sizeof(udata_dst));
+ HDmemcpy(&(udata_dst.common.key), lt_key, sizeof(H5D_istore_key_t));
+ udata_dst.common.mesg = udata->common.mesg; /* Share this pointer for a short while */
+
+ /* Insert chunk into the destination Btree */
+ if(H5B_insert(udata->file_dst, dxpl_id, H5B_ISTORE, udata->addr_dst, &udata_dst) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, H5B_ITER_ERROR, "unable to allocate chunk")
+
+ /* Write chunk data to destination file */
+ HDassert(H5F_addr_defined(udata_dst.addr));
+ if(H5F_block_write(udata->file_dst, H5FD_MEM_DRAW, udata_dst.addr, udata_dst.common.key.nbytes, dxpl_id, chunk) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, H5B_ITER_ERROR, "unable to write raw data to file")
+
+done:
+ if(chunk)
+ H5MM_xfree(chunk);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_istore_iter_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_init
*
* Purpose: Initialize the raw data chunk cache for a dataset. This is
@@ -974,12 +1029,12 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
if (ent->dirty) {
H5D_istore_ud1_t udata; /*pass through B-tree */
- udata.mesg = &io_info->dset->shared->layout;
- udata.key.filter_mask = 0;
+ udata.common.mesg = &io_info->dset->shared->layout;
+ udata.common.key.filter_mask = 0;
udata.addr = HADDR_UNDEF;
- udata.key.nbytes = ent->chunk_size;
+ udata.common.key.nbytes = ent->chunk_size;
for (u=0; u<io_info->dset->shared->layout.u.chunk.ndims; u++)
- udata.key.offset[u] = ent->offset[u];
+ udata.common.key.offset[u] = ent->offset[u];
alloc = ent->alloc_size;
/* Should the chunk be filtered before writing it to disk? */
@@ -1005,8 +1060,8 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
point_of_no_return = TRUE;
ent->chunk = NULL;
}
- if (H5Z_pipeline(&(io_info->dset->shared->dcpl_cache.pline), 0, &(udata.key.filter_mask), io_info->dxpl_cache->err_detect,
- io_info->dxpl_cache->filter_cb, &(udata.key.nbytes), &alloc, &buf)<0)
+ if (H5Z_pipeline(&(io_info->dset->shared->dcpl_cache.pline), 0, &(udata.common.key.filter_mask), io_info->dxpl_cache->err_detect,
+ io_info->dxpl_cache->filter_cb, &(udata.common.key.nbytes), &alloc, &buf)<0)
HGOTO_ERROR(H5E_PLINE, H5E_WRITEERROR, FAIL, "output pipeline failed")
}
@@ -1016,7 +1071,7 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
*/
if (H5B_insert(io_info->dset->ent.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, &udata)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
- if (H5F_block_write(io_info->dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.key.nbytes, io_info->dxpl_id, buf)<0)
+ if (H5F_block_write(io_info->dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, io_info->dxpl_id, buf)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
/* Mark cache entry as clean */
@@ -1251,16 +1306,12 @@ done:
static herr_t
H5D_istore_shared_create (const H5F_t *f, H5O_layout_t *layout)
{
- H5D_istore_ud1_t udata;
H5B_shared_t *shared; /* Shared B-tree node info */
size_t u; /* Local index variable */
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_shared_create)
- /* Initialize "user" data for B-tree callbacks, etc. */
- udata.mesg = layout;
-
/* Allocate space for the shared structure */
if(NULL==(shared=H5FL_MALLOC(H5B_shared_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for shared B-tree info")
@@ -1268,7 +1319,9 @@ H5D_istore_shared_create (const H5F_t *f, H5O_layout_t *layout)
/* Set up the "global" information for this file's groups */
shared->type= H5B_ISTORE;
shared->two_k=2*H5F_KVALUE(f,H5B_ISTORE);
- shared->sizeof_rkey = H5D_istore_sizeof_rkey(f, &udata);
+ shared->sizeof_rkey = 4 + /*storage size */
+ 4 + /*filter mask */
+ layout->u.chunk.ndims*8; /*dimension indices */
assert(shared->sizeof_rkey);
shared->sizeof_rnode = H5B_nodesize(f, shared, &shared->sizeof_keys);
assert(shared->sizeof_rnode);
@@ -1539,10 +1592,10 @@ H5D_istore_lock(const H5D_io_info_t *io_info,
haddr_t chunk_addr; /* Address of chunk on disk */
if(udata!=NULL)
- chunk_addr=udata->addr;
+ chunk_addr = udata->addr;
else {
/* Point at temporary storage for B-tree pass through */
- udata=&tmp_udata;
+ udata = &tmp_udata;
/*
* Not in the cache. Read it from the file and count this as a miss
@@ -1552,22 +1605,22 @@ H5D_istore_lock(const H5D_io_info_t *io_info,
} /* end else */
if (H5F_addr_defined(chunk_addr)) {
- size_t chunk_alloc=0; /*allocated chunk size */
+ size_t chunk_alloc = 0; /*allocated chunk size */
/*
* The chunk exists on disk.
*/
/* Chunk size on disk isn't [likely] the same size as the final chunk
* size in memory, so allocate memory big enough. */
- chunk_alloc = udata->key.nbytes;
+ chunk_alloc = udata->common.key.nbytes;
if (NULL==(chunk = H5D_istore_chunk_alloc (chunk_alloc,pline)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk")
- if (H5F_block_read(dset->ent.file, H5FD_MEM_DRAW, chunk_addr, udata->key.nbytes, io_info->dxpl_id, chunk)<0)
+ if (H5F_block_read(dset->ent.file, H5FD_MEM_DRAW, chunk_addr, udata->common.key.nbytes, io_info->dxpl_id, chunk)<0)
HGOTO_ERROR (H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk")
if (pline->nused)
- if (H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->key.filter_mask), io_info->dxpl_cache->err_detect,
- io_info->dxpl_cache->filter_cb, &(udata->key.nbytes), &chunk_alloc, &chunk)<0) {
+ if (H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->common.key.filter_mask), io_info->dxpl_cache->err_detect,
+ io_info->dxpl_cache->filter_cb, &(udata->common.key.nbytes), &chunk_alloc, &chunk)<0) {
HGOTO_ERROR(H5E_PLINE, H5E_READERROR, NULL, "data pipeline read failed")
}
#ifdef H5D_ISTORE_DEBUG
@@ -1831,16 +1884,16 @@ H5D_istore_readvv(const H5D_io_info_t *io_info,
FUNC_ENTER_NOAPI(H5D_istore_readvv, FAIL)
/* Check args */
- assert(io_info);
- assert(dset && H5D_CHUNKED==dset->shared->layout.type);
- assert(dset->shared->layout.u.chunk.ndims>0 && dset->shared->layout.u.chunk.ndims<=H5O_LAYOUT_NDIMS);
- assert(io_info->dxpl_cache);
- assert(io_info->store);
- assert(chunk_len_arr);
- assert(chunk_offset_arr);
- assert(mem_len_arr);
- assert(mem_offset_arr);
- assert(buf);
+ HDassert(io_info);
+ HDassert(dset && H5D_CHUNKED==dset->shared->layout.type);
+ HDassert(dset->shared->layout.u.chunk.ndims>0 && dset->shared->layout.u.chunk.ndims<=H5O_LAYOUT_NDIMS);
+ HDassert(io_info->dxpl_cache);
+ HDassert(io_info->store);
+ HDassert(chunk_len_arr);
+ HDassert(chunk_offset_arr);
+ HDassert(mem_len_arr);
+ HDassert(mem_offset_arr);
+ HDassert(buf);
/* Get the address of this chunk on disk */
#ifdef QAK
@@ -1848,7 +1901,7 @@ HDfprintf(stderr,"%s: io_info->store->chunk.offset={",FUNC);
for(u=0; u<dset->shared->layout.u.chunk.ndims; u++)
HDfprintf(stderr,"%Hd%s",io_info->store->chunk.offset[u],(u<(dset->shared->layout.u.chunk.ndims-1) ? ", " : "}\n"));
#endif /* QAK */
- chunk_addr=H5D_istore_get_addr(io_info, &udata);
+ chunk_addr = H5D_istore_get_addr(io_info, &udata);
#ifdef QAK
HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Zu\n",FUNC,chunk_addr,dset->shared->layout.u.chunk.size);
HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
@@ -2013,7 +2066,7 @@ H5D_istore_writevv(const H5D_io_info_t *io_info,
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
const void *buf)
{
- H5D_t *dset=io_info->dset; /* Local pointer to the dataset info */
+ H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
H5D_istore_ud1_t udata; /*B-tree pass-through */
haddr_t chunk_addr; /* Chunk address on disk */
size_t u; /* Local index variables */
@@ -2022,16 +2075,16 @@ H5D_istore_writevv(const H5D_io_info_t *io_info,
FUNC_ENTER_NOAPI(H5D_istore_writevv, FAIL)
/* Check args */
- assert(io_info);
- assert(dset && H5D_CHUNKED==dset->shared->layout.type);
- assert(dset->shared->layout.u.chunk.ndims>0 && dset->shared->layout.u.chunk.ndims<=H5O_LAYOUT_NDIMS);
- assert(io_info->dxpl_cache);
- assert(io_info->store);
- assert(chunk_len_arr);
- assert(chunk_offset_arr);
- assert(mem_len_arr);
- assert(mem_offset_arr);
- assert(buf);
+ HDassert(io_info);
+ HDassert(dset && H5D_CHUNKED==dset->shared->layout.type);
+ HDassert(dset->shared->layout.u.chunk.ndims>0 && dset->shared->layout.u.chunk.ndims<=H5O_LAYOUT_NDIMS);
+ HDassert(io_info->dxpl_cache);
+ HDassert(io_info->store);
+ HDassert(chunk_len_arr);
+ HDassert(chunk_offset_arr);
+ HDassert(mem_len_arr);
+ HDassert(mem_offset_arr);
+ HDassert(buf);
/* Get the address of this chunk on disk */
#ifdef QAK
@@ -2039,7 +2092,7 @@ HDfprintf(stderr,"%s: io_info->store->chunk.offset={",FUNC);
for(u=0; u<dset->shared->layout.u.chunk.ndims; u++)
HDfprintf(stderr,"%Hd%s",io_info->store->chunk.offset[u],(u<(dset->shared->layout.u.chunk.ndims-1) ? ", " : "}\n"));
#endif /* QAK */
- chunk_addr=H5D_istore_get_addr(io_info, &udata);
+ chunk_addr = H5D_istore_get_addr(io_info, &udata);
#ifdef QAK
HDfprintf(stderr,"%s: chunk_addr=%a, chunk_size=%Zu\n",FUNC,chunk_addr,dset->shared->layout.u.chunk.size);
HDfprintf(stderr,"%s: chunk_len_arr[%Zu]=%Zu\n",FUNC,*chunk_curr_seq,chunk_len_arr[*chunk_curr_seq]);
@@ -2161,29 +2214,29 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5D_istore_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */ )
+H5D_istore_create(H5F_t *f, hid_t dxpl_id, H5O_layout_t *layout /*out */)
{
- H5D_istore_ud1_t udata;
+ H5D_istore_ud0_t udata;
#ifndef NDEBUG
unsigned u;
#endif
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_create, FAIL)
/* Check args */
- assert(f);
- assert(layout && H5D_CHUNKED == layout->type);
- assert(layout->u.chunk.ndims > 0 && layout->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
+ HDassert(f);
+ HDassert(layout && H5D_CHUNKED == layout->type);
+ HDassert(layout->u.chunk.ndims > 0 && layout->u.chunk.ndims <= H5O_LAYOUT_NDIMS);
#ifndef NDEBUG
- for (u = 0; u < layout->u.chunk.ndims; u++)
- assert(layout->u.chunk.dim[u] > 0);
+ for(u = 0; u < layout->u.chunk.ndims; u++)
+ HDassert(layout->u.chunk.dim[u] > 0);
#endif
/* Initialize "user" data for B-tree callbacks, etc. */
udata.mesg = layout;
- if (H5B_create(f, dxpl_id, H5B_ISTORE, &udata, &(layout->u.chunk.addr)/*out*/) < 0)
+ if(H5B_create(f, dxpl_id, H5B_ISTORE, &udata, &(layout->u.chunk.addr)/*out*/) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "can't create B-tree")
done:
@@ -2215,12 +2268,12 @@ H5D_istore_allocated(H5D_t *dset, hid_t dxpl_id)
H5D_rdcc_ent_t *ent; /*cache entry */
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */
- H5D_istore_ud1_t udata;
+ H5D_istore_it_ud1_t udata;
hsize_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_allocated, 0)
- assert(dset);
+ HDassert(dset);
/* Fill the DXPL cache values for later use */
if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache)<0)
@@ -2237,12 +2290,12 @@ H5D_istore_allocated(H5D_t *dset, hid_t dxpl_id)
} /* end for */
HDmemset(&udata, 0, sizeof udata);
- udata.mesg = &dset->shared->layout;
+ udata.common.mesg = &dset->shared->layout;
if (H5B_iterate(dset->ent.file, dxpl_id, H5B_ISTORE, H5D_istore_iter_allocated, dset->shared->layout.u.chunk.addr, &udata)<0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, 0, "unable to iterate over chunk B-tree")
/* Set return value */
- ret_value=udata.total_storage;
+ ret_value = udata.total_storage;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -2273,18 +2326,18 @@ H5D_istore_get_addr(const H5D_io_info_t *io_info, H5D_istore_ud1_t *_udata)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_istore_get_addr)
- assert(io_info);
- assert(io_info->dset);
- assert(io_info->dset->shared->layout.u.chunk.ndims > 0);
- assert(io_info->store->chunk.offset);
+ HDassert(io_info);
+ HDassert(io_info->dset);
+ HDassert(io_info->dset->shared->layout.u.chunk.ndims > 0);
+ HDassert(io_info->store->chunk.offset);
/* Check for udata struct to return */
- udata = (_udata!=NULL ? _udata : &tmp_udata);
+ udata = (_udata != NULL ? _udata : &tmp_udata);
/* Initialize the information about the chunk we are looking for */
- for (u=0; u<io_info->dset->shared->layout.u.chunk.ndims; u++)
- udata->key.offset[u] = io_info->store->chunk.offset[u];
- udata->mesg = &(io_info->dset->shared->layout);
+ for(u = 0; u < io_info->dset->shared->layout.u.chunk.ndims; u++)
+ udata->common.key.offset[u] = io_info->store->chunk.offset[u];
+ udata->common.mesg = &(io_info->dset->shared->layout);
udata->addr = HADDR_UNDEF;
/* Go get the chunk information */
@@ -2328,6 +2381,7 @@ static void *
H5D_istore_chunk_alloc(size_t size, const H5O_pline_t *pline)
{
void *ret_value=NULL; /* Return value */
+
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_chunk_alloc)
assert(size);
@@ -2411,7 +2465,6 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
H5D_fill_time_t fill_time; /* When to write fill values */
H5D_fill_value_t fill_status; /* The fill value status */
unsigned should_fill=0; /* Whether fill values should be written */
- H5D_istore_ud1_t udata; /* B-tree pass-through for creating chunk */
void *chunk=NULL; /* Chunk buffer for writing fill values */
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */
@@ -2562,14 +2615,16 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
} /* end if */
if(!chunk_exists) {
+ H5D_istore_ud1_t udata; /* B-tree pass-through for creating chunk */
+
/* Initialize the chunk information */
- udata.mesg = &dset->shared->layout;
- udata.key.filter_mask = filter_mask;
+ udata.common.mesg = &dset->shared->layout;
+ udata.common.key.filter_mask = filter_mask;
udata.addr = HADDR_UNDEF;
H5_CHECK_OVERFLOW(chunk_size,hsize_t,size_t);
- udata.key.nbytes = (size_t)chunk_size;
- for (u=0; u<dset->shared->layout.u.chunk.ndims; u++)
- udata.key.offset[u] = chunk_offset[u];
+ udata.common.key.nbytes = (size_t)chunk_size;
+ for(u = 0; u < dset->shared->layout.u.chunk.ndims; u++)
+ udata.common.key.offset[u] = chunk_offset[u];
/* Allocate the chunk with all processes */
if (H5B_insert(dset->ent.file, dxpl_id, H5B_ISTORE, dset->shared->layout.u.chunk.addr, &udata)<0)
@@ -2583,7 +2638,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Write the chunks out from only one process */
/* !! Use the internal "independent" DXPL!! -QAK */
if(H5_PAR_META_WRITE==mpi_rank) {
- if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.key.nbytes, H5AC_ind_dxpl_id, chunk)<0)
+ if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, H5AC_ind_dxpl_id, chunk)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
} /* end if */
@@ -2592,7 +2647,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.key.nbytes, dxpl_id, chunk)<0)
+ if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, dxpl_id, chunk)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -2735,14 +2790,14 @@ done:
herr_t
H5D_istore_prune_by_extent(const H5D_io_info_t *io_info)
{
- H5D_t *dset=io_info->dset; /* Local pointer to the dataset info */
+ H5D_t *dset = io_info->dset; /* Local pointer to the dataset info */
const H5D_rdcc_t *rdcc = &(dset->shared->cache.chunk); /*raw data chunk cache */
H5D_rdcc_ent_t *ent = NULL, *next = NULL; /*cache entry */
unsigned u; /*counters */
int found; /*remove this entry */
- H5D_istore_ud1_t udata; /*B-tree pass-through */
+ H5D_istore_it_ud3_t udata; /*B-tree pass-through */
hsize_t curr_dims[H5O_LAYOUT_NDIMS]; /*current dataspace dimensions */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_prune_by_extent, FAIL)
@@ -2794,8 +2849,7 @@ H5D_istore_prune_by_extent(const H5D_io_info_t *io_info)
*/
HDmemset(&udata, 0, sizeof udata);
- udata.stream = stdout;
- udata.mesg = &dset->shared->layout;
+ udata.common.mesg = &dset->shared->layout;
udata.dims = curr_dims;
if(H5B_iterate(dset->ent.file, io_info->dxpl_id, H5B_ISTORE, H5D_istore_prune_extent, dset->shared->layout.u.chunk.addr, &udata) < 0)
@@ -2826,11 +2880,10 @@ static int
H5D_istore_prune_extent(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t UNUSED addr,
const void UNUSED *_rt_key, void *_udata)
{
- H5D_istore_ud1_t *bt_udata = (H5D_istore_ud1_t *)_udata;
+ H5D_istore_it_ud3_t *udata = (H5D_istore_it_ud3_t *)_udata;
const H5D_istore_key_t *lt_key = (const H5D_istore_key_t *)_lt_key;
unsigned u;
- H5D_istore_ud1_t udata;
- int ret_value=H5B_ITER_CONT; /* Return value */
+ int ret_value = H5B_ITER_CONT; /* Return value */
/* The LT_KEY is the left key (the one that describes the chunk). It points to a chunk of
* storage that contains the beginning of the logical address space represented by UDATA.
@@ -2839,21 +2892,16 @@ H5D_istore_prune_extent(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t UN
FUNC_ENTER_NOAPI_NOINIT(H5D_istore_prune_extent)
/* Figure out what chunks are no longer in use for the specified extent and release them */
- for(u = 0; u < bt_udata->mesg->u.chunk.ndims - 1; u++)
- if((hsize_t)lt_key->offset[u] > bt_udata->dims[u]) {
-#ifdef H5D_ISTORE_DEBUG
- HDfputs("b-tree:remove:[", bt_udata->stream);
- for(u = 0; u < bt_udata->mesg->u.chunk.ndims - 1; u++)
- HDfprintf(bt_udata->stream, "%s%Hd", u ? ", " : "", lt_key->offset[u]);
- HDfputs("]\n", bt_udata->stream);
-#endif
+ for(u = 0; u < udata->common.mesg->u.chunk.ndims - 1; u++)
+ if((hsize_t)lt_key->offset[u] > udata->dims[u]) {
+ H5D_istore_ud0_t bt_udata;
- HDmemset(&udata, 0, sizeof udata);
- udata.key = *lt_key;
- udata.mesg = bt_udata->mesg;
+ HDmemset(&bt_udata, 0, sizeof bt_udata);
+ bt_udata.key = *lt_key;
+ bt_udata.mesg = udata->common.mesg;
/* Remove */
- if(H5B_remove(f, dxpl_id, H5B_ISTORE, bt_udata->mesg->u.chunk.addr, &udata) < 0)
+ if(H5B_remove(f, dxpl_id, H5B_ISTORE, udata->common.mesg->u.chunk.addr, &bt_udata) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_ITER_ERROR, "unable to remove entry")
break;
} /* end if */
@@ -3128,7 +3176,7 @@ H5D_istore_delete(H5F_t *f, hid_t dxpl_id, const H5O_layout_t *layout)
/* Check if the B-tree has been created in the file */
if(H5F_addr_defined(layout->u.chunk.addr)) {
H5O_layout_t tmp_layout=*layout;/* Local copy of layout info */
- H5D_istore_ud1_t udata; /* User data for B-tree iterator call */
+ H5D_istore_ud0_t udata; /* User data for B-tree iterator call */
/* Set up user data for B-tree deletion */
HDmemset(&udata, 0, sizeof udata);
@@ -3253,6 +3301,67 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5D_istore_copy
+ *
+ * Purpose: copy an indexed storage B-tree from SRC file to DST file.
+ *
+ * Return: Non-negative on success (with the ISTORE argument initialized
+ * and ready to write to an object header). Negative on failure.
+ *
+ * Programmer: Peter Cao
+ * August 20, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src,
+ H5F_t *f_dst, H5O_layout_t *layout_dst, hid_t dxpl_id)
+{
+ H5D_istore_it_ud4_t udata;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5D_istore_copy, FAIL)
+
+ /* Check args */
+ HDassert(f_src);
+ HDassert(f_dst);
+ HDassert(layout_src && H5D_CHUNKED == layout_src->type);
+ HDassert(layout_dst && H5D_CHUNKED == layout_dst->type);
+
+ /* Create shared B-tree info for each file */
+ if(H5D_istore_shared_create(f_src, layout_src) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
+ if(H5D_istore_shared_create(f_dst, layout_dst) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
+
+ /* Check if we need to create the B-tree in the dest. file */
+ if(layout_dst->u.chunk.addr == HADDR_UNDEF) {
+ /* Create the root of the B-tree that describes chunked storage */
+ if(H5D_istore_create(f_dst, dxpl_id, layout_dst) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to initialize chunked storage")
+ } /* end if */
+
+ /* Initialize the callback structure for the source */
+ HDmemset(&udata, 0, sizeof udata);
+ udata.common.mesg = layout_src;
+ udata.file_dst = f_dst;
+ udata.addr_dst = layout_dst->u.chunk.addr;
+
+ /* copy the chunked data by iteration */
+ if(H5B_iterate(f_src, dxpl_id, H5B_ISTORE, H5D_istore_iter_copy, layout_src->u.chunk.addr, &udata) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to iterate over chunk B-tree")
+
+done:
+ if(H5RC_DEC(layout_src->u.chunk.btree_shared) < 0)
+ HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
+ if(H5RC_DEC(layout_dst->u.chunk.btree_shared) < 0)
+ HDONE_ERROR(H5E_IO, H5E_CANTFREE, FAIL, "unable to decrement ref-counted page")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5D_istore_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5D_istore_dump_btree
*
* Purpose: Prints information about the storage B-tree to the specified
@@ -3271,17 +3380,17 @@ herr_t
H5D_istore_dump_btree(H5F_t *f, hid_t dxpl_id, FILE *stream, unsigned ndims, haddr_t addr)
{
H5O_layout_t layout;
- H5D_istore_ud1_t udata;
+ H5D_istore_it_ud2_t udata;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_dump_btree, FAIL)
HDmemset(&udata, 0, sizeof udata);
layout.u.chunk.ndims = ndims;
- udata.mesg = &layout;
+ udata.common.mesg = &layout;
udata.stream = stream;
if(stream)
- HDfprintf(stream, " Address: %a\n",addr);
+ HDfprintf(stream, " Address: %a\n", addr);
if(H5B_iterate(f, dxpl_id, H5B_ISTORE, H5D_istore_iter_dump, addr, &udata)<0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, 0, "unable to iterate over chunk B-tree")
@@ -3371,20 +3480,22 @@ H5D_istore_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int inden
int fwidth, unsigned ndims)
{
H5O_layout_t layout;
- H5D_istore_ud1_t udata;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5D_istore_ud0_t udata; /* B-tree user data */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5D_istore_debug,FAIL)
layout.u.chunk.ndims = ndims;
- HDmemset (&udata, 0, sizeof udata);
- udata.mesg = &layout;
/* Allocate the shared structure */
if(H5D_istore_shared_create(f, &layout)<0)
HGOTO_ERROR (H5E_RESOURCE, H5E_CANTINIT, FAIL, "can't create wrapper for shared B-tree info")
- (void)H5B_debug (f, dxpl_id, addr, stream, indent, fwidth, H5B_ISTORE, &udata);
+ /* Set up B-tree user data */
+ HDmemset(&udata, 0, sizeof udata);
+ udata.mesg = &layout;
+
+ (void)H5B_debug(f, dxpl_id, addr, stream, indent, fwidth, H5B_ISTORE, &udata);
/* Free the raw B-tree node buffer */
if(layout.u.chunk.btree_shared==NULL)
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 04fce35..651f2b8 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -271,6 +271,8 @@ H5_DLL ssize_t H5D_istore_writevv(const H5D_io_info_t *io_info,
const void *buf);
H5_DLL haddr_t H5D_istore_get_addr(const H5D_io_info_t *io_info,
struct H5D_istore_ud1_t *_udata);
+H5_DLL herr_t H5D_istore_copy(H5F_t *f_src, H5O_layout_t *layout_src,
+ H5F_t *f_dst, H5O_layout_t *layout_dst, hid_t dxpl_id);
/* Functions that operate on external file list (efl) storage */
H5_DLL ssize_t H5D_efl_readvv(const H5D_io_info_t *io_info,
diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h
index 83074f2..0edabb3 100644
--- a/src/H5Dpublic.h
+++ b/src/H5Dpublic.h
@@ -88,29 +88,28 @@ extern "C" {
typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id, unsigned ndim,
const hsize_t *point, void *operator_data);
-H5_DLL hid_t H5Dcreate (hid_t file_id, const char *name, hid_t type_id,
+H5_DLL hid_t H5Dcreate(hid_t file_id, const char *name, hid_t type_id,
hid_t space_id, hid_t plist_id);
-H5_DLL hid_t H5Dopen (hid_t file_id, const char *name);
-H5_DLL herr_t H5Dclose (hid_t dset_id);
-H5_DLL hid_t H5Dget_space (hid_t dset_id);
-H5_DLL herr_t H5Dget_space_status(hid_t dset_id,
- H5D_space_status_t *allocation);
-H5_DLL hid_t H5Dget_type (hid_t dset_id);
-H5_DLL hid_t H5Dget_create_plist (hid_t dset_id);
+H5_DLL hid_t H5Dopen(hid_t file_id, const char *name);
+H5_DLL herr_t H5Dclose(hid_t dset_id);
+H5_DLL hid_t H5Dget_space(hid_t dset_id);
+H5_DLL herr_t H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation);
+H5_DLL hid_t H5Dget_type(hid_t dset_id);
+H5_DLL hid_t H5Dget_create_plist(hid_t dset_id);
H5_DLL hsize_t H5Dget_storage_size(hid_t dset_id);
H5_DLL haddr_t H5Dget_offset(hid_t dset_id);
-H5_DLL herr_t H5Dread (hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+H5_DLL herr_t H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
hid_t file_space_id, hid_t plist_id, void *buf/*out*/);
-H5_DLL herr_t H5Dwrite (hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
+H5_DLL herr_t H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
hid_t file_space_id, hid_t plist_id, const void *buf);
-H5_DLL herr_t H5Dextend (hid_t dset_id, const hsize_t *size);
+H5_DLL herr_t H5Dextend(hid_t dset_id, const hsize_t *size);
H5_DLL herr_t H5Diterate(void *buf, hid_t type_id, hid_t space_id,
H5D_operator_t op, void *operator_data);
H5_DLL herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf);
H5_DLL herr_t H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, hsize_t *size);
H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf,
hid_t buf_type, hid_t space);
-H5_DLL herr_t H5Dset_extent (hid_t dset_id, const hsize_t *size);
+H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t *size);
H5_DLL herr_t H5Ddebug(hid_t dset_id);
@@ -118,4 +117,3 @@ H5_DLL herr_t H5Ddebug(hid_t dset_id);
}
#endif
#endif /* _H5Dpublic_H */
-
diff --git a/src/H5G.c b/src/H5G.c
index e7fc1cf..90e08db 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -91,7 +91,6 @@
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5G_init_interface
-
/* Packages needed by this file... */
#include "H5private.h" /* Generic Functions */
#include "H5Aprivate.h" /* Attributes */
@@ -108,7 +107,6 @@
/* Local macros */
#define H5G_INIT_HEAP 8192
#define H5G_RESERVED_ATOMS 0
-#define H5G_SIZE_HINT 256 /*default root grp size hint */
/*
* During name lookups (see H5G_namei()) we sometimes want information about
@@ -149,6 +147,8 @@ typedef struct H5G_typeinfo_t {
char *desc; /*description of object type */
} H5G_typeinfo_t;
+/* Package variables */
+
/* Local variables */
static H5G_typeinfo_t *H5G_type_g = NULL; /*object typing info */
static size_t H5G_ntypes_g = 0; /*entries in type table */
@@ -163,6 +163,9 @@ H5FL_DEFINE(H5G_shared_t);
/* Declare extern the PQ free list for the wrapped strings */
H5FL_BLK_EXTERN(str_buf);
+/* Declare a free list to manage haddr_t's */
+H5FL_DEFINE(haddr_t);
+
/* Private prototypes */
static herr_t H5G_register_type(H5G_obj_t type, htri_t(*isa)(H5G_entry_t*, hid_t),
const char *desc);
@@ -200,6 +203,8 @@ static htri_t H5G_common_path(const H5RS_str_t *fullpath_r,
const H5RS_str_t *prefix_r);
static H5RS_str_t *H5G_build_fullpath(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r);
static int H5G_replace_ent(void *obj_ptr, hid_t obj_id, void *key);
+static herr_t H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst,
+ const char *name_dst, hid_t plist_id);
/*-------------------------------------------------------------------------
@@ -1036,6 +1041,50 @@ done:
FUNC_LEAVE_API(ret_value);
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gcopy
+ *
+ * Purpose: Copy an object to destination location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * June 4, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Gcopy(hid_t id_src, hid_t loc_dst, const char *name_dst, hid_t plist_id)
+{
+ H5G_entry_t *ent_src = NULL, *ent_dst=NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Gcopy, FAIL)
+
+ /* Check arguments */
+ if(NULL == (ent_src = H5G_loc(id_src)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(NULL == (ent_dst = H5G_loc(loc_dst)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name_dst || !*name_dst)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
+
+/* Get correct property list */
+/* XXX: This is a kludge, to use the datatype creation property list - QAK */
+if(H5P_DEFAULT == plist_id)
+ plist_id = H5P_DATATYPE_CREATE_DEFAULT;
+else
+ if(TRUE != H5P_isa_class(plist_id, H5P_DATATYPE_CREATE))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object create property list")
+
+ if(H5G_copy(ent_src, ent_dst, name_dst, plist_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gcopy() */
+
/*
*-------------------------------------------------------------------------
*-------------------------------------------------------------------------
@@ -4214,3 +4263,60 @@ H5G_unmount(H5G_t *grp)
FUNC_LEAVE_NOAPI(SUCCEED);
} /* end H5G_unmount() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_copy
+ *
+ * Purpose: Copy an object to destination location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * June 4, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst,
+ const char *name_dst, hid_t plist_id)
+{
+ H5P_genplist_t *oc_plist; /* Property list created */
+ hid_t dxpl_id = H5AC_dxpl_id;
+ H5G_entry_t ent_new;
+ hbool_t entry_inserted = FALSE; /* Flag to indicate that the new entry was inserted into a group */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_copy, FAIL);
+
+ HDassert(ent_src);
+ HDassert(ent_src->file);
+ HDassert(loc_dst);
+ HDassert(loc_dst->file);
+ HDassert(name_dst);
+
+ /* Get the property list */
+ if(NULL == (oc_plist = H5I_object(plist_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* Reset group entry for new object */
+ H5G_ent_reset(&ent_new);
+ ent_new.file = loc_dst->file;
+
+ /* copy the object from the source file to the destination file */
+ if(H5O_copy_header(ent_src, &ent_new, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* Insert the new object in the destination file's group */
+ if(H5G_insert(loc_dst, name_dst, &ent_new, dxpl_id, oc_plist) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert the name")
+ entry_inserted = TRUE;
+
+done:
+ /* Free the ID to name buffers */
+ if(entry_inserted)
+ H5G_free_ent_name(&ent_new);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_copy() */
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index faff6ba..5e053fd 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -68,7 +68,6 @@ static herr_t H5G_node_clear(H5F_t *f, H5G_node_t *sym, hbool_t destroy);
static herr_t H5G_compute_size(const H5F_t *f, const H5G_node_t *sym, size_t *size_ptr);
/* B-tree callbacks */
-static size_t H5G_node_sizeof_rkey(const H5F_t *f, const void *_udata);
static H5RC_t *H5G_node_get_shared(const H5F_t *f, const void *_udata);
static herr_t H5G_node_create(H5F_t *f, hid_t dxpl_id, H5B_ins_t op, void *_lt_key,
void *_udata, void *_rt_key,
@@ -109,7 +108,6 @@ const H5AC_class_t H5AC_SNODE[1] = {{
H5B_class_t H5B_SNODE[1] = {{
H5B_SNODE_ID, /*id */
sizeof(H5G_node_key_t), /*sizeof_nkey */
- H5G_node_sizeof_rkey, /*get_sizeof_rkey */
H5G_node_get_shared, /*get_shared */
H5G_node_create, /*new */
H5G_node_cmp2, /*cmp2 */
@@ -124,9 +122,6 @@ H5B_class_t H5B_SNODE[1] = {{
H5G_node_debug_key, /*debug */
}};
-/* Declare a free list to manage the H5B_shared_t struct */
-H5FL_EXTERN(H5B_shared_t);
-
/* Declare a free list to manage the H5G_node_t struct */
H5FL_DEFINE_STATIC(H5G_node_t);
@@ -142,33 +137,8 @@ H5FL_SEQ_DEFINE_STATIC(size_t);
/* Declare a free list to manage the raw page information */
H5FL_BLK_DEFINE_STATIC(grp_page);
-
-/*-------------------------------------------------------------------------
- * Function: H5G_node_sizeof_rkey
- *
- * Purpose: Returns the size of a raw B-link tree key for the specified
- * file.
- *
- * Return: Success: Size of the key.
- *
- * Failure: never fails
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Jul 14 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static size_t
-H5G_node_sizeof_rkey(const H5F_t *f, const void UNUSED * udata)
-{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_node_sizeof_rkey);
-
- FUNC_LEAVE_NOAPI(H5F_SIZEOF_SIZE(f)); /*the name offset */
-}
+/* Declare extern the free list to manage haddr_t's */
+H5FL_EXTERN(haddr_t);
/*-------------------------------------------------------------------------
@@ -1803,7 +1773,7 @@ H5G_node_init(H5F_t *f)
/* Set up the "global" information for this file's groups */
shared->type= H5B_SNODE;
shared->two_k=2*H5F_KVALUE(f,H5B_SNODE);
- shared->sizeof_rkey = H5G_node_sizeof_rkey(f, NULL);
+ shared->sizeof_rkey = H5F_SIZEOF_SIZE(f); /*the name offset */
assert(shared->sizeof_rkey);
shared->sizeof_rnode = H5B_nodesize(f, shared, &shared->sizeof_keys);
assert(shared->sizeof_rnode);
@@ -1894,6 +1864,106 @@ H5G_node_shared_free (void *_shared)
/*-------------------------------------------------------------------------
+ * Function: H5G_node_copy
+ *
+ * Purpose: This function gets called during a group iterate operation
+ * to copy objects of this node into a new location.
+ *
+ * Return: 0(zero) on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * Sept 10, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
+ const void UNUSED *_rt_key, void *_udata)
+{
+ H5G_bt_it_ud5_t *udata = (H5G_bt_it_ud5_t *)_udata;
+ const H5HL_t *heap = NULL;
+ H5G_node_t *sn = NULL;
+ unsigned int i; /* Local index variable */
+ int ret_value = H5B_ITER_CONT;
+
+ FUNC_ENTER_NOAPI(H5G_node_copy, H5B_ITER_ERROR)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(udata);
+
+ /* load the symbol table into memory from the source file */
+ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node")
+
+ /* get the base address of the heap */
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name")
+
+ /* copy object in this node one by one */
+ for(i = 0; i < sn->nsyms; i++) {
+ H5G_entry_t ent_new; /* New entry to insert into dest. group */
+ H5G_entry_t *ent_src = &(sn->entry[i]); /* Convenience variable to refer to current source group entry */
+ const char *name; /* Name of source object */
+
+ /* Set up symbol table entry for destination */
+ H5G_ent_reset(&ent_new);
+ ent_new.file = udata->loc_dst->file;
+
+ /* Determine name of source object */
+ name = H5HL_offset_into(f, heap, ent_src->name_off);
+ HDassert(name);
+
+ /* Check if object in source group is a hard link */
+ if(H5F_addr_defined(ent_src->header)) {
+ /* Copy the shared object from source to destination */
+ /* (Increments link count on destination) */
+ if(H5O_copy_header_map(ent_src, &ent_new, dxpl_id, udata->map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5B_ITER_ERROR, "unable to copy object")
+ } /* ( H5F_addr_defined(ent_src->header)) */
+ else if(H5G_CACHED_SLINK == ent_src->type) {
+ /* it is a soft link */
+ H5O_stab_t stab_mesg;
+ size_t offset_link;
+ char *name_link = H5HL_offset_into(f, heap, ent_src->cache.slink.lval_offset);
+
+ /* read the symbol table where the soft link to be inserted */
+ if(NULL == H5O_read(udata->loc_dst, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_ITER_ERROR, "unable to determine local heap address")
+ if((size_t)(-1) == (offset_link = H5HL_insert(udata->loc_dst->file, dxpl_id,
+ stab_mesg.heap_addr, HDstrlen(name_link) + 1, name_link)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_ITER_ERROR, "unable to write link value to local heap")
+ H5O_reset (H5O_STAB_ID, &stab_mesg);
+
+ /* Set up soft link to insert */
+ ent_new.type = H5G_CACHED_SLINK;
+ ent_new.cache.slink.lval_offset = offset_link;
+ } /* else if */
+ else
+ HDassert(0 && "Unknown entry type");
+
+ /* Insert the new object in the destination file's group */
+ /* (Don't increment the link count - that's already done above for hard links) */
+ if(H5G_stab_insert(udata->loc_dst, name, &ent_new, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5B_ITER_ERROR, "unable to insert the name")
+
+ /* Free the ID to name buffers */
+ H5G_free_ent_name(&ent_new);
+ } /* end of for (i=0; i<sn->nsyms; i++) */
+
+done:
+ if (heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name")
+
+ if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5G_node_debug
*
* Purpose: Prints debugging information about a symbol table node
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index adb546f..4c6ec68 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -31,8 +31,11 @@
#include "H5Gprivate.h"
/* Other private headers needed by this file */
-#include "H5ACprivate.h" /* Metadata cache */
+#include "H5ACprivate.h" /* Metadata cache */
#include "H5Oprivate.h" /* Object headers */
+#include "H5SLprivate.h" /* Skip lists */
+
+#define H5G_SIZE_HINT 256 /* default root grp size hint */
/*
* A symbol table node is a collection of symbol table entries. It can
@@ -166,6 +169,13 @@ typedef struct H5G_bt_it_ud4_t {
/* upward */
} H5G_bt_it_ud4_t;
+/* Data passed to B-tree iteration for copying copy symblol table content */
+typedef struct H5G_bt_it_ud5_t {
+ H5SL_t *map_list; /* skip list to map copied object addresses */
+ haddr_t heap_addr; /* heap address of the source symbol table */
+ H5G_entry_t *loc_dst; /* group where new object is inserted to */
+} H5G_bt_it_ud5_t;
+
/*
* This is the class identifier to give to the B-tree functions.
*/
@@ -187,6 +197,9 @@ H5_DLL herr_t H5G_stab_insert(H5G_entry_t *grp_ent, const char *name,
H5G_entry_t *obj_ent, hbool_t inc_link, hid_t dxpl_id);
H5_DLL herr_t H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab, hbool_t adj_link);
H5_DLL herr_t H5G_stab_remove(H5G_entry_t *grp_ent, const char *name, hid_t dxpl_id);
+H5_DLL herr_t H5G_stab_copy_tmp(H5F_t *f_dst, H5O_stab_t *stab_dst,
+ hid_t dxpl_id);
+
/*
* Functions that understand symbol table entries.
@@ -206,4 +219,7 @@ H5_DLL int H5G_node_name(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t a
const void *_rt_key, void *_udata);
H5_DLL int H5G_node_type(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
const void *_rt_key, void *_udata);
+H5_DLL int H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
+ const void *_rt_key, void *_udata);
+
#endif
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index 2f82536..1a7807a 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -14,15 +14,13 @@
/*-------------------------------------------------------------------------
*
- * Created: H5Gproto.h
+ * Created: H5Gpublic.h
* Jul 11 1997
* Robb Matzke <matzke@llnl.gov>
*
* Purpose: Public declarations for the H5G package (symbol
* tables).
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
#ifndef _H5Gpublic_H
@@ -123,6 +121,8 @@ H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize,
char *buf);
H5_DLL hid_t H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id,
hid_t gapl_id);
+H5_DLL herr_t H5Gcopy(hid_t id_src, hid_t loc_dst, const char *name_dst,
+ hid_t plist_id);
#ifdef __cplusplus
}
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index 8c83859..b63e1cd 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -315,3 +315,50 @@ H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab, hbool_t adj_lin
done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5G_stab_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_copy_tmp
+ *
+ * Purpose: copy a group symbol table and memeber objects from SRC file to DST file.
+ *
+ * Return: Non-negative on success
+ * Negative on failure.
+ *
+ * Programmer: Peter Cao
+ * September 10, 2005
+ *
+ * Note: This routine should be replaced with proper call to "real"
+ * stab creation routine after the "big group revision" checkin
+ * occurs. -QAK
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_copy_tmp(H5F_t *f_dst, H5O_stab_t *stab_dst, hid_t dxpl_id)
+{
+ size_t size_init, name_offset;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_copy_tmp, FAIL)
+
+ HDassert(f_dst);
+ HDassert(stab_dst);
+
+ /* create B-tree private heap */
+ size_init = MAX(H5G_SIZE_HINT, H5HL_SIZEOF_FREE(f_dst) + 2);
+ if (H5HL_create(f_dst, dxpl_id, size_init, &(stab_dst->heap_addr))<0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap")
+
+ name_offset = H5HL_insert(f_dst, dxpl_id, stab_dst->heap_addr, 1, "");
+ if ((size_t)(-1)==name_offset)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap")
+ assert(0 == name_offset);
+
+ /* create the B-tree */
+ if (H5B_create(f_dst, dxpl_id, H5B_SNODE, NULL, &(stab_dst->btree_addr)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_copy_tmp() */
diff --git a/src/H5O.c b/src/H5O.c
index 2a3f39c..7522b4a 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -64,6 +64,12 @@ typedef struct {
typedef herr_t (*H5O_operator_int_t)(H5O_mesg_t *mesg/*in,out*/, unsigned idx,
unsigned * oh_flags_ptr, void *operator_data/*in,out*/);
+/* Node in skip list to map addresses from one file to another during object header copy */
+typedef struct H5O_addr_map_t {
+ haddr_t src_addr; /* Address of object in source file */
+ haddr_t dst_addr; /* Address of object in destination file */
+} H5O_addr_map_t;
+
/* PRIVATE PROTOTYPES */
static herr_t H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5G_entry_t *ent/*out*/, haddr_t header);
@@ -107,6 +113,14 @@ static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
unsigned * oh_flags_ptr);
static herr_t H5O_iterate_real(const H5G_entry_t *ent, const H5O_class_t *type,
H5AC_protect_t prot, hbool_t internal, void *op, void *op_data, hid_t dxpl_id);
+static void * H5O_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
+ void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
+static herr_t H5O_post_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
+ const void *mesg_src, H5G_entry_t *loc_dst,
+ hid_t dxpl_id, H5SL_t *map_list);
+static herr_t H5O_copy_header_real(const H5G_entry_t *ent_src,
+ H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list);
+static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
/* Metadata cache callbacks */
static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
@@ -153,6 +167,8 @@ static const H5O_class_t *const message_type_g[] = {
H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
};
+/* Library private variables */
+
/*
* An array of functions indexed by symbol table entry cache type
* (H5G_type_t) that are called to retrieve constant messages cached in the
@@ -180,6 +196,9 @@ H5FL_EXTERN(time_t);
/* Declare extern the free list for H5O_cont_t's */
H5FL_EXTERN(H5O_cont_t);
+/* Declare a free list to manage the H5O_addr_map_t struct */
+H5FL_DEFINE_STATIC(H5O_addr_map_t);
+
/*-------------------------------------------------------------------------
* Function: H5O_init_interface
@@ -584,12 +603,8 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
p += 3; /*reserved*/
/* Try to detect invalidly formatted object header messages */
- if (p + mesg_size > oh->chunk[chunkno].image + chunk_size) {
-
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, \
- "corrupt object header");
- }
-
+ if (p + mesg_size > oh->chunk[chunkno].image + chunk_size)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "corrupt object header");
/* Skip header messages we don't know about */
/* (Usually from future versions of the library */
@@ -680,7 +695,6 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
int id;
unsigned u;
H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- H5O_cont_t *cont = NULL;
herr_t (*encode)(H5F_t*, uint8_t*, const void*) = NULL;
unsigned combine=0; /* Whether to combine the object header prefix & the first chunk */
herr_t ret_value=SUCCEED; /* Return value */
@@ -2259,8 +2273,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large (16k max)");
/* Allocate space in the object headed for the message */
- if ((ret_value = H5O_alloc(f, dxpl_id, oh,
- orig_type, size, oh_flags_ptr)) == UFAIL)
+ if ((ret_value = H5O_alloc(f, dxpl_id, oh, orig_type, size, oh_flags_ptr)) == UFAIL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "unable to allocate space for message");
/* Increment any links in message */
@@ -3045,8 +3058,8 @@ H5O_alloc_new_chunk(H5F_t *f,
H5O_cont_t *cont = NULL; /*native continuation message */
int chunkno;
unsigned u;
- unsigned ret_value; /*return value */
haddr_t new_chunk_addr;
+ unsigned ret_value; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_new_chunk);
@@ -3088,10 +3101,8 @@ H5O_alloc_new_chunk(H5F_t *f,
* message, then make sure the new chunk has enough room for that
* other message.
*/
- if ( found_null < 0 ) {
-
+ if (found_null < 0)
size += H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
- }
/*
* The total chunk size must include the requested space plus enough
@@ -3103,11 +3114,8 @@ H5O_alloc_new_chunk(H5F_t *f,
/* allocate space in file to hold the new chunk */
new_chunk_addr = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id, (hsize_t)size);
- if ( HADDR_UNDEF == new_chunk_addr ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, \
- "unable to allocate space for new chunk");
- }
+ if(HADDR_UNDEF == new_chunk_addr)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "unable to allocate space for new chunk")
/*
* Create the new chunk giving it a file address.
@@ -3117,11 +3125,8 @@ H5O_alloc_new_chunk(H5F_t *f,
unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
- if ( !x ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, \
- "memory allocation failed");
- }
+ if (!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
oh->alloc_nchunks = na;
oh->chunk = x;
}
@@ -3142,11 +3147,8 @@ H5O_alloc_new_chunk(H5F_t *f,
unsigned na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3);
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, (size_t)na);
- if ( !x ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, \
- "memory allocation failed");
- }
+ if (!x)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
oh->alloc_nmesgs = na;
oh->mesg = x;
@@ -3211,11 +3213,8 @@ H5O_alloc_new_chunk(H5F_t *f,
*/
oh->mesg[found_null].type = H5O_CONT;
oh->mesg[found_null].dirty = TRUE;
- if (NULL==(cont = H5FL_MALLOC(H5O_cont_t))) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, \
- "memory allocation failed");
- }
+ if (NULL==(cont = H5FL_MALLOC(H5O_cont_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
cont->addr = oh->chunk[chunkno].addr;
cont->size = oh->chunk[chunkno].size;
cont->chunkno = chunkno;
@@ -3226,7 +3225,6 @@ H5O_alloc_new_chunk(H5F_t *f,
done:
FUNC_LEAVE_NOAPI(ret_value);
-
} /* H5O_alloc_new_chunk() */
@@ -3270,7 +3268,7 @@ H5O_alloc(H5F_t *f,
size_t size,
unsigned * oh_flags_ptr)
{
- unsigned idx = UFAIL;
+ unsigned idx;
H5O_mesg_t *msg; /* Pointer to newly allocated message */
size_t aligned_size = H5O_ALIGN(size);
htri_t tri_result;
@@ -3310,8 +3308,7 @@ H5O_alloc(H5F_t *f,
* Note that in this new version of this function, all chunks
* must have file space allocated to them.
*/
- for ( chunkno = 0; chunkno < oh->nchunks; chunkno++ )
- {
+ for (chunkno = 0; chunkno < oh->nchunks; chunkno++) {
HDassert( H5F_addr_defined(oh->chunk[chunkno].addr) );
tri_result = H5O_alloc_extend_chunk(f, oh, chunkno, size, &idx);
@@ -3334,13 +3331,9 @@ H5O_alloc(H5F_t *f,
/* if idx is still UFAIL, we were not able to extend a chunk.
* Create a new one.
*/
- if (idx == UFAIL) {
-
- if ( (idx = H5O_alloc_new_chunk(f, dxpl_id, oh, size)) == UFAIL ) {
-
- HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, \
- "unable to create a new object header data chunk");
- }
+ if(idx == UFAIL) {
+ if((idx = H5O_alloc_new_chunk(f, dxpl_id, oh, size)) == UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, "unable to create a new object header data chunk")
}
}
@@ -3349,35 +3342,26 @@ H5O_alloc(H5F_t *f,
/* do we need to split the null message? */
if (msg->raw_size > aligned_size) {
-
H5O_mesg_t *null_msg; /* Pointer to null message */
+ size_t mesg_size = aligned_size+ H5O_SIZEOF_MSGHDR(f); /* Total size of newly allocated message */
- size_t mesg_size = aligned_size + H5O_SIZEOF_MSGHDR(f);
- /* Total size of newly allocated message */
-
- HDassert( msg->raw_size - aligned_size >= H5O_SIZEOF_MSGHDR(f) );
+ HDassert(msg->raw_size - aligned_size >= H5O_SIZEOF_MSGHDR(f));
if (oh->nmesgs >= oh->alloc_nmesgs) {
-
int old_alloc=oh->alloc_nmesgs;
unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
- if (!x) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, \
- "memory allocation failed");
- }
- oh->alloc_nmesgs = na;
- oh->mesg = x;
+ if (!x)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
+ oh->alloc_nmesgs = na;
+ oh->mesg = x;
/* Set new object header info to zeros */
HDmemset(&oh->mesg[old_alloc],0,
(oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
- /* "Retarget" local 'msg' pointer into newly allocated array
- * of messages
- */
+ /* "Retarget" local 'msg' pointer into newly allocated array of messages */
msg=&oh->mesg[idx];
}
null_msg = &(oh->mesg[oh->nmesgs++]);
@@ -3402,7 +3386,6 @@ H5O_alloc(H5F_t *f,
done:
FUNC_LEAVE_NOAPI(ret_value);
-
} /* H5O_alloc() */
#ifdef NOT_YET
@@ -4078,6 +4061,432 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_copy_mesg_file
+ *
+ * Purpose: Copies a message to file. If MESG is is the null pointer then a null
+ * pointer is returned with no error.
+ *
+ * Return: Success: Ptr to the new message
+ *
+ * Failure: NULL
+ *
+ * Programmer: Peter Cao
+ * June 4, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
+ void *native_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata)
+{
+ void *ret_value;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_copy_mesg_file)
+
+ /* check args */
+ HDassert(type);
+ HDassert(type->copy_file);
+ HDassert(file_src);
+ HDassert(native_src);
+ HDassert(file_dst);
+ HDassert(map_list);
+
+ if(NULL == (ret_value = (type->copy_file)(file_src, native_src, file_dst, dxpl_id, map_list, udata)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy object header message to file")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_mesg_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_post_copy_mesg_file
+ *
+ * Purpose: Copies what's left to file after the object a meesage is copied.
+ * This function is need for situations like copying symbol tables.
+ * Copying a member of symbol table requires the parent object header
+ * exists in file. For this case, the first round of the message will
+ * create symbol table enttries but will not go deep copying member
+ * objects in the symbol table. The post copy will do that.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * September 28, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_post_copy_mesg_file (const H5O_class_t *type, H5F_t *file_src,
+ const void *mesg_src, H5G_entry_t *loc_dst,
+ hid_t dxpl_id, H5SL_t *map_list)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_post_copy_mesg_file)
+
+ /* check args */
+ HDassert(type);
+ HDassert(file_src);
+ HDassert(mesg_src);
+ HDassert(loc_dst->file);
+ HDassert(map_list);
+
+ if(type->post_copy_file && (type->post_copy_file)(file_src, mesg_src, loc_dst, dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy object header message to file")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_post_copy_mesg_file */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_header_real
+ *
+ * Purpose: copy header object from one location to another.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * May 30, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_copy_header_real(const H5G_entry_t *ent_src,
+ H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
+{
+ H5O_addr_map_t *addr_map; /* Address mapping of object copied */
+ uint8_t buf[16], *p;
+ H5O_t *oh = NULL;
+ unsigned chunkno = 0, mesgno = 0;
+ size_t chunk_size, hdr_size;
+ haddr_t addr_new;
+ H5O_mesg_t *mesg_src;
+ H5O_chunk_t *chunk;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_copy_header_real)
+
+ HDassert(ent_src);
+ HDassert(ent_src->file);
+ HDassert(H5F_addr_defined(ent_src->header));
+ HDassert(ent_dst->file);
+ HDassert(map_list);
+
+ if(NULL == (oh = H5AC_protect(ent_src->file, dxpl_id, H5AC_OHDR, ent_src->header, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* get the size of the file header of the destination file */
+ hdr_size = H5O_SIZEOF_HDR(ent_dst->file);
+
+ /* allocate memory space for the destitnation chunks */
+ if(NULL == (chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->nchunks)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Allocate space for the first chunk */
+ if(HADDR_UNDEF == (addr_new = H5MF_alloc(ent_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + oh->chunk[0].size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
+
+ /* Return the first chunk address */
+ ent_dst->header = addr_new;
+
+ /* Set chunk's address */
+ chunk[0].addr = addr_new + (hsize_t)hdr_size;
+
+ /* Encode header information */
+ p = buf;
+
+ /* encode version */
+ *p++ = H5O_VERSION;
+
+ /* reserved */
+ *p++ = 0;
+
+ /* encode number of messages */
+ UINT16ENCODE(p, oh->nmesgs);
+
+ /* encode link count (at zero initially) */
+ UINT32ENCODE(p, 0);
+
+ /* encode body size */
+ UINT32ENCODE(p, oh->chunk[0].size);
+
+ /* zero to alignment */
+ HDmemset(p, 0, (size_t)(hdr_size-12));
+
+ /* need to allocate all the chunks for the destination before copy the chunk message
+ because continuation chunk message will need to know the chunk address of address of
+ continuation block.
+ */
+ for(chunkno = 1; chunkno < oh->nchunks; chunkno++) {
+ if(HADDR_UNDEF == (chunk[chunkno].addr = H5MF_alloc(ent_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)oh->chunk[chunkno].size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
+ } /* end for */
+
+ /* Loop through chunks to copy chunk information */
+ for(chunkno = 0; chunkno < oh->nchunks; chunkno++) {
+ chunk_size = oh->chunk[chunkno].size;
+
+ /* copy chunk information */
+ chunk[chunkno].dirty = oh->chunk[chunkno].dirty;
+ chunk[chunkno].size = chunk_size;
+
+ /* create memory image for the new chunk */
+ if(NULL == (chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image,chunk_size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* copy the chunk image from source to destination in memory */
+ /* (This copies over all the messages which don't require special
+ * callbacks to fix them up.)
+ */
+ HDmemcpy(chunk[chunkno].image, oh->chunk[chunkno].image, chunk_size);
+
+ /* Loop through messages, to fix up any which refer to addresses in the source file, etc. */
+ for(mesgno = 0; mesgno < oh->nmesgs; mesgno++) {
+ const H5O_class_t *copy_type;
+
+ mesg_src = &(oh->mesg[mesgno]);
+
+ /* check if the message belongs to this chunk */
+ if(mesg_src->chunkno != chunkno)
+ continue;
+
+ if (mesg_src->flags & H5O_FLAG_SHARED)
+ copy_type = H5O_SHARED;
+ else
+ copy_type = mesg_src->type;
+
+ /* copy this message into destination file */
+ HDassert(copy_type);
+ if(copy_type->copy_file) {
+ void *dst_native; /* Pointer to copy of native information for current message */
+
+ /*
+ * Decode the message if necessary. If the message is shared then d
+ * a shared message, ignoring the message type.
+ */
+ if(NULL == mesg_src->native) {
+ /* Decode the message if necessary */
+ HDassert(copy_type->decode);
+ if(NULL == (mesg_src->native = (copy_type->decode)(ent_src->file, dxpl_id, mesg_src->raw, NULL)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode a message")
+ } /* end if (NULL == mesg_src->native) */
+
+ /* Copy the source message */
+ if(H5O_CONT_ID == copy_type->id) {
+ if((dst_native = H5O_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
+ ent_dst->file, dxpl_id, map_list, chunk)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
+ } /* end if */
+ else {
+ if((dst_native = H5O_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
+ ent_dst->file, dxpl_id, map_list, NULL)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
+ } /* end else */
+
+ /* Calculate address in destination raw chunk */
+ p = chunk[chunkno].image + (mesg_src->raw - oh->chunk[chunkno].image);
+
+ /*
+ * Encode the message. If the message is shared then we
+ * encode a Shared Object message instead of the object
+ * which is being shared.
+ */
+ if((copy_type->encode)(ent_dst->file, p, dst_native) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
+
+ /* Release native destination info */
+ H5O_free_real(copy_type, dst_native);
+ } /* end if (mesg_src->type && mesg_src->type->copy_file) */
+ } /* end of mesgno loop */
+
+ /* Write the object header to the file if this is the first chunk */
+ if(chunkno == 0)
+ if(H5F_block_write(ent_dst->file, H5FD_MEM_OHDR, addr_new, hdr_size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk")
+
+ /* Write this chunk into disk */
+ if(H5F_block_write(ent_dst->file, H5FD_MEM_OHDR, chunk[chunkno].addr, chunk[chunkno].size, dxpl_id, chunk[chunkno].image) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk")
+ } /* end of chunkno loop */
+
+ /* Allocate space for the address mapping of the object copied */
+ if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Insert the address mapping for the new object into the copied list */
+ /* (Do this here, because "post copy" possibly checks it) */
+ addr_map->src_addr = ent_src->header;
+ addr_map->dst_addr = ent_dst->header;
+ if(H5SL_insert(map_list, addr_map, &(addr_map->src_addr)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
+
+ /* "post copy" loop over messages */
+ for(mesgno = 0; mesgno < oh->nmesgs; mesgno++) {
+ const H5O_class_t *copy_type;
+
+ mesg_src = &(oh->mesg[mesgno]);
+
+ if (mesg_src->flags & H5O_FLAG_SHARED)
+ copy_type = H5O_SHARED;
+ else
+ copy_type = mesg_src->type;
+
+ HDassert(copy_type);
+ if(mesg_src->native) {
+ if((H5O_post_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
+ ent_dst, dxpl_id, map_list)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
+ } /* end if */
+ } /* end for */
+
+done:
+ /* Release pointer to object header itself */
+ if(oh != NULL) {
+ for(chunkno = 0; chunkno < oh->nchunks; chunkno++)
+ H5FL_BLK_FREE(chunk_image, chunk[chunkno].image);
+ H5FL_SEQ_FREE(H5O_chunk_t, chunk);
+
+ if(H5AC_unprotect(ent_src->file, dxpl_id, H5AC_OHDR, ent_src->header, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_header_real() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_header_map
+ *
+ * Purpose: Copy header object from one location to another, detecting
+ * already mapped objects, etc.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * November 1, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_copy_header_map(const H5G_entry_t *ent_src,
+ H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
+{
+ H5O_addr_map_t *addr_map; /* Address mapping of object copied */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5O_copy_header_map, FAIL)
+
+ /* Sanity check */
+ HDassert(ent_src);
+ HDassert(ent_dst);
+ HDassert(ent_dst->file);
+ HDassert(map_list);
+
+ /* Look up the address of the object to copy in the skip list */
+ addr_map = (H5O_addr_map_t *)H5SL_search(map_list, &(ent_src->header));
+
+ /* Check if address is already in list of objects copied */
+ if(addr_map == NULL) {
+ /* Copy object for the first time */
+
+ /* Copy object referred to */
+ if(H5O_copy_header_real(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+ } /* end if */
+ else {
+ /* Object has already been copied, set it's address in destination file */
+ ent_dst->header = addr_map->dst_addr;
+ } /* end else */
+
+ /* Increment destination object's link count */
+ if(H5O_link(ent_dst, 1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to increment object link count")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_header_map() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5O_copy_free_addrmap_cb
+ PURPOSE
+ Internal routine to free address maps from the skip list for copying objects
+ USAGE
+ herr_t H5O_copy_free_addrmap_cb(item, key, op_data)
+ void *item; IN/OUT: Pointer to addr
+ void *key; IN/OUT: (unused)
+ void *op_data; IN: (unused)
+ RETURNS
+ Returns zero on success, negative on failure.
+ DESCRIPTION
+ Releases the memory for the address.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static herr_t
+H5O_copy_free_addrmap_cb(void *item, void UNUSED *key, void UNUSED *op_data)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_copy_free_addrmap_cb)
+
+ HDassert(item);
+
+ /* Release the item */
+ H5FL_FREE(H5O_addr_map_t, item);
+
+ FUNC_LEAVE_NOAPI(0)
+} /* H5O_copy_free_addrmap_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_copy_header
+ *
+ * Purpose: copy header object from one location to another.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * May 30, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_copy_header(const H5G_entry_t *ent_src,
+ H5G_entry_t *ent_dst /*out */, hid_t dxpl_id)
+{
+ H5SL_t *map_list = NULL; /* Skip list to hold address mappings */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5O_copy_header, FAIL)
+
+ HDassert(ent_src);
+ HDassert(ent_src->file);
+ HDassert(H5F_addr_defined(ent_src->header));
+ HDassert(ent_dst->file);
+
+ /* Create a skip list to keep track of which objects are copied */
+ if((map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, 16)) == NULL)
+ HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
+
+ /* copy the object from the source file to the destination file */
+ if(H5O_copy_header_real(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+done:
+ if(map_list)
+ H5SL_destroy(map_list, H5O_copy_free_addrmap_cb, NULL);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_copy_header() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_debug_id
*
* Purpose: Act as a proxy for calling the 'debug' method for a
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index abff4f3..9ac5570 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -35,6 +35,8 @@ static herr_t H5O_attr_reset (void *_mesg);
static herr_t H5O_attr_free (void *mesg);
static herr_t H5O_attr_delete (H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static herr_t H5O_attr_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
+static void *H5O_attr_copy_file(H5F_t *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_attr_debug (H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -53,7 +55,9 @@ const H5O_class_t H5O_ATTR[1] = {{
H5O_attr_link, /* link method */
NULL, /* get share method */
NULL, /* set share method */
- H5O_attr_debug, /* debug the message */
+ H5O_attr_copy_file, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_attr_debug /* debug the message */
}};
/* This is the initial version, which does not have support for shared datatypes */
@@ -65,12 +69,6 @@ const H5O_class_t H5O_ATTR[1] = {{
/* Flags for attribute flag encoding */
#define H5O_ATTR_FLAG_TYPE_SHARED 0x01
-/* Declare extern the free list for H5A_t's */
-H5FL_EXTERN(H5A_t);
-
-/* Declare extern the free list for attribute data buffers */
-H5FL_BLK_EXTERN(attr_buf);
-
/* Declare external the free list for H5S_t's */
H5FL_EXTERN(H5S_t);
@@ -595,6 +593,95 @@ done:
} /* end H5O_attr_link() */
+/*-------------------------------------------------------------------------
+ * Function: H5O_attr_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * November 1, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void UNUSED *udata)
+{
+ H5A_t *attr_src = (H5A_t *)native_src;
+ H5A_t *attr_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_copy_file)
+
+ /* check args */
+ HDassert(attr_src);
+ HDassert(file_dst);
+ HDassert(map_list);
+
+ /* Allocate space for the destination message */
+ if(NULL == (attr_dst = H5FL_CALLOC(H5A_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy the top level of the attribute */
+ *attr_dst = *attr_src;
+
+ /* Don't have an opened group entry for copy */
+ H5G_ent_reset(&(attr_dst->ent));
+ attr_dst->ent_opened = 0;
+
+ /* Copy attribute's name */
+ attr_dst->name = H5MM_strdup(attr_src->name);
+
+ /* Copy attribute's datatype */
+ /* (Start destination datatype as transient, even if source is named) */
+ attr_dst->dt = H5T_copy(attr_src->dt, H5T_COPY_ALL);
+
+ /* Check for named datatype being copied */
+ if(H5T_committed(attr_src->dt)) {
+ H5G_entry_t *ent_src; /* Pointer to source datatype's group entry */
+ H5G_entry_t *ent_dst; /* Pointer to dest. datatype's group entry */
+
+ /* Get group entries for source & destination */
+ ent_src = H5T_entof(attr_src->dt);
+ HDassert(ent_src);
+ ent_dst = H5T_entof(attr_dst->dt);
+ HDassert(ent_dst);
+
+ /* Reset group entry for new object */
+ H5G_ent_reset(ent_dst);
+ ent_dst->file = file_dst;
+
+ /* Copy the shared object from source to destination */
+ if(H5O_copy_header_map(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
+ } /* end if */
+
+ /* Copy the guts of the attribute */
+ attr_dst->ds = H5S_copy(attr_src->ds, FALSE);
+
+ if(attr_src->data) {
+ if(NULL == (attr_dst->data = H5FL_BLK_MALLOC(attr_buf, attr_src->data_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ HDmemcpy(attr_dst->data, attr_src->data, attr_src->data_size);
+ } /* end if */
+
+ /* Set return value */
+ ret_value = attr_dst;
+
+done:
+ if(!ret_value)
+ if(attr_dst)
+ (void)H5A_free(attr_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_attr_copy_file() */
+
+
/*--------------------------------------------------------------------------
NAME
H5O_attr_debug
diff --git a/src/H5Obogus.c b/src/H5Obogus.c
index 54a52b2..7296860 100644
--- a/src/H5Obogus.c
+++ b/src/H5Obogus.c
@@ -60,7 +60,9 @@ const H5O_class_t H5O_BOGUS[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_bogus_debug, /*debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_bogus_debug /*debug the message */
}};
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index e62ca07..afa5ab7 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -42,6 +42,8 @@ static void *H5O_cont_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shar
static herr_t H5O_cont_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static size_t H5O_cont_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_cont_free(void *mesg);
+static void *H5O_cont_copy_file(H5F_t *file_src, void *mesg_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_cont_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -60,7 +62,9 @@ const H5O_class_t H5O_CONT[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_cont_debug, /*debugging */
+ H5O_cont_copy_file, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_cont_debug /*debugging */
}};
/* Declare the free list for H5O_cont_t's */
@@ -209,6 +213,54 @@ H5O_cont_free (void *mesg)
/*-------------------------------------------------------------------------
+ * Function: H5O_cont_copy_file
+ *
+ * Purpose: Copies a continuation block message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Peter Cao
+ * September 22, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_cont_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
+ H5F_t *file_dst, hid_t UNUSED dxpl_id, H5SL_t UNUSED *map_list, void *udata)
+{
+ H5O_cont_t *cont_src = (H5O_cont_t *) mesg_src;
+ H5O_chunk_t *chunk = (H5O_chunk_t *)udata;
+ H5O_cont_t *cont_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_cont_copy_file)
+
+ /* check args */
+ HDassert(cont_src);
+ HDassert(file_dst);
+
+ /* Allocate space for the destination cont */
+ if(NULL == (cont_dst = H5FL_MALLOC(H5O_cont_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ HDmemcpy(cont_dst, cont_src, sizeof(H5O_cont_t));
+ cont_dst->addr = chunk[cont_src->chunkno].addr;
+
+ /* Set return value */
+ ret_value = cont_dst;
+
+done:
+ if(!ret_value)
+ if(cont_dst)
+ H5FL_FREE(H5O_cont_t, cont_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_cont_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_cont_debug
*
* Purpose: Prints debugging info.
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 0eed438..05ca879 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -53,7 +53,9 @@ const H5O_class_t H5O_DTYPE[1] = {{
NULL, /* link method */
H5O_dtype_get_share, /* get share method */
H5O_dtype_set_share, /* set share method */
- H5O_dtype_debug, /* debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_dtype_debug /* debug the message */
}};
/* This is the correct version to create all datatypes which don't contain
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 9106310..8c78cae 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -33,6 +33,8 @@ static herr_t H5O_efl_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_efl_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_efl_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_efl_reset(void *_mesg);
+static void *H5O_efl_copy_file(H5F_t *file_src, void *mesg_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_efl_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -51,7 +53,9 @@ const H5O_class_t H5O_EFL[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_efl_debug, /*debug the message */
+ H5O_efl_copy_file, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_efl_debug /*debug the message */
}};
#define H5O_EFL_VERSION 1
@@ -415,6 +419,86 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_efl_copy_file
+ *
+ * Purpose: Copies an efl message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Peter Cao
+ * September 29, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_efl_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t UNUSED *map_list, void UNUSED *_udata)
+{
+ H5O_efl_t *efl_src = (H5O_efl_t *) mesg_src;
+ H5O_efl_t *efl_dst = NULL;
+ size_t idx, size, name_offset, heap_size;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_efl_copy_file)
+
+ /* check args */
+ HDassert(efl_src);
+ HDassert(file_dst);
+
+ /* Allocate space for the destination efl */
+ if(NULL == (efl_dst = H5MM_calloc(sizeof(H5O_efl_t))))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy the "top level" information */
+ HDmemcpy(efl_dst, efl_src, sizeof(H5O_efl_t));
+
+ /* create name heap */
+ heap_size = H5HL_ALIGN(1);
+ for(idx = 0; idx < efl_src->nused; idx++)
+ heap_size += H5HL_ALIGN(HDstrlen(efl_src->slot[idx].name) + 1);
+
+ if(H5HL_create(file_dst, dxpl_id, heap_size, &efl_dst->heap_addr/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create heap")
+
+ name_offset = H5HL_insert(file_dst, dxpl_id, efl_dst->heap_addr, 1, "");
+ if((size_t)(-1) == name_offset)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't initialize heap")
+ HDassert(0 == name_offset);
+
+ /* allocate array of external file entries */
+ if(efl_src->nalloc > 0) {
+ size = efl_src->nalloc * sizeof(H5O_efl_entry_t);
+ if((efl_dst->slot = H5MM_calloc(size)) == NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* copy content from the source. Need to update later */
+ HDmemcpy(efl_dst->slot, efl_src->slot, size);
+ }
+
+ /* copy the name from the source */
+ for(idx = 0; idx < efl_src->nused; idx++) {
+ efl_dst->slot[idx].name = H5MM_xstrdup(efl_src->slot[idx].name);
+ efl_dst->slot[idx].name_offset = H5HL_insert(file_dst, dxpl_id, efl_dst->heap_addr,
+ HDstrlen(efl_dst->slot[idx].name)+1, efl_dst->slot[idx].name);
+ }
+
+ /* Set return value */
+ ret_value = efl_dst;
+
+done:
+ if(!ret_value)
+ if(efl_dst)
+ H5MM_xfree(efl_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_efl_debug
*
* Purpose: Prints debugging info for a message.
@@ -475,3 +559,4 @@ H5O_efl_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * s
FUNC_LEAVE_NOAPI(SUCCEED);
}
+
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index d0bf381..b68c106 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -63,7 +63,9 @@ const H5O_class_t H5O_FILL[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_fill_debug, /*debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_fill_debug /*debug the message */
}};
/* This message derives from H5O, for new fill value after version 1.4 */
@@ -81,7 +83,9 @@ const H5O_class_t H5O_FILL_NEW[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_fill_new_debug, /*debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_fill_new_debug /*debug the message */
}};
/* Initial version of the "old" fill value information */
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 4a6fdfe..3103053 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -18,16 +18,18 @@
* Purpose: Messages related to data layout.
*/
+#define H5D_PACKAGE /*suppress error about including H5Dpkg */
#define H5O_PACKAGE /*suppress error about including H5Opkg */
-#include "H5private.h"
-#include "H5Dprivate.h"
-#include "H5Eprivate.h"
-#include "H5FLprivate.h" /*Free Lists */
+#include "H5private.h" /* Generic Functions */
+#include "H5Dpkg.h" /* Dataset functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5MFprivate.h" /* File space management */
-#include "H5MMprivate.h"
-#include "H5Opkg.h" /* Object header functions */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Opkg.h" /* Object headers */
+#include "H5Pprivate.h" /* Property lists */
/* PRIVATE PROTOTYPES */
static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
@@ -37,6 +39,8 @@ static size_t H5O_layout_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_layout_reset(void *_mesg);
static herr_t H5O_layout_free(void *_mesg);
static herr_t H5O_layout_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
+static void *H5O_layout_copy_file(H5F_t *file_src, void *mesg_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_layout_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
int indent, int fwidth);
@@ -55,7 +59,9 @@ const H5O_class_t H5O_LAYOUT[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_layout_debug, /*debug the message */
+ H5O_layout_copy_file, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_layout_debug /*debug the message */
}};
/* For forward and backward compatibility. Version is 1 when space is
@@ -599,6 +605,113 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_layout_copy_file
+ *
+ * Purpose: Copies a data layout message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Peter Cao
+ * July 23, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_layout_copy_file(H5F_t *file_src, void *mesg_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t UNUSED *map_list, void UNUSED *_udata)
+{
+ H5O_layout_t *layout_src = (H5O_layout_t *) mesg_src;
+ H5O_layout_t *layout_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_layout_copy_file)
+
+ /* check args */
+ HDassert(layout_src);
+ HDassert(file_dst);
+
+ /* Allocate space for the destination layout */
+ if(NULL == (layout_dst = H5FL_MALLOC(H5O_layout_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy the "top level" information */
+ HDmemcpy(layout_dst, layout_src, sizeof(H5O_layout_t));
+
+ /* Copy the layout type specific information */
+ switch(layout_src->type) {
+ case H5D_COMPACT:
+ if(layout_src->u.compact.buf) {
+ if(NULL == (layout_dst->u.compact.buf = H5MM_malloc(layout_src->u.compact.size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset")
+ HDmemcpy(layout_dst->u.compact.buf, layout_src->u.compact.buf, layout_src->u.compact.size);
+ layout_dst->u.compact.dirty = TRUE;
+ }
+ break;
+
+ case H5D_CONTIGUOUS:
+ if(H5F_addr_defined(layout_src->u.contig.addr)) {
+ haddr_t addr_src, addr_dst;
+ unsigned DRAW_BUF_SIZE = 4096;
+ uint8_t buf[4096];
+ size_t nbytes=0, total_nbytes=0;
+
+ /* create layout */
+ if(H5D_contig_create (file_dst, dxpl_id, layout_dst)<0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to initialize contiguous storage")
+
+ /* copy raw data*/
+ nbytes = total_nbytes = 0;
+ while(total_nbytes < layout_src->u.contig.size) {
+ addr_src = layout_src->u.contig.addr + total_nbytes;
+ addr_dst = layout_dst->u.contig.addr + total_nbytes;
+
+ nbytes = layout_src->u.contig.size-total_nbytes;
+ if(nbytes > DRAW_BUF_SIZE)
+ nbytes = DRAW_BUF_SIZE;
+ total_nbytes += nbytes;
+
+ if(H5F_block_read(file_src, H5FD_MEM_DRAW, addr_src, nbytes, H5P_DATASET_XFER_DEFAULT, buf)<0)
+ HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read raw data")
+
+ if(H5F_block_write(file_dst, H5FD_MEM_DRAW, addr_dst, nbytes, H5P_DATASET_XFER_DEFAULT, buf)<0)
+ HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to write raw data")
+ }
+ } /* if ( H5F_addr_defined(layout_src->u.contig.addr)) */
+ break;
+
+ case H5D_CHUNKED:
+ if(H5F_addr_defined(layout_src->u.chunk.addr)) {
+
+ /* layout is not created in the destination file, undef btree address */
+ layout_dst->u.chunk.addr = HADDR_UNDEF;
+
+ /* create chunked layout */
+ if(H5D_istore_copy(file_src, layout_src, file_dst, layout_dst, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy chunked storage")
+ } /* if ( H5F_addr_defined(layout_srct->u.chunk.addr)) */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "Invalid layout class");
+ } /* end switch */
+
+ /* Set return value */
+ ret_value=layout_dst;
+
+done:
+ if(!ret_value)
+ if(layout_dst)
+ H5FL_FREE(H5O_layout_t, layout_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_layout_debug
*
* Purpose: Prints debugging info for a message.
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index d3c2f3c..4244733 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -60,7 +60,9 @@ const H5O_class_t H5O_MTIME[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_mtime_debug, /*debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_mtime_debug /*debug the message */
}};
/* This message derives from H5O */
@@ -79,7 +81,9 @@ const H5O_class_t H5O_MTIME_NEW[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_mtime_debug, /*debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_mtime_debug /*debug the message */
}};
/* Current version of new mtime information */
diff --git a/src/H5Oname.c b/src/H5Oname.c
index 64477af..ba4433a 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -57,7 +57,9 @@ const H5O_class_t H5O_NAME[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_name_debug, /*debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_name_debug /*debug the message */
}};
diff --git a/src/H5Onull.c b/src/H5Onull.c
index 028a535..074026e 100644
--- a/src/H5Onull.c
+++ b/src/H5Onull.c
@@ -46,5 +46,7 @@ const H5O_class_t H5O_NULL[1] = {{
NULL, /*no link method */
NULL, /*no get share method */
NULL, /*no set share method */
- NULL, /*no debug method */
+ NULL, /*no copy native value to file */
+ NULL, /*no post copy native value to file */
+ NULL /*no debug method */
}};
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index 83889f6..fdca31a 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -19,8 +19,11 @@
#ifndef _H5Opkg_H
#define _H5Opkg_H
-/* Include private header file */
-#include "H5Oprivate.h" /* Object header functions */
+/* Get package's private header */
+#include "H5Oprivate.h" /* Object headers */
+
+/* Other private headers needed by this file */
+#include "H5SLprivate.h" /* Skip lists */
/*
* Align messages on 8-byte boundaries because we would like to copy the
@@ -69,6 +72,8 @@ typedef struct H5O_class_t {
herr_t (*link)(H5F_t *, hid_t, const void *); /* Increment any links in file reference by this message */
herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*); /* Get shared information */
herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*); /* Set shared information */
+ void *(*copy_file)(H5F_t *, void *, H5F_t *, hid_t, H5SL_t *, void *); /*copy native value to file */
+ herr_t (*post_copy_file)(H5F_t *, const void *, H5G_entry_t *, hid_t, H5SL_t *); /*"post copy" action when copying native value to file */
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
} H5O_class_t;
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 280c8db..391c758 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -54,7 +54,9 @@ const H5O_class_t H5O_PLINE[1] = {{
NULL, /* link method */
NULL, /* get share method */
NULL, /* set share method */
- H5O_pline_debug, /* debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_pline_debug /* debug the message */
}};
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index e3043af..d619806 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -28,16 +28,17 @@
#define _H5Oprivate_H
/* Include the public header file for this API */
-#include "H5Opublic.h" /* Object header functions */
+#include "H5Opublic.h" /* Object header functions */
/* Public headers needed by this file */
-#include "H5Dpublic.h" /* Dataset functions */
-#include "H5Spublic.h" /* Dataspace functions */
+#include "H5Dpublic.h" /* Dataset functions */
+#include "H5Spublic.h" /* Dataspace functions */
/* Private headers needed by this file */
-#include "H5HGprivate.h" /* Global heap functions */
-#include "H5Tprivate.h" /* Datatype functions */
-#include "H5Zprivate.h" /* I/O pipeline filters */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5HGprivate.h" /* Global heap functions */
+#include "H5Tprivate.h" /* Datatype functions */
+#include "H5Zprivate.h" /* I/O pipeline filters */
/* Object header macros */
#define H5O_MIN_SIZE H5O_ALIGN(32) /*min obj header data size */
@@ -249,6 +250,9 @@ typedef struct H5O_stab_t {
typedef herr_t (*H5O_operator_t)(const void *mesg/*in*/, unsigned idx,
void *operator_data/*in,out*/);
+/* Forward declarations for prototype arguments */
+struct H5SL_t;
+
/* General message operators */
H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5G_entry_t *ent/*out*/);
@@ -291,6 +295,10 @@ H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr);
H5_DLL herr_t H5O_get_info(H5G_entry_t *ent, H5O_stat_t *ostat, hid_t dxpl_id);
H5_DLL herr_t H5O_iterate(const H5G_entry_t *ent, unsigned type_id, H5O_operator_t op,
void *op_data, hid_t dxpl_id);
+H5_DLL herr_t H5O_copy_header(const H5G_entry_t *ent_src,
+ H5G_entry_t *ent_dst /*out */, hid_t dxpl_id);
+H5_DLL herr_t H5O_copy_header_map(const H5G_entry_t *ent_src,
+ H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, struct H5SL_t *obj_list);
H5_DLL herr_t H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
int fwidth);
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index cc3beb1..f4c5500 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -49,7 +49,9 @@ const H5O_class_t H5O_SDSPACE[1] = {{
NULL, /* link method */
NULL, /* get share method */
NULL, /* set share method */
- H5O_sdspace_debug, /* debug the message */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_sdspace_debug /* debug the message */
}};
/* Initial version of the "old" data space information */
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 8a0a291..09f273d 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -42,6 +42,8 @@ static void *H5O_shared_copy(const void *_mesg, void *_dest, unsigned update_fla
static size_t H5O_shared_size (const H5F_t*, const void *_mesg);
static herr_t H5O_shared_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static herr_t H5O_shared_link(H5F_t *f, hid_t dxpl_id, const void *_mesg);
+static void *H5O_shared_copy_file(H5F_t *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_shared_debug (H5F_t*, hid_t dxpl_id, const void*, FILE*, int, int);
/* This message derives from H5O */
@@ -59,7 +61,9 @@ const H5O_class_t H5O_SHARED[1] = {{
H5O_shared_link, /*link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_shared_debug, /*debug method */
+ H5O_shared_copy_file, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_shared_debug /*debug method */
}};
/* Old version, with full symbol table entry as link for object header sharing */
@@ -472,6 +476,63 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_shared_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * November 1, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void UNUSED *udata)
+{
+ H5O_shared_t *shared_src = (H5O_shared_t *)native_src;
+ H5O_shared_t *shared_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_copy_file)
+
+ /* check args */
+ HDassert(shared_src);
+ HDassert(file_dst);
+ HDassert(map_list);
+
+ /* Allocate space for the destination message */
+ if(NULL == (shared_dst = H5MM_malloc(sizeof(H5O_shared_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Can't handle copying message in global heap currently */
+ HDassert(!shared_src->in_gh);
+ shared_dst->in_gh = FALSE;
+
+ /* Reset group entry for new object */
+ H5G_ent_reset(&(shared_dst->u.ent));
+ shared_dst->u.ent.file = file_dst;
+
+ /* Copy the shared object from source to destination */
+ if(H5O_copy_header_map(&(shared_src->u.ent), &(shared_dst->u.ent), dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
+
+ /* Set return value */
+ ret_value = shared_dst;
+
+done:
+ if(!ret_value)
+ if(shared_dst)
+ H5MM_xfree(shared_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_shared_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_shared_debug
*
* Purpose: Prints debugging info for the message
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 21391bd..e03d6b1 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -42,8 +42,12 @@ static void *H5O_stab_copy(const void *_mesg, void *_dest, unsigned update_flags
static size_t H5O_stab_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_stab_free(void *_mesg);
static herr_t H5O_stab_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
+static void *H5O_stab_copy_file(H5F_t *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
+static herr_t H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src,
+ H5G_entry_t *loc_dst, hid_t dxpl_id, H5SL_t *map_list);
static herr_t H5O_stab_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
- FILE * stream, int indent, int fwidth);
+ FILE * stream, int indent, int fwidth);
/* This message derives from H5O */
const H5O_class_t H5O_STAB[1] = {{
@@ -60,7 +64,9 @@ const H5O_class_t H5O_STAB[1] = {{
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
- H5O_stab_debug, /*debug the message */
+ H5O_stab_copy_file, /* copy native value to file */
+ H5O_stab_post_copy_file, /* post copy native value to file */
+ H5O_stab_debug /*debug the message */
}};
/* Declare a free list to manage the H5O_stab_t struct */
@@ -337,6 +343,95 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5O_stab_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Peter Cao
+ * September 10, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_stab_copy_file(H5F_t UNUSED *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t UNUSED *map_list, void UNUSED *udata)
+{
+ H5O_stab_t *stab_src = (H5O_stab_t *) native_src;
+ H5O_stab_t *stab_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_stab_copy_file)
+
+ /* check args */
+ HDassert(stab_src);
+ HDassert(file_dst);
+
+ /* Allocate space for the destination stab */
+ if(NULL == (stab_dst = H5FL_MALLOC(H5O_stab_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ if(H5G_stab_copy_tmp(file_dst, stab_dst, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy group symbol table")
+
+ /* Set return value */
+ ret_value = stab_dst;
+
+done:
+ if(!ret_value)
+ if(stab_dst)
+ H5FL_FREE(H5O_stab_t, stab_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_stab_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_stab_post_copy_file
+ *
+ * Purpose: Copies entries of a symbol table message from _MESG to _DEST in file
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Peter Cao
+ * September 28, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src,
+ H5G_entry_t *loc_dst, hid_t dxpl_id, H5SL_t *map_list)
+{
+ H5G_bt_it_ud5_t udata; /* B-tree user data */
+ const H5O_stab_t *stab_src = (const H5O_stab_t *) mesg_src;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_stab_post_copy_file)
+
+ /* check args */
+ HDassert(file_src);
+ HDassert(stab_src);
+ HDassert(loc_dst->file);
+ HDassert(map_list);
+
+ /* Set up B-tree iteration user data */
+ udata.map_list = map_list;
+ udata.heap_addr = stab_src->heap_addr;
+ udata.loc_dst = loc_dst;
+
+ /* Iterate over objects in group, copying them */
+ if((H5B_iterate(file_src, dxpl_id, H5B_SNODE, H5G_node_copy, stab_src->btree_addr, &udata)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_stab_post_copy_file() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_stab_debug
*
* Purpose: Prints debugging info for a symbol table message.
diff --git a/src/H5S.c b/src/H5S.c
index db535f6..4190ca4 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -39,6 +39,7 @@ static herr_t H5S_set_extent_simple (H5S_t *space, unsigned rank,
static htri_t H5S_is_simple(const H5S_t *sdim);
static herr_t H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc);
static H5S_t *H5S_decode(const unsigned char *buf);
+static htri_t H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2);
#ifdef H5S_DEBUG
/* Names of the selection names, for debugging */
@@ -2225,6 +2226,106 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5Sextent_equal
+ *
+ * Purpose: Determines if two dataspace extents are equal.
+ *
+ * Return: Success: TRUE if equal, FALSE if unequal
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 24, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5Sextent_equal(hid_t space1_id, hid_t space2_id)
+{
+ const H5S_t *ds1, *ds2; /* Dataspaces to compare */
+ htri_t ret_value;
+
+ FUNC_ENTER_API(H5Sextent_equal, FAIL)
+ H5TRACE2("t","ii",space1_id,space2_id);
+
+ /* check args */
+ if(NULL == (ds1 = H5I_object_verify(space1_id, H5I_DATASPACE)) ||
+ NULL == (ds2 = H5I_object_verify(space2_id, H5I_DATASPACE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
+
+ /* Check dataspaces for extent's equality */
+ if((ret_value = H5S_extent_equal(ds1, ds2)) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "dataspace comparison failed")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Sextent_equal() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5S_extent_equal
+ PURPOSE
+ Check if two dataspaces have equal extents
+ USAGE
+ htri_t H5S_extent_equal(ds1, ds2)
+ H5S_t *ds1, *ds2; IN: Dataspace objects to compare
+ RETURNS
+ TRUE if equal, FALSE if unequal on succeess/Negative on failure
+ DESCRIPTION
+ Compare two dataspaces if their extents are identical.
+--------------------------------------------------------------------------*/
+static htri_t
+H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2)
+{
+ unsigned u; /* Local index variable */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5S_extent_equal, FAIL)
+
+ /* Check args */
+ HDassert(ds1);
+ HDassert(ds2);
+
+ /* Make certain the dataspaces are the same type */
+ if(ds1->extent.type != ds2->extent.type)
+ HGOTO_DONE(FALSE)
+
+ /* Make certain the dataspaces are the same rank */
+ if(ds1->extent.rank != ds2->extent.rank)
+ HGOTO_DONE(FALSE)
+
+ /* Make certain the dataspaces' current dimensions are the same size */
+ if(ds1->extent.rank > 0) {
+ HDassert(ds1->extent.size);
+ HDassert(ds2->extent.size);
+ for(u = 0; u < ds1->extent.rank; u++) {
+ if(ds1->extent.size[u] != ds2->extent.size[u])
+ HGOTO_DONE(FALSE)
+ } /* end for */
+ } /* end if */
+
+ /* Make certain the dataspaces' maximum dimensions are the same size */
+ if(ds1->extent.rank > 0) {
+ /* Check for no maximum dimensions on dataspaces */
+ if(ds1->extent.max != NULL && ds2->extent.max != NULL) {
+ for(u = 0; u < ds1->extent.rank; u++) {
+ if(ds1->extent.max[u] != ds2->extent.max[u])
+ HGOTO_DONE(FALSE)
+ } /* end for */
+ } /* end if */
+ else
+ if((ds1->extent.max == NULL && ds2->extent.max != NULL) ||
+ (ds1->extent.max != NULL && ds2->extent.max == NULL))
+ HGOTO_DONE(FALSE)
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_extent_equal() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5S_debug
*
* Purpose: Prints debugging information about a data space.
diff --git a/src/H5Shyper.c b/src/H5Shyper.c
index 1f75af4..83bebe9 100644
--- a/src/H5Shyper.c
+++ b/src/H5Shyper.c
@@ -5371,7 +5371,7 @@ H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab
hsize_t curr_start;
hsize_t curr_low;
int outcount;
- int i;
+ unsigned u;
H5S_hyper_dim_t canon_down_span_slab_info[H5S_MAX_RANK];
hbool_t ret_value = TRUE;
@@ -5414,17 +5414,17 @@ H5S_hyper_rebuild_helper(const H5S_hyper_span_t *span, H5S_hyper_dim_t span_slab
/* Compare the slab information of the adjacent spans in the down span tree.
We have to compare all the sub-tree slab information with the canon_down_span_slab_info.*/
- for( i = 0; i < rank - 1; i++) {
- curr_down_span_slab_info = &span_slab_info[i];
+ for( u = 0; u < rank - 1; u++) {
+ curr_down_span_slab_info = &span_slab_info[u];
- if(curr_down_span_slab_info->count > 0 && canon_down_span_slab_info[i].count > 0) {
- if(curr_down_span_slab_info->start != canon_down_span_slab_info[i].start
- || curr_down_span_slab_info->stride != canon_down_span_slab_info[i].stride
- || curr_down_span_slab_info->block != canon_down_span_slab_info[i].block
- || curr_down_span_slab_info->count != canon_down_span_slab_info[i].count)
+ if(curr_down_span_slab_info->count > 0 && canon_down_span_slab_info[u].count > 0) {
+ if(curr_down_span_slab_info->start != canon_down_span_slab_info[u].start
+ || curr_down_span_slab_info->stride != canon_down_span_slab_info[u].stride
+ || curr_down_span_slab_info->block != canon_down_span_slab_info[u].block
+ || curr_down_span_slab_info->count != canon_down_span_slab_info[u].count)
HGOTO_DONE(FALSE)
} /* end if */
- else if (!((curr_down_span_slab_info->count == 0) && (canon_down_span_slab_info[i].count == 0)))
+ else if (!((curr_down_span_slab_info->count == 0) && (canon_down_span_slab_info[u].count == 0)))
HGOTO_DONE(FALSE)
}
} /* end if */
diff --git a/src/H5Spublic.h b/src/H5Spublic.h
index 9efaeab..5e2177f 100644
--- a/src/H5Spublic.h
+++ b/src/H5Spublic.h
@@ -132,6 +132,7 @@ H5_DLL herr_t H5Sselect_elements(hid_t space_id, H5S_seloper_t op,
H5_DLL H5S_class_t H5Sget_simple_extent_type(hid_t space_id);
H5_DLL herr_t H5Sset_extent_none(hid_t space_id);
H5_DLL herr_t H5Sextent_copy(hid_t dst_id,hid_t src_id);
+H5_DLL herr_t H5Sextent_equal(hid_t sid1, hid_t sid2);
H5_DLL herr_t H5Sselect_all(hid_t spaceid);
H5_DLL herr_t H5Sselect_none(hid_t spaceid);
H5_DLL herr_t H5Soffset_simple(hid_t space_id, const hssize_t *offset);
diff --git a/src/H5T.c b/src/H5T.c
index 59ae47d..f0800bb 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -3459,8 +3459,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to copy entry");
} /* end if */
else {
- HDmemset (&(new_dt->ent), 0, sizeof(new_dt->ent));
- new_dt->ent.header = HADDR_UNDEF;
+ H5G_ent_reset(&(new_dt->ent));
} /* end else */
/* Set return value */
diff --git a/src/Makefile.am b/src/Makefile.am
index 15a09ed..b4307a0 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -37,7 +37,8 @@ libhdf5_la_LDFLAGS= -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT_
MOSTLYCLEANFILES=H5Tinit.c
# library sources
-libhdf5_la_SOURCES= H5.c H5A.c H5AC.c H5B.c H5B2.c H5B2cache.c H5B2dbg.c \
+libhdf5_la_SOURCES= H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \
+ H5B2dbg.c \
H5B2test.c H5BP.c H5BPcache.c H5BPdbg.c H5BPtest.c \
H5BT.c H5BTbtree2.c H5BTcache.c H5BTdbg.c H5BTtest.c H5C.c \
H5D.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 3d09c5a..516859b 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -82,10 +82,10 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(settingsdir)" \
libLTLIBRARIES_INSTALL = $(INSTALL)
LTLIBRARIES = $(lib_LTLIBRARIES)
libhdf5_la_LIBADD =
-am_libhdf5_la_OBJECTS = H5.lo H5A.lo H5AC.lo H5B.lo H5B2.lo \
- H5B2cache.lo H5B2dbg.lo H5B2test.lo H5BP.lo H5BPcache.lo \
- H5BPdbg.lo H5BPtest.lo H5BT.lo H5BTbtree2.lo H5BTcache.lo \
- H5BTdbg.lo H5BTtest.lo H5C.lo H5D.lo H5Dcontig.lo \
+am_libhdf5_la_OBJECTS = H5.lo H5A.lo H5AC.lo H5B.lo H5Bcache.lo \
+ H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2test.lo H5BP.lo \
+ H5BPcache.lo H5BPdbg.lo H5BPtest.lo H5BT.lo H5BTbtree2.lo \
+ H5BTcache.lo H5BTdbg.lo H5BTtest.lo H5C.lo H5D.lo H5Dcontig.lo \
H5Dcompact.lo H5Defl.lo H5Dio.lo H5Distore.lo H5Dmpio.lo \
H5Dselect.lo H5Dtest.lo H5E.lo H5F.lo H5Fdbg.lo H5Fmount.lo \
H5Fsfile.lo H5Fsuper.lo H5FD.lo H5FDcore.lo H5FDfamily.lo \
@@ -384,7 +384,8 @@ libhdf5_la_LDFLAGS = -version-info $(LT_VERS_INTERFACE):$(LT_VERS_REVISION):$(LT
MOSTLYCLEANFILES = H5Tinit.c
# library sources
-libhdf5_la_SOURCES = H5.c H5A.c H5AC.c H5B.c H5B2.c H5B2cache.c H5B2dbg.c \
+libhdf5_la_SOURCES = H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \
+ H5B2dbg.c \
H5B2test.c H5BP.c H5BPcache.c H5BPdbg.c H5BPtest.c \
H5BT.c H5BTbtree2.c H5BTcache.c H5BTdbg.c H5BTtest.c H5C.c \
H5D.c \
@@ -563,6 +564,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5BTcache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5BTdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5BTtest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Bcache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5C.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5D.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dcompact.Plo@am__quote@