2003-04-01 02:30:57 +08:00
|
|
|
|
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
|
|
* 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. *
|
|
|
|
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
1998-10-08 05:04:51 +08:00
|
|
|
|
|
|
|
|
|
/* $Id$ */
|
|
|
|
|
|
2000-10-10 15:43:38 +08:00
|
|
|
|
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
|
2002-07-31 23:27:07 +08:00
|
|
|
|
#define H5S_PACKAGE /*suppress error about including H5Spkg */
|
2000-10-10 15:43:38 +08:00
|
|
|
|
|
2001-04-06 01:29:14 +08:00
|
|
|
|
#include "H5private.h" /* Generic Functions */
|
|
|
|
|
#include "H5Iprivate.h" /* ID Functions */
|
|
|
|
|
#include "H5Dprivate.h" /* Datasets */
|
|
|
|
|
#include "H5Eprivate.h" /* Error handling */
|
|
|
|
|
#include "H5Fpkg.h" /* Files */
|
|
|
|
|
#include "H5Gprivate.h" /* Groups */
|
|
|
|
|
#include "H5HGprivate.h" /* Global Heaps */
|
|
|
|
|
#include "H5MMprivate.h" /* Memory Management */
|
|
|
|
|
#include "H5Rprivate.h" /* References */
|
2002-07-31 23:27:07 +08:00
|
|
|
|
#include "H5Spkg.h" /* Dataspaces */
|
2001-04-06 01:29:14 +08:00
|
|
|
|
#include "H5Tprivate.h" /* Datatypes */
|
1998-10-08 05:04:51 +08:00
|
|
|
|
|
|
|
|
|
/* Interface initialization */
|
|
|
|
|
#define PABLO_MASK H5R_mask
|
|
|
|
|
#define INTERFACE_INIT H5R_init_interface
|
2001-08-15 06:09:56 +08:00
|
|
|
|
static int interface_initialize_g = 0;
|
1998-10-08 05:04:51 +08:00
|
|
|
|
static herr_t H5R_init_interface(void);
|
|
|
|
|
|
1998-10-14 05:28:53 +08:00
|
|
|
|
/* Static functions */
|
1998-10-23 06:49:16 +08:00
|
|
|
|
static herr_t H5R_create(void *ref, H5G_entry_t *loc, const char *name,
|
2003-02-11 01:26:09 +08:00
|
|
|
|
H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id);
|
|
|
|
|
static hid_t H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref);
|
|
|
|
|
static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref);
|
2003-07-10 03:16:17 +08:00
|
|
|
|
static H5G_obj_t H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
1998-10-08 05:04:51 +08:00
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5R_init_interface -- Initialize interface-specific information
|
|
|
|
|
USAGE
|
|
|
|
|
herr_t H5R_init_interface()
|
|
|
|
|
|
|
|
|
|
RETURNS
|
1998-10-27 05:18:54 +08:00
|
|
|
|
Non-negative on success/Negative on failure
|
1998-10-08 05:04:51 +08:00
|
|
|
|
DESCRIPTION
|
|
|
|
|
Initializes any interface-specific data or routines.
|
|
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
|
static herr_t
|
|
|
|
|
H5R_init_interface(void)
|
|
|
|
|
{
|
2002-08-09 00:52:55 +08:00
|
|
|
|
herr_t ret_value=SUCCEED; /* Return value */
|
|
|
|
|
|
2002-05-29 02:17:12 +08:00
|
|
|
|
FUNC_ENTER_NOINIT(H5R_init_interface);
|
1998-10-08 05:04:51 +08:00
|
|
|
|
|
|
|
|
|
/* Initialize the atom group for the file IDs */
|
1998-11-21 11:36:51 +08:00
|
|
|
|
if (H5I_init_group(H5I_REFERENCE, H5I_REFID_HASHSIZE, H5R_RESERVED_ATOMS,
|
2002-08-09 00:52:55 +08:00
|
|
|
|
(H5I_free_t)NULL)<0)
|
|
|
|
|
HGOTO_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to initialize interface");
|
1998-10-08 05:04:51 +08:00
|
|
|
|
|
2002-08-09 00:52:55 +08:00
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value);
|
1998-11-21 11:36:51 +08:00
|
|
|
|
}
|
1998-10-08 05:04:51 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5R_term_interface
|
|
|
|
|
PURPOSE
|
|
|
|
|
Terminate various H5R objects
|
|
|
|
|
USAGE
|
|
|
|
|
void H5R_term_interface()
|
|
|
|
|
RETURNS
|
1998-10-14 05:28:53 +08:00
|
|
|
|
void
|
1998-10-08 05:04:51 +08:00
|
|
|
|
DESCRIPTION
|
|
|
|
|
Release the atom group and any other resources allocated.
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
Can't report errors...
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
2001-08-15 06:09:56 +08:00
|
|
|
|
int
|
1999-03-30 19:38:34 +08:00
|
|
|
|
H5R_term_interface(void)
|
1998-10-08 05:04:51 +08:00
|
|
|
|
{
|
2001-08-15 06:09:56 +08:00
|
|
|
|
int n=0;
|
2002-05-29 02:17:12 +08:00
|
|
|
|
|
|
|
|
|
FUNC_ENTER_NOINIT(H5R_term_interface);
|
1999-03-30 19:38:34 +08:00
|
|
|
|
|
|
|
|
|
if (interface_initialize_g) {
|
|
|
|
|
if ((n=H5I_nmembers(H5I_REFERENCE))) {
|
1999-04-27 22:47:54 +08:00
|
|
|
|
H5I_clear_group(H5I_REFERENCE, FALSE);
|
1999-03-30 19:38:34 +08:00
|
|
|
|
} else {
|
|
|
|
|
H5I_destroy_group(H5I_REFERENCE);
|
|
|
|
|
interface_initialize_g = 0;
|
|
|
|
|
n = 1; /*H5I*/
|
|
|
|
|
}
|
1998-11-21 11:36:51 +08:00
|
|
|
|
}
|
|
|
|
|
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_NOAPI(n);
|
1998-11-21 11:36:51 +08:00
|
|
|
|
}
|
1998-10-08 05:04:51 +08:00
|
|
|
|
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5R_create
|
|
|
|
|
PURPOSE
|
|
|
|
|
Creates a particular kind of reference for the user
|
|
|
|
|
USAGE
|
|
|
|
|
herr_t H5R_create(ref, loc, name, ref_type, space)
|
1998-10-23 06:49:16 +08:00
|
|
|
|
void *ref; OUT: Reference created
|
1998-10-14 05:28:53 +08:00
|
|
|
|
H5G_entry_t *loc; IN: File location used to locate object pointed to
|
|
|
|
|
const char *name; IN: Name of object at location LOC_ID of object
|
|
|
|
|
pointed to
|
|
|
|
|
H5R_type_t ref_type; IN: Type of reference to create
|
|
|
|
|
H5S_t *space; IN: Dataspace ID with selection, used for Dataset
|
|
|
|
|
Region references.
|
|
|
|
|
|
|
|
|
|
RETURNS
|
1998-10-27 05:18:54 +08:00
|
|
|
|
Non-negative on success/Negative on failure
|
1998-10-14 05:28:53 +08:00
|
|
|
|
DESCRIPTION
|
|
|
|
|
Creates a particular type of reference specified with REF_TYPE, in the
|
|
|
|
|
space pointed to by REF. The LOC_ID and NAME are used to locate the object
|
|
|
|
|
pointed to and the SPACE_ID is used to choose the region pointed to (for
|
|
|
|
|
Dataset Region references).
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
|
static herr_t
|
2003-02-11 01:26:09 +08:00
|
|
|
|
H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
{
|
|
|
|
|
H5G_stat_t sb; /* Stat buffer for retrieving OID */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
herr_t ret_value=SUCCEED; /* Return value */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2002-05-29 02:17:12 +08:00
|
|
|
|
FUNC_ENTER_NOINIT(H5R_create);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
1998-10-23 06:49:16 +08:00
|
|
|
|
assert(_ref);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
assert(loc);
|
|
|
|
|
assert(name);
|
|
|
|
|
assert(ref_type>H5R_BADTYPE || ref_type<H5R_MAXTYPE);
|
|
|
|
|
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if (H5G_get_objinfo (loc, name, 0, &sb, dxpl_id)<0)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
HGOTO_ERROR (H5E_REFERENCE, H5E_NOTFOUND, FAIL, "unable to stat object");
|
|
|
|
|
|
1998-10-23 06:49:16 +08:00
|
|
|
|
switch(ref_type) {
|
|
|
|
|
case H5R_OBJECT:
|
|
|
|
|
{
|
|
|
|
|
hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */
|
1998-11-19 02:40:09 +08:00
|
|
|
|
uint8_t *p; /* Pointer to OID to store */
|
1998-10-23 06:49:16 +08:00
|
|
|
|
|
|
|
|
|
/* Set information for reference */
|
2003-08-09 03:20:57 +08:00
|
|
|
|
p=(uint8_t *)ref;
|
|
|
|
|
H5F_addr_encode(loc->file,&p,sb.objno);
|
1998-10-23 06:49:16 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case H5R_DATASET_REGION:
|
1998-11-13 08:28:29 +08:00
|
|
|
|
{
|
1998-11-25 08:29:09 +08:00
|
|
|
|
H5HG_t hobjid; /* Heap object ID */
|
1998-11-13 08:28:29 +08:00
|
|
|
|
hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
|
|
|
|
|
hssize_t buf_size; /* Size of buffer needed to serialize selection */
|
1998-11-19 02:40:09 +08:00
|
|
|
|
uint8_t *p; /* Pointer to OID to store */
|
|
|
|
|
uint8_t *buf; /* Buffer to store serialized selection in */
|
2001-08-15 06:09:56 +08:00
|
|
|
|
unsigned heapid_found; /* Flag for non-zero heap ID found */
|
|
|
|
|
unsigned u; /* local index */
|
1998-11-13 08:28:29 +08:00
|
|
|
|
|
|
|
|
|
/* Set up information for dataset region */
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Return any previous heap block to the free list if we are garbage collecting */
|
1999-08-18 03:12:59 +08:00
|
|
|
|
if(loc->file->shared->gc_ref) {
|
1998-11-25 08:29:09 +08:00
|
|
|
|
/* Check for an existing heap ID in the reference */
|
|
|
|
|
for(u=0, heapid_found=0; u<H5R_DSET_REG_REF_BUF_SIZE; u++)
|
|
|
|
|
if(ref->heapid[u]!=0) {
|
|
|
|
|
heapid_found=1;
|
|
|
|
|
break;
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
if(heapid_found!=0) {
|
|
|
|
|
/* Return heap block to free list */
|
|
|
|
|
} /* end if */
|
|
|
|
|
} /* end if */
|
|
|
|
|
|
|
|
|
|
/* Zero the heap ID out, may leak heap space if user is re-using reference and doesn't have garbage collection on */
|
|
|
|
|
HDmemset(ref->heapid,H5R_DSET_REG_REF_BUF_SIZE,0);
|
1998-11-13 08:28:29 +08:00
|
|
|
|
|
|
|
|
|
/* Get the amount of space required to serialize the selection */
|
2002-07-31 23:27:07 +08:00
|
|
|
|
if ((buf_size = (*space->select.serial_size)(space)) < 0)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection");
|
1998-11-13 08:28:29 +08:00
|
|
|
|
|
1998-11-25 08:29:09 +08:00
|
|
|
|
/* Increase buffer size to allow for the dataset OID */
|
|
|
|
|
buf_size+=sizeof(haddr_t);
|
|
|
|
|
|
1998-11-13 08:28:29 +08:00
|
|
|
|
/* Allocate the space to store the serialized information */
|
2001-11-28 00:29:13 +08:00
|
|
|
|
H5_CHECK_OVERFLOW(buf_size,hssize_t,size_t);
|
|
|
|
|
if (NULL==(buf = H5MM_malloc((size_t)buf_size)))
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
|
1998-11-13 08:28:29 +08:00
|
|
|
|
|
1998-11-25 08:29:09 +08:00
|
|
|
|
/* Serialize information for dataset OID */
|
|
|
|
|
p=(uint8_t *)buf;
|
2003-08-09 03:20:57 +08:00
|
|
|
|
H5F_addr_encode(loc->file,&p,sb.objno);
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
1998-11-13 08:28:29 +08:00
|
|
|
|
/* Serialize the selection */
|
2002-07-31 23:27:07 +08:00
|
|
|
|
if ((*space->select.serialize)(space,p) < 0)
|
2001-11-28 00:29:13 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Save the serialized buffer for later */
|
2001-11-28 00:29:13 +08:00
|
|
|
|
H5_CHECK_OVERFLOW(buf_size,hssize_t,size_t);
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if(H5HG_insert(loc->file,dxpl_id,(size_t)buf_size,buf,&hobjid)<0)
|
2001-11-28 00:29:13 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Serialize the heap ID and index for storage in the file */
|
|
|
|
|
p=(uint8_t *)ref->heapid;
|
1999-07-29 02:25:43 +08:00
|
|
|
|
H5F_addr_encode(loc->file,&p,hobjid.addr);
|
1998-11-25 08:29:09 +08:00
|
|
|
|
INT32ENCODE(p,hobjid.idx);
|
|
|
|
|
|
|
|
|
|
/* Free the buffer we serialized data in */
|
|
|
|
|
H5MM_xfree(buf);
|
1998-11-13 08:28:29 +08:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
1998-10-23 06:49:16 +08:00
|
|
|
|
case H5R_INTERNAL:
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "Internal references are not yet supported");
|
1998-10-23 06:49:16 +08:00
|
|
|
|
|
|
|
|
|
case H5R_BADTYPE:
|
|
|
|
|
case H5R_MAXTYPE:
|
1998-11-25 08:29:09 +08:00
|
|
|
|
default:
|
1998-10-23 06:49:16 +08:00
|
|
|
|
assert("unknown reference type" && 0);
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)");
|
1998-10-23 06:49:16 +08:00
|
|
|
|
} /* end switch */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
} /* end H5R_create() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5Rcreate
|
|
|
|
|
PURPOSE
|
|
|
|
|
Creates a particular kind of reference for the user
|
|
|
|
|
USAGE
|
|
|
|
|
herr_t H5Rcreate(ref, loc_id, name, ref_type, space_id)
|
1998-10-23 06:49:16 +08:00
|
|
|
|
void *ref; OUT: Reference created
|
1998-10-14 05:28:53 +08:00
|
|
|
|
hid_t loc_id; IN: Location ID used to locate object pointed to
|
|
|
|
|
const char *name; IN: Name of object at location LOC_ID of object
|
|
|
|
|
pointed to
|
|
|
|
|
H5R_type_t ref_type; IN: Type of reference to create
|
|
|
|
|
hid_t space_id; IN: Dataspace ID with selection, used for Dataset
|
|
|
|
|
Region references.
|
|
|
|
|
|
|
|
|
|
RETURNS
|
1998-10-27 05:18:54 +08:00
|
|
|
|
Non-negative on success/Negative on failure
|
1998-10-14 05:28:53 +08:00
|
|
|
|
DESCRIPTION
|
|
|
|
|
Creates a particular type of reference specified with REF_TYPE, in the
|
|
|
|
|
space pointed to by REF. The LOC_ID and NAME are used to locate the object
|
|
|
|
|
pointed to and the SPACE_ID is used to choose the region pointed to (for
|
|
|
|
|
Dataset Region references).
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
|
herr_t
|
1998-10-23 06:49:16 +08:00
|
|
|
|
H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
{
|
|
|
|
|
H5G_entry_t *loc = NULL; /* File location */
|
|
|
|
|
H5S_t *space = NULL; /* Pointer to dataspace containing region */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
herr_t ret_value; /* Return value */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2002-05-29 23:07:55 +08:00
|
|
|
|
FUNC_ENTER_API(H5Rcreate, FAIL);
|
1998-10-26 22:49:52 +08:00
|
|
|
|
H5TRACE5("e","xisRti",ref,loc_id,name,ref_type,space_id);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
/* Check args */
|
|
|
|
|
if(ref==NULL)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer");
|
1998-10-14 05:28:53 +08:00
|
|
|
|
if (NULL==(loc=H5G_loc (loc_id)))
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
|
1998-10-14 05:28:53 +08:00
|
|
|
|
if (!name || !*name)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given");
|
1998-10-14 05:28:53 +08:00
|
|
|
|
if(ref_type<=H5R_BADTYPE || ref_type>=H5R_MAXTYPE)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type");
|
1998-11-13 08:28:29 +08:00
|
|
|
|
if(ref_type!=H5R_OBJECT && ref_type!=H5R_DATASET_REGION)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported");
|
2002-08-01 03:17:12 +08:00
|
|
|
|
if (space_id!=(-1) && (NULL==(space=H5I_object_verify(space_id,H5I_DATASPACE))))
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace");
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
/* Create reference */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if ((ret_value=H5R_create(ref,loc,name,ref_type,space, H5AC_dxpl_id))<0)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
HGOTO_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference");
|
|
|
|
|
|
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_API(ret_value);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
} /* end H5Rcreate() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5R_dereference
|
|
|
|
|
PURPOSE
|
|
|
|
|
Opens the HDF5 object referenced.
|
|
|
|
|
USAGE
|
|
|
|
|
hid_t H5R_dereference(ref)
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5F_t *file; IN: File the object being dereferenced is within
|
1998-10-23 06:49:16 +08:00
|
|
|
|
H5R_type_t ref_type; IN: Type of reference
|
|
|
|
|
void *ref; IN: Reference to open.
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
RETURNS
|
1998-10-27 05:18:54 +08:00
|
|
|
|
Valid ID on success, Negative on failure
|
1998-10-14 05:28:53 +08:00
|
|
|
|
DESCRIPTION
|
|
|
|
|
Given a reference to some object, open that object and return an ID for
|
|
|
|
|
that object.
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
Currently only set up to work with references to datasets
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
|
static hid_t
|
2003-02-11 01:26:09 +08:00
|
|
|
|
H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
{
|
1999-03-18 08:07:50 +08:00
|
|
|
|
H5G_t *group; /* Pointer to group to open */
|
1999-03-18 09:30:03 +08:00
|
|
|
|
H5T_t *datatype; /* Pointer to datatype to open */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
H5G_entry_t ent; /* Symbol table entry */
|
1998-11-19 02:40:09 +08:00
|
|
|
|
uint8_t *p; /* Pointer to OID to store */
|
2003-04-30 21:55:51 +08:00
|
|
|
|
int oid_type; /* type of object being dereferenced */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
hid_t ret_value;
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2002-05-29 02:17:12 +08:00
|
|
|
|
FUNC_ENTER_NOINIT(H5R_dereference);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
1998-11-25 08:29:09 +08:00
|
|
|
|
assert(_ref);
|
|
|
|
|
assert(ref_type>H5R_BADTYPE || ref_type<H5R_MAXTYPE);
|
1999-06-26 03:36:54 +08:00
|
|
|
|
assert(file);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
/* Initialize the symbol table entry */
|
|
|
|
|
HDmemset(&ent,0,sizeof(H5G_entry_t));
|
|
|
|
|
ent.type=H5G_NOTHING_CACHED;
|
1999-06-26 03:36:54 +08:00
|
|
|
|
ent.file=file;
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
switch(ref_type) {
|
|
|
|
|
case H5R_OBJECT:
|
|
|
|
|
{
|
|
|
|
|
hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */
|
|
|
|
|
/*
|
|
|
|
|
* Switch on object type, when we implement that feature, always try to
|
|
|
|
|
* open a dataset for now
|
|
|
|
|
*/
|
|
|
|
|
/* Get the object oid */
|
2003-08-09 03:20:57 +08:00
|
|
|
|
p=(uint8_t *)ref;
|
1998-11-25 08:29:09 +08:00
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
|
|
|
|
|
} /* end case */
|
2001-12-21 04:51:30 +08:00
|
|
|
|
break;
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
case H5R_DATASET_REGION:
|
|
|
|
|
{
|
|
|
|
|
hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
|
|
|
|
|
H5HG_t hobjid; /* Heap object ID */
|
|
|
|
|
uint8_t *buf; /* Buffer to store serialized selection in */
|
|
|
|
|
|
|
|
|
|
/* Get the heap ID for the dataset region */
|
|
|
|
|
p=(uint8_t *)ref->heapid;
|
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr));
|
|
|
|
|
INT32DECODE(p,hobjid.idx);
|
|
|
|
|
|
|
|
|
|
/* Get the dataset region from the heap (allocate inside routine) */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if((buf=H5HG_read(ent.file,dxpl_id,&hobjid,NULL))==NULL)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Get the object oid for the dataset */
|
|
|
|
|
p=(uint8_t *)buf;
|
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
|
|
|
|
|
|
|
|
|
|
/* Free the buffer allocated in H5HG_read() */
|
|
|
|
|
H5MM_xfree(buf);
|
|
|
|
|
} /* end case */
|
2001-12-21 04:51:30 +08:00
|
|
|
|
break;
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
case H5R_INTERNAL:
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "Internal references are not yet supported");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
case H5R_BADTYPE:
|
|
|
|
|
case H5R_MAXTYPE:
|
|
|
|
|
default:
|
|
|
|
|
assert("unknown reference type" && 0);
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
} /* end switch */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2000-10-18 04:46:57 +08:00
|
|
|
|
/* Check to make certain that this object hasn't been deleted since the reference was created */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if(H5O_link(&ent,0,dxpl_id)<=0)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object");
|
2000-10-18 04:46:57 +08:00
|
|
|
|
|
1998-10-14 05:28:53 +08:00
|
|
|
|
/* Open the dataset object */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
oid_type=H5G_get_type(&ent,dxpl_id);
|
1999-03-12 05:03:30 +08:00
|
|
|
|
switch(oid_type) {
|
|
|
|
|
case H5G_GROUP:
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if ((group=H5G_open_oid(&ent,dxpl_id)) == NULL)
|
1999-03-18 08:07:50 +08:00
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found");
|
|
|
|
|
|
|
|
|
|
/* Create an atom for the dataset */
|
|
|
|
|
if ((ret_value = H5I_register(H5I_GROUP, group)) < 0) {
|
|
|
|
|
H5G_close(group);
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "can't register group");
|
1999-03-18 08:07:50 +08:00
|
|
|
|
}
|
1999-03-12 05:03:30 +08:00
|
|
|
|
break;
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
1999-03-12 05:03:30 +08:00
|
|
|
|
case H5G_TYPE:
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if ((datatype=H5T_open_oid(&ent, dxpl_id)) == NULL)
|
1999-03-18 09:30:03 +08:00
|
|
|
|
HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found");
|
|
|
|
|
|
|
|
|
|
/* Create an atom for the dataset */
|
|
|
|
|
if ((ret_value = H5I_register(H5I_DATATYPE, datatype)) < 0) {
|
|
|
|
|
H5T_close(datatype);
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "can't register group");
|
1999-03-18 09:30:03 +08:00
|
|
|
|
}
|
1999-03-12 05:03:30 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case H5G_DATASET:
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
/* Open the dataset */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if ((ret_value=H5D_open(&ent,dxpl_id)) < 0)
|
1999-03-12 05:03:30 +08:00
|
|
|
|
HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, FAIL, "can't identify type of object referenced");
|
1999-03-12 05:03:30 +08:00
|
|
|
|
} /* end switch */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
} /* end H5R_dereference() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5Rdereference
|
|
|
|
|
PURPOSE
|
|
|
|
|
Opens the HDF5 object referenced.
|
|
|
|
|
USAGE
|
|
|
|
|
hid_t H5Rdereference(ref)
|
1999-06-26 03:36:54 +08:00
|
|
|
|
hid_t id; IN: Dataset reference object is in or location ID of
|
|
|
|
|
object that the dataset is located within.
|
1998-10-23 06:49:16 +08:00
|
|
|
|
H5R_type_t ref_type; IN: Type of reference to create
|
1999-06-26 03:36:54 +08:00
|
|
|
|
void *ref; IN: Reference to open.
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
RETURNS
|
1998-10-27 05:18:54 +08:00
|
|
|
|
Valid ID on success, Negative on failure
|
1998-10-14 05:28:53 +08:00
|
|
|
|
DESCRIPTION
|
|
|
|
|
Given a reference to some object, open that object and return an ID for
|
|
|
|
|
that object.
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
|
hid_t
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5Rdereference(hid_t id, H5R_type_t ref_type, void *_ref)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
{
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5G_entry_t *loc = NULL; /* Symbol table entry */
|
|
|
|
|
H5F_t *file=NULL; /* File object */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
hid_t ret_value;
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2002-05-29 23:07:55 +08:00
|
|
|
|
FUNC_ENTER_API(H5Rdereference, FAIL);
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5TRACE3("i","iRtx",id,ref_type,_ref);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
/* Check args */
|
2000-12-02 23:11:57 +08:00
|
|
|
|
if (NULL == (loc = H5G_loc(id)))
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
|
1998-10-23 06:49:16 +08:00
|
|
|
|
if(ref_type<=H5R_BADTYPE || ref_type>=H5R_MAXTYPE)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type");
|
1998-10-23 06:49:16 +08:00
|
|
|
|
if(_ref==NULL)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer");
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2000-12-02 23:11:57 +08:00
|
|
|
|
/* Get the file pointer from the entry */
|
|
|
|
|
file=loc->file;
|
|
|
|
|
|
1998-10-14 05:28:53 +08:00
|
|
|
|
/* Create reference */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if ((ret_value=H5R_dereference(file, H5AC_dxpl_id, ref_type, _ref))<0)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
HGOTO_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable dereference object");
|
|
|
|
|
|
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_API(ret_value);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
} /* end H5Rdereference() */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
1998-10-27 01:14:00 +08:00
|
|
|
|
H5R_get_region
|
1998-10-14 05:28:53 +08:00
|
|
|
|
PURPOSE
|
|
|
|
|
Retrieves a dataspace with the region pointed to selected.
|
|
|
|
|
USAGE
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5S_t *H5R_get_region(file, ref_type, ref)
|
|
|
|
|
H5F_t *file; IN: File the object being dereferenced is within
|
|
|
|
|
H5R_type_t ref_type; UNUSED
|
|
|
|
|
void *ref; IN: Reference to open.
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
RETURNS
|
|
|
|
|
Pointer to the dataspace on success, NULL on failure
|
|
|
|
|
DESCRIPTION
|
|
|
|
|
Given a reference to some object, creates a copy of the dataset pointed
|
|
|
|
|
to's dataspace and defines a selection in the copy which is the region
|
|
|
|
|
pointed to.
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
|
static H5S_t *
|
2003-02-11 01:26:09 +08:00
|
|
|
|
H5R_get_region(H5F_t *file, hid_t dxpl_id, H5R_type_t UNUSED ref_type, void *_ref)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
{
|
1998-11-25 08:29:09 +08:00
|
|
|
|
H5G_entry_t ent; /* Symbol table entry */
|
|
|
|
|
uint8_t *p; /* Pointer to OID to store */
|
|
|
|
|
hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
|
|
|
|
|
H5HG_t hobjid; /* Heap object ID */
|
|
|
|
|
uint8_t *buf; /* Buffer to store serialized selection in */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
H5S_t *ret_value;
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2002-05-29 02:17:12 +08:00
|
|
|
|
FUNC_ENTER_NOINIT(H5R_get_region);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
1998-11-25 08:29:09 +08:00
|
|
|
|
assert(_ref);
|
|
|
|
|
assert(ref_type==H5R_DATASET_REGION);
|
1999-06-26 03:36:54 +08:00
|
|
|
|
assert(file);
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Initialize the symbol table entry */
|
|
|
|
|
HDmemset(&ent,0,sizeof(H5G_entry_t));
|
|
|
|
|
ent.type=H5G_NOTHING_CACHED;
|
1999-06-26 03:36:54 +08:00
|
|
|
|
ent.file=file;
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Get the heap ID for the dataset region */
|
|
|
|
|
p=(uint8_t *)ref->heapid;
|
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr));
|
|
|
|
|
INT32DECODE(p,hobjid.idx);
|
|
|
|
|
|
|
|
|
|
/* Get the dataset region from the heap (allocate inside routine) */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if((buf=H5HG_read(ent.file,dxpl_id,&hobjid,NULL))==NULL)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Get the object oid for the dataset */
|
|
|
|
|
p=(uint8_t *)buf;
|
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
|
|
|
|
|
|
[svn-r6252] Purpose:
Lots of performance improvements & a couple new internal API interfaces.
Description:
Performance Improvements:
- Cached file offset & length sizes in shared file struct, to avoid
constantly looking them up in the FCPL.
- Generic property improvements:
- Added "revision" number to generic property classes to speed
up comparisons.
- Changed method of storing properties from using a hash-table
to the TBBT routines in the library.
- Share the propery names between classes and the lists derived
from them.
- Removed redundant 'def_value' buffer from each property.
- Switching code to use a "copy on write" strategy for
properties in each list, where the properties in each list
are shared with the properties in the class, until a
property's value is changed in a list.
- Fixed error in layout code which was allocating too many buffers.
- Redefined public macros of the form (H5open()/H5check, <variable>)
internally to only be (<variable>), avoiding innumerable useless
calls to H5open() and H5check_version().
- Reuse already zeroed buffers in H5F_contig_fill instead of
constantly re-zeroing them.
- Don't write fill values if writing entire dataset.
- Use gettimeofday() system call instead of time() system when
checking the modification time of a dataset.
- Added reference counted string API and use it for tracking the
names of objects opening in a file (for the ID->name code).
- Removed redundant H5P_get() calls in B-tree routines.
- Redefine H5T datatype macros internally to the library, to avoid
calling H5check redundantly.
- Keep dataspace information for dataset locally instead of reading
from disk each time. Added new module to track open objects
in a file, to allow this (which will be useful eventually for
some FPH5 metadata caching issues).
- Remove H5AC_find macro which was inlining metadata cache lookups,
and call function instead.
- Remove redundant memset() calls from H5G_namei() routine.
- Remove redundant checking of object type when locating objects
in metadata cache and rely on the address only.
- Create default dataset object to use when default dataset creation
property list is used to create datasets, bypassing querying
for all the property list values.
- Use default I/O vector size when performing raw data with the
default dataset transfer property list, instead of querying for
I/O vector size.
- Remove H5P_DEFAULT internally to the library, replacing it with
more specific default property list based on the type of
property list needed.
- Remove redundant memset() calls in object header message (H5O*)
routines.
- Remove redunant memset() calls in data I/O routines.
- Split free-list allocation routines into malloc() and calloc()-
like routines, instead of one combined routine.
- Remove lots of indirection in H5O*() routines.
- Simplify metadata cache entry comparison routine (used when
flushing entire cache out).
- Only enable metadata cache statistics when H5AC_DEBUG is turned
on, instead of always tracking them.
- Simplify address comparison macro (H5F_addr_eq).
- Remove redundant metadata cache entry protections during dataset
creation by protecting the object header once and making all
the modifications necessary for the dataset creation before
unprotecting it.
- Reduce # of "number of element in extent" computations performed
by computing and storing the value during dataspace creation.
- Simplify checking for group location's file information, when file
has not been involving in file-mounting operations.
- Use binary encoding for modification time, instead of ASCII.
- Hoist H5HL_peek calls (to get information in a local heap)
out of loops in many group routine.
- Use static variable for iterators of selections, instead of
dynamically allocation them each time.
- Lookup & insert new entries in one step, avoiding traversing
group's B-tree twice.
- Fixed memory leak in H5Gget_objname_idx() routine (tangential to
performance improvements, but fixed along the way).
- Use free-list for reference counted strings.
- Don't bother copying object names into cached group entries,
since they are re-created when an object is opened.
The benchmark I used to measure these results created several thousand
small (2K) datasets in a file and wrote out the data for them. This is
Elena's "regular.c" benchmark.
These changes resulted in approximately ~4.3x speedup of the
development branch when compared to the previous code in the
development branch and ~1.4x speedup compared to the release
branch.
Additionally, these changes reduce the total memory used (code and
data) by the development branch by ~800KB, bringing the development
branch back into the same ballpark as the release branch.
I'll send out a more detailed description of the benchmark results
as a followup note.
New internal API routines:
Added "reference counted strings" API for tracking strings that get
used by multiple owners without duplicating the strings.
Added "ternary search tree" API for text->object mappings.
Platforms tested:
Tested h5committest {arabica (fortran), eirene (fortran, C++)
modi4 (parallel, fortran)}
Other platforms/configurations tested?
FreeBSD 4.7 (sleipnir) serial & parallel
Solaris 2.6 (baldric) serial
2003-01-10 01:20:03 +08:00
|
|
|
|
/* Open and copy the dataset's dataspace */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if ((ret_value=H5S_read(&ent, dxpl_id)) == NULL)
|
1998-11-25 08:29:09 +08:00
|
|
|
|
HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found");
|
|
|
|
|
|
1999-03-11 07:50:03 +08:00
|
|
|
|
/* Unserialize the selection */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
if (H5S_select_deserialize(ret_value,p) < 0)
|
1999-03-11 07:50:03 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
|
|
|
|
|
/* Free the buffer allocated in H5HG_read() */
|
|
|
|
|
H5MM_xfree(buf);
|
|
|
|
|
|
1998-10-14 05:28:53 +08:00
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value);
|
1998-10-27 01:14:00 +08:00
|
|
|
|
} /* end H5R_get_region() */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
1998-10-27 01:14:00 +08:00
|
|
|
|
H5Rget_region
|
1998-10-14 05:28:53 +08:00
|
|
|
|
PURPOSE
|
|
|
|
|
Retrieves a dataspace with the region pointed to selected.
|
|
|
|
|
USAGE
|
1999-06-26 03:36:54 +08:00
|
|
|
|
hid_t H5Rget_region(id, ref_type, ref)
|
|
|
|
|
hid_t id; IN: Dataset reference object is in or location ID of
|
|
|
|
|
object that the dataset is located within.
|
|
|
|
|
H5R_type_t ref_type; IN: Type of reference to get region of
|
1998-10-23 06:49:16 +08:00
|
|
|
|
void *ref; IN: Reference to open.
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
RETURNS
|
1998-10-27 05:18:54 +08:00
|
|
|
|
Valid ID on success, Negative on failure
|
1998-10-14 05:28:53 +08:00
|
|
|
|
DESCRIPTION
|
|
|
|
|
Given a reference to some object, creates a copy of the dataset pointed
|
|
|
|
|
to's dataspace and defines a selection in the copy which is the region
|
|
|
|
|
pointed to.
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
|
|
|
|
hid_t
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5Rget_region(hid_t id, H5R_type_t ref_type, void *_ref)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
{
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5G_entry_t *loc = NULL; /* Symbol table entry */
|
1998-11-25 08:29:09 +08:00
|
|
|
|
H5S_t *space = NULL; /* dataspace object */
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5F_t *file=NULL; /* File object */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
hid_t ret_value;
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2002-05-29 23:07:55 +08:00
|
|
|
|
FUNC_ENTER_API(H5Rget_region, FAIL);
|
1999-06-26 03:36:54 +08:00
|
|
|
|
H5TRACE3("i","iRtx",id,ref_type,_ref);
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
|
|
|
|
/* Check args */
|
2000-12-02 23:11:57 +08:00
|
|
|
|
if (NULL == (loc = H5G_loc(id)))
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
if(ref_type!=H5R_DATASET_REGION)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type");
|
1998-11-25 08:29:09 +08:00
|
|
|
|
if(_ref==NULL)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer");
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2000-12-02 23:11:57 +08:00
|
|
|
|
/* Get the file pointer from the entry */
|
|
|
|
|
file=loc->file;
|
|
|
|
|
|
1998-11-25 08:29:09 +08:00
|
|
|
|
/* Get the dataspace with the correct region selected */
|
2003-02-11 02:44:22 +08:00
|
|
|
|
if ((space=H5R_get_region(file,H5AC_ind_dxpl_id,ref_type,_ref))==NULL)
|
1998-10-14 05:28:53 +08:00
|
|
|
|
HGOTO_ERROR (H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace");
|
|
|
|
|
|
|
|
|
|
/* Atomize */
|
|
|
|
|
if ((ret_value=H5I_register (H5I_DATASPACE, space))<0)
|
|
|
|
|
HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom");
|
|
|
|
|
|
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_API(ret_value);
|
1998-10-27 01:14:00 +08:00
|
|
|
|
} /* end H5Rget_region() */
|
1998-10-14 05:28:53 +08:00
|
|
|
|
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5R_get_obj_type
|
|
|
|
|
PURPOSE
|
|
|
|
|
Retrieves the type of object that an object reference points to
|
|
|
|
|
USAGE
|
2003-07-10 03:16:17 +08:00
|
|
|
|
H5G_obj_t H5R_get_obj_type(file, ref_type, ref)
|
2001-12-21 04:51:30 +08:00
|
|
|
|
H5F_t *file; IN: File the object being dereferenced is within
|
|
|
|
|
H5R_type_t ref_type; IN: Type of reference to query
|
|
|
|
|
void *ref; IN: Reference to query.
|
|
|
|
|
|
|
|
|
|
RETURNS
|
|
|
|
|
Success: An object type defined in H5Gpublic.h
|
|
|
|
|
Failure: H5G_UNKNOWN
|
|
|
|
|
DESCRIPTION
|
|
|
|
|
Given a reference to some object, this function returns the type of object
|
|
|
|
|
pointed to.
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
2003-07-10 03:16:17 +08:00
|
|
|
|
static H5G_obj_t
|
2003-02-11 01:26:09 +08:00
|
|
|
|
H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
|
2001-12-21 04:51:30 +08:00
|
|
|
|
{
|
|
|
|
|
H5G_entry_t ent; /* Symbol table entry */
|
|
|
|
|
uint8_t *p; /* Pointer to OID to store */
|
2003-07-10 03:16:17 +08:00
|
|
|
|
H5G_obj_t ret_value; /* Return value */
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
2002-05-29 02:17:12 +08:00
|
|
|
|
FUNC_ENTER_NOINIT(H5R_get_obj_type);
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
assert(file);
|
|
|
|
|
assert(_ref);
|
|
|
|
|
|
|
|
|
|
/* Initialize the symbol table entry */
|
|
|
|
|
HDmemset(&ent,0,sizeof(H5G_entry_t));
|
|
|
|
|
ent.type=H5G_NOTHING_CACHED;
|
|
|
|
|
ent.file=file;
|
|
|
|
|
|
|
|
|
|
switch(ref_type) {
|
|
|
|
|
case H5R_OBJECT:
|
|
|
|
|
{
|
|
|
|
|
hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */
|
|
|
|
|
|
|
|
|
|
/* Get the object oid */
|
2003-08-09 03:20:57 +08:00
|
|
|
|
p=(uint8_t *)ref;
|
2001-12-21 04:51:30 +08:00
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
|
|
|
|
|
} /* end case */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case H5R_DATASET_REGION:
|
|
|
|
|
{
|
|
|
|
|
hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
|
|
|
|
|
H5HG_t hobjid; /* Heap object ID */
|
|
|
|
|
uint8_t *buf; /* Buffer to store serialized selection in */
|
|
|
|
|
|
|
|
|
|
/* Get the heap ID for the dataset region */
|
|
|
|
|
p=(uint8_t *)ref->heapid;
|
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr));
|
|
|
|
|
INT32DECODE(p,hobjid.idx);
|
|
|
|
|
|
|
|
|
|
/* Get the dataset region from the heap (allocate inside routine) */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if((buf=H5HG_read(ent.file,dxpl_id,&hobjid,NULL))==NULL)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5G_UNKNOWN, "Unable to read dataset region information");
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
/* Get the object oid for the dataset */
|
|
|
|
|
p=(uint8_t *)buf;
|
|
|
|
|
H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
|
|
|
|
|
|
|
|
|
|
/* Free the buffer allocated in H5HG_read() */
|
|
|
|
|
H5MM_xfree(buf);
|
|
|
|
|
} /* end case */
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case H5R_INTERNAL:
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, "Internal references are not yet supported");
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
case H5R_BADTYPE:
|
|
|
|
|
case H5R_MAXTYPE:
|
|
|
|
|
default:
|
|
|
|
|
assert("unknown reference type" && 0);
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, "internal error (unknown reference type)");
|
2001-12-21 04:51:30 +08:00
|
|
|
|
} /* end switch */
|
|
|
|
|
|
|
|
|
|
/* Check to make certain that this object hasn't been deleted since the reference was created */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
if(H5O_link(&ent,0,dxpl_id)<=0)
|
2001-12-21 04:51:30 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5G_UNKNOWN, "dereferencing deleted object");
|
|
|
|
|
|
|
|
|
|
/* Get the OID type */
|
2003-02-11 01:26:09 +08:00
|
|
|
|
ret_value=H5G_get_type(&ent,dxpl_id);
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_NOAPI(ret_value);
|
2001-12-21 04:51:30 +08:00
|
|
|
|
} /* end H5R_get_obj_type() */
|
2002-08-09 00:52:55 +08:00
|
|
|
|
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------------
|
|
|
|
|
NAME
|
|
|
|
|
H5Rget_obj_type
|
|
|
|
|
PURPOSE
|
|
|
|
|
Retrieves the type of object that an object reference points to
|
|
|
|
|
USAGE
|
|
|
|
|
int H5Rget_obj_type(id, ref_type, ref)
|
|
|
|
|
hid_t id; IN: Dataset reference object is in or location ID of
|
|
|
|
|
object that the dataset is located within.
|
|
|
|
|
H5R_type_t ref_type; IN: Type of reference to query
|
|
|
|
|
void *ref; IN: Reference to query.
|
|
|
|
|
|
|
|
|
|
RETURNS
|
|
|
|
|
Success: An object type defined in H5Gpublic.h
|
|
|
|
|
Failure: H5G_UNKNOWN
|
|
|
|
|
DESCRIPTION
|
|
|
|
|
Given a reference to some object, this function returns the type of object
|
|
|
|
|
pointed to.
|
|
|
|
|
GLOBAL VARIABLES
|
|
|
|
|
COMMENTS, BUGS, ASSUMPTIONS
|
|
|
|
|
EXAMPLES
|
|
|
|
|
REVISION LOG
|
|
|
|
|
--------------------------------------------------------------------------*/
|
2003-04-30 21:55:51 +08:00
|
|
|
|
H5G_obj_t
|
|
|
|
|
H5Rget_obj_type(hid_t id, H5R_type_t ref_type, void *_ref)
|
2001-12-21 04:51:30 +08:00
|
|
|
|
{
|
|
|
|
|
H5G_entry_t *loc = NULL; /* Symbol table entry */
|
|
|
|
|
H5F_t *file=NULL; /* File object */
|
2003-04-30 21:55:51 +08:00
|
|
|
|
H5G_obj_t ret_value;
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
2002-05-29 23:07:55 +08:00
|
|
|
|
FUNC_ENTER_API(H5Rget_obj_type, H5G_UNKNOWN);
|
2001-12-23 04:13:44 +08:00
|
|
|
|
H5TRACE3("Is","iRtx",id,ref_type,_ref);
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
/* Check args */
|
|
|
|
|
if (NULL == (loc = H5G_loc(id)))
|
2003-05-10 02:18:21 +08:00
|
|
|
|
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location");
|
2001-12-21 04:51:30 +08:00
|
|
|
|
if(ref_type<=H5R_BADTYPE || ref_type>=H5R_MAXTYPE)
|
2003-05-10 02:18:21 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type");
|
2001-12-21 04:51:30 +08:00
|
|
|
|
if(_ref==NULL)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer");
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
/* Get the file pointer from the entry */
|
|
|
|
|
file=loc->file;
|
|
|
|
|
|
|
|
|
|
/* Get the object information */
|
2003-02-11 02:44:22 +08:00
|
|
|
|
if ((ret_value=H5R_get_obj_type(file,H5AC_ind_dxpl_id,ref_type,_ref))<0)
|
2002-08-09 00:52:55 +08:00
|
|
|
|
HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type");
|
2001-12-21 04:51:30 +08:00
|
|
|
|
|
|
|
|
|
done:
|
2003-01-11 04:26:02 +08:00
|
|
|
|
FUNC_LEAVE_API(ret_value);
|
2001-12-21 04:51:30 +08:00
|
|
|
|
} /* end H5Rget_obj_type() */
|
1999-06-12 06:04:42 +08:00
|
|
|
|
|