mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-27 02:10:55 +08:00
[svn-r129] Changes since 19970916
---------------------- ./config/depend.in Fixed backslashes in sed script because the H5Gnode.c dependency info was disappearing. You'll have to rerun config.status to rebuild the Makefiles unless you use gnu make. ./config/conclude.in Also removes emacs backup files, TAGS, and svf backup files. ./config/linux Grouped gcc flags and added provisions for debugging vs. production. ./html/H5.format.html Updated messages 0x0008, 0x0009, and 0x000A. ./html/storage.html Documentation describing storage schemes. ./src/Makefile.in ./test/Makefile.in New source files. ./src/H5A.c ./src/H5Apublic.h ./src/H5C.c Changed VOIDP to void* in a couple places. ./src/H5AC.c ./src/H5ACprivate.h ./src/H5B.c ./src/H5Bprivate.h ./src/H5G.c ./src/H5Gnode.c ./src/H5Gprivate.h ./src/H5H.c ./src/H5O.c Removed `const' from some variables because H5G_node_found() wanted to modify it's udata argument. Removing const there caused it to cascade to these other locations. ./src/H5AC.c ./src/H5ACprivate.h ./src/H5B.c ./src/H5Gnode.c ./src/H5Gstab.c ./src/H5H.c ./src/H5O.c Added an extra argument to H5AC_find_f() and H5AC_protect(). This arg gets passed to the load() method. Also added an extra argument to the H5AC_find() macro. ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c Extra argument passed to the sizeof_rkey() method. ./src/H5Fprivate.c ./src/H5Fistore.c (new) Added indexed I/O operations. ./src/H5G.c ./src/H5Gnode.c ./src/H5Gprivate.h Beginning to add H5G_open/close and related bug fixes. ./src/H5Oprivate.h ./src/H5Oistore.c (new) Added the H5O_ISTORE messsage (0x0008) for indexed storage of objects. ./src/H5private.h Added extra braces around both sides of the FUNC_ENTER() and FUNC_LEAVE() macros so FUNC_ENTER() can appear before declarations or after executable statements the second case is used by H5G_namei() to initialize output arguments to sane values before FUNC_ENTER() might return failure. int f () { int decl1; printf ("This happens before FUNC_ENTER()\n"); FUNC_ENTER (...); int another_declaration; ./src/H5B.c ./src/H5Bprivate.h ./src/H5Gnode.c Extra arguments for key encoding and decoding. ./src/H5E.c ./src/H5Epublic.h ./src/H5Fistore.c ./src/H5Oistore.c ./src/H5Oprivate.h Indexed, chunked, sparse storage (not ready for general consumption yet). ./src/H5V.c (new) ./src/H5Vprivate.h (new) ./test/hyperslab.c (new) Vector, array, and hyperslab functions. ./src/H5B.c ./src/H5Bprivate.h ./src/H5Fistore.c ./src/H5Gnode.c ./src/H5V.c ./src/H5Vprivate.h ./test/hyperslab.c Added functionality for indexed storage. ./src/H5F.c Fixed problems with seek optimizing. Recommend we disable it until we can implement it in the file/address class since all of HDF5 must be aware of it. ./src/H5O.c Fixed comeent speling erorr :-) ./MANIFEST Added new files. ./config/conclude.in Added the word `Testing' to the test cases. So if a test program is called hyperslab then the make output will contain the line `Testing hyperslab'. ./config/linux The default file I/O library is Posix section 2 on my linux machine so I can do some I/O performance testing. ./src/H5C.c ./src/H5Cprivate.h ./src/H5Cpublic.h Added ability to set size of indexed-storage B-tree. ./src/H5D.c ./src/H5E.c ./src/H5Epublic.h ./src/H5F.c ./src/H5Fprivate.h ./src/H5G.c ./src/H5Gnode.c ./src/H5Gpkg.h ./src/H5Gprivate.h ./src/H5Gpublic.h ./src/H5Gshad.c ./src/H5Gstab.c ./test/stab.c Changed `directory' to `group' in numerous places. ./src/H5private.h The FILELIB constant can be set on the compile command-line. ./src/istore.c NEW Tests for indexed storage.
This commit is contained in:
parent
dc4961d072
commit
56ad55117a
6
MANIFEST
6
MANIFEST
@ -48,6 +48,7 @@
|
||||
./src/H5Eprivate.h
|
||||
./src/H5Epublic.h
|
||||
./src/H5F.c
|
||||
./src/H5Fistore.c
|
||||
./src/H5Fprivate.h
|
||||
./src/H5Fpublic.h
|
||||
./src/H5G.c
|
||||
@ -72,6 +73,7 @@
|
||||
./src/H5Mpublic.h
|
||||
./src/H5O.c
|
||||
./src/H5Ocont.c
|
||||
./src/H5Oistore.c
|
||||
./src/H5Oname.c
|
||||
./src/H5Onull.c
|
||||
./src/H5Oprivate.h
|
||||
@ -88,10 +90,14 @@
|
||||
./src/H5T.c
|
||||
./src/H5Tprivate.h
|
||||
./src/H5Tpublic.h
|
||||
./src/H5V.c
|
||||
./src/H5Vprivate.h
|
||||
./src/hdf5.h
|
||||
./src/Makefile.in
|
||||
./src/Naming-Conventions
|
||||
./test/Makefile.in
|
||||
./test/hyperslab.c
|
||||
./test/istore.c
|
||||
./test/testhdf5.c
|
||||
./test/testhdf5.h
|
||||
./test/tfile.c
|
||||
|
@ -73,7 +73,7 @@ distclean:
|
||||
(cd $$d && $(MAKE) $@) || exit 1; \
|
||||
done
|
||||
$(RM) config/commence config/conclude config/depend
|
||||
$(RM) config.cache config.log config.status src/config.h
|
||||
$(RM) config.cache config.log config.status src/H5config.h
|
||||
$(RM) Makefile
|
||||
|
||||
maintainer-clean:
|
||||
@ -82,8 +82,8 @@ maintainer-clean:
|
||||
@@SETX@; for d in $(SUBDIRS); do \
|
||||
(cd $$d && $(MAKE) $@) || exit 1; \
|
||||
done
|
||||
$(RM) config.cache config.log config.status src/config.h
|
||||
$(RM) configure src/config.h.in
|
||||
$(RM) config.cache config.log config.status src/H5config.h
|
||||
$(RM) configure src/H5config.h.in
|
||||
|
||||
|
||||
# This file does not end with the `CONCLUDE' statement since it has
|
||||
|
5
acconfig.h
Normal file
5
acconfig.h
Normal file
@ -0,0 +1,5 @@
|
||||
/* Define if the __attribute__(()) extension is present */
|
||||
/* #define HAVE_ATTRIBUTE */
|
||||
|
||||
/* Define if the compiler understands the __FUNCTION__ keyword. */
|
||||
/* #define HAVE_FUNCTION */
|
@ -23,7 +23,7 @@ TAGS: $(LIB_SRC)
|
||||
test: $(PROGS)
|
||||
@for test in $(TESTS) dummy; do \
|
||||
if test $$test != dummy; then \
|
||||
echo "$$test $(TEST_FLAGS)"; \
|
||||
echo "Testing $$test $(TEST_FLAGS)"; \
|
||||
$$test $(TEST_FLAGS) || exit 1; \
|
||||
fi; \
|
||||
done;
|
||||
@ -68,7 +68,7 @@ clean: mostlyclean
|
||||
# in the distribution.
|
||||
#
|
||||
distclean: clean
|
||||
$(RM) .depend TAGS
|
||||
$(RM) .depend TAGS *~ core *.bak *.old *.new
|
||||
@if test -f Makefile.in; then \
|
||||
(set -x; $(RM) Makefile); \
|
||||
fi
|
||||
|
13
config/linux
13
config/linux
@ -1,6 +1,17 @@
|
||||
# Site configuration -- do not distribute this file.
|
||||
|
||||
CFLAGS_WARN="-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
|
||||
|
||||
CFLAGS_DEBUG="-g -DH5AC_DEBUG_PROTECT -DFILELIB=1 -fverbose-asm"
|
||||
CFLAGS_PROFILE="-pg"
|
||||
CFLAGS_PRODUCTION="-O3 -UH5AC_DEBUG_PROTECT -DNDEBUG -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"
|
||||
|
||||
if test "x$CFLAGS" = "x"; then
|
||||
CFLAGS="-g -DH5AC_DEBUG_PROTECT -Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
|
||||
|
||||
# Uncomment the following line for a production version of the library.
|
||||
#CFLAGS="-pipe $CFLAGS_PRODUCTION $CFLAGS_WARN"
|
||||
|
||||
# Uncomment the following line for normal development
|
||||
CFLAGS="-pipe $CFLAGS_DEBUG $CFLAGS_WARN"
|
||||
fi
|
||||
|
||||
|
18
configure.in
18
configure.in
@ -105,9 +105,21 @@ AC_CHECK_SIZEOF(double, 8)
|
||||
|
||||
|
||||
dnl ----------------------------------------------------------------------
|
||||
dnl AC_FUNC_MEMCMP
|
||||
dnl AC_C_CONST
|
||||
dnl AC_C_INLINE
|
||||
dnl Check compiler characteristics
|
||||
dnl
|
||||
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
|
||||
AC_MSG_CHECKING(for __attribute__ extension)
|
||||
AC_TRY_COMPILE(,[int __attribute__((unused)) f(void){return 1;}],
|
||||
AC_DEFINE(HAVE_ATTRIBUTE) AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_MSG_CHECKING(for __FUNCTION__ extension)
|
||||
AC_TRY_COMPILE(,[int f(void){return __FUNCTION__;}],
|
||||
AC_DEFINE(HAVE_FUNCTION) AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
|
||||
|
||||
|
@ -276,7 +276,7 @@ done:
|
||||
|
||||
*******************************************************************************/
|
||||
hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in */
|
||||
const VOIDP object /* IN: Object to attach to atom */
|
||||
const void *object /* IN: Object to attach to atom */
|
||||
)
|
||||
{
|
||||
atom_group_t *grp_ptr=NULL; /* ptr to the atomic group */
|
||||
|
26
src/H5AC.c
26
src/H5AC.c
@ -143,10 +143,12 @@ H5AC_dest (H5F_t *f)
|
||||
*
|
||||
* Purpose: Given an object type and the address at which that object
|
||||
* is located in the file, return a pointer to the object.
|
||||
* The optional UDATA structure is passed down to the function
|
||||
* that is responsible for loading the object into memory.
|
||||
* The pointer is guaranteed to be valid until the next call
|
||||
* to an H5AC function (if you want a pointer which is valid
|
||||
* The optional UDATA1 and UDATA2 structures are passed down to
|
||||
* the function that is responsible for loading the object into
|
||||
* memory.
|
||||
*
|
||||
* The returned pointer is guaranteed to be valid until the next
|
||||
* call to an H5AC function (if you want a pointer which is valid
|
||||
* indefinately then see H5AC_protect()).
|
||||
*
|
||||
* If H5AC_DEBUG_PROTECT is defined then this function also
|
||||
@ -175,7 +177,8 @@ H5AC_dest (H5F_t *f)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void *
|
||||
H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
|
||||
H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
void *udata1, void *udata2)
|
||||
{
|
||||
unsigned idx;
|
||||
herr_t status;
|
||||
@ -228,7 +231,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
|
||||
* Load a new thing. If it can't be loaded, then return an error
|
||||
* without preempting anything.
|
||||
*/
|
||||
if (NULL==(thing=(type->load)(f, addr, udata))) {
|
||||
if (NULL==(thing=(type->load)(f, addr, udata1, udata2))) {
|
||||
HRETURN_ERROR (H5E_CACHE, H5E_CANTLOAD, NULL);
|
||||
}
|
||||
|
||||
@ -272,7 +275,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
|
||||
* Failure: never fails
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -604,7 +607,7 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Sep 2 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -612,7 +615,8 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void *
|
||||
H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
|
||||
H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
void *udata1, void *udata2)
|
||||
{
|
||||
int idx;
|
||||
void *thing = NULL;
|
||||
@ -663,7 +667,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
|
||||
* Load a new thing. If it can't be loaded, then return an error
|
||||
* without preempting anything.
|
||||
*/
|
||||
if (NULL==(thing=(type->load)(f, addr, udata))) {
|
||||
if (NULL==(thing=(type->load)(f, addr, udata1, udata2))) {
|
||||
HRETURN_ERROR (H5E_CACHE, H5E_CANTLOAD, NULL);
|
||||
}
|
||||
}
|
||||
@ -706,7 +710,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *udata)
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Sep 2 1997
|
||||
*
|
||||
* Modifications:
|
||||
|
@ -39,7 +39,7 @@
|
||||
* by the LOAD method if the DEST argument is non-zero.
|
||||
*/
|
||||
typedef struct H5AC_class_t {
|
||||
void *(*load)(H5F_t*, haddr_t addr, void *udata);
|
||||
void *(*load)(H5F_t*, haddr_t addr, void *udata1, void *udata2);
|
||||
herr_t (*flush)(H5F_t*, hbool_t dest, haddr_t addr, void *thing);
|
||||
} H5AC_class_t;
|
||||
|
||||
@ -78,9 +78,9 @@ typedef struct H5AC_t {
|
||||
*/
|
||||
herr_t H5AC_dest (H5F_t *f);
|
||||
void *H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
void *udata);
|
||||
void *udata1, void *udata2);
|
||||
void * H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
void *udata);
|
||||
void *udata1, void *udata2);
|
||||
herr_t H5AC_unprotect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
void *thing);
|
||||
herr_t H5AC_flush (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
@ -91,11 +91,11 @@ herr_t H5AC_rename (H5F_t *f, const H5AC_class_t *type, haddr_t old,
|
||||
herr_t H5AC_set (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
|
||||
void *thing);
|
||||
|
||||
#define H5AC_find(F,TYPE,ADDR,UDATA) \
|
||||
#define H5AC_find(F,TYPE,ADDR,UDATA1,UDATA2) \
|
||||
(((F)->shared->cache->slot[H5AC_HASH(F,ADDR)].type==(TYPE) && \
|
||||
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)].addr==(ADDR)) ? \
|
||||
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)].thing : \
|
||||
H5AC_find_f (F, TYPE, ADDR, UDATA))
|
||||
H5AC_find_f (F, TYPE, ADDR, UDATA1, UDATA2))
|
||||
|
||||
|
||||
#endif /* !_H5ACprivate_H */
|
||||
|
@ -110,7 +110,7 @@ intn H5Adestroy_group(group_t grp /* IN: Group to destroy */
|
||||
|
||||
*******************************************************************************/
|
||||
hid_t H5Aregister_atom(group_t grp, /* IN: Group to register the object in */
|
||||
const VOIDP object /* IN: Object to attach to atom */
|
||||
const void *object /* IN: Object to attach to atom */
|
||||
);
|
||||
|
||||
/******************************************************************************
|
||||
|
373
src/H5B.c
373
src/H5B.c
@ -100,21 +100,23 @@
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static haddr_t H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
H5B_ins_t *anchor,
|
||||
uint8 *lt_key, hbool_t *lt_key_changed,
|
||||
uint8 *md_key, void *udata,
|
||||
uint8 *rt_key, hbool_t *rt_key_changed);
|
||||
static herr_t H5B_insert_child (H5F_t *f, const H5B_class_t *type,
|
||||
H5B_t *bt, intn idx, haddr_t child,
|
||||
intn anchor, void *md_key);
|
||||
H5B_ins_t anchor, void *md_key);
|
||||
static herr_t H5B_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *b);
|
||||
static H5B_t *H5B_load (H5F_t *f, haddr_t addr, void *_data);
|
||||
static H5B_t *H5B_load (H5F_t *f, haddr_t addr, void *_type, void *udata);
|
||||
static herr_t H5B_decode_key (H5F_t *f, H5B_t *bt, intn idx);
|
||||
static herr_t H5B_decode_keys (H5F_t *f, H5B_t *bt, intn idx);
|
||||
static size_t H5B_nodesize (H5F_t *f, const H5B_class_t *type,
|
||||
size_t *total_nkey_size, size_t sizeof_rkey);
|
||||
|
||||
/* H5B inherits cache-like properties from H5AC */
|
||||
static const H5AC_class_t H5AC_BT[1] = {{
|
||||
(void*(*)(H5F_t*,haddr_t,void*))H5B_load,
|
||||
(void*(*)(H5F_t*,haddr_t,void*,void*))H5B_load,
|
||||
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5B_flush,
|
||||
}};
|
||||
|
||||
@ -125,7 +127,9 @@ static interface_initialize_g = FALSE;
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5B_new
|
||||
*
|
||||
* Purpose: Creates a new empty B-tree leaf node.
|
||||
* Purpose: Creates a new empty B-tree leaf node. The UDATA pointer is
|
||||
* passed as an argument to the sizeof_rkey() method for the
|
||||
* B-tree.
|
||||
*
|
||||
* Return: Success: address of new node.
|
||||
*
|
||||
@ -140,7 +144,7 @@ static interface_initialize_g = FALSE;
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
haddr_t
|
||||
H5B_new (H5F_t *f, const H5B_class_t *type)
|
||||
H5B_new (H5F_t *f, const H5B_class_t *type, void *udata)
|
||||
{
|
||||
H5B_t *bt=NULL;
|
||||
haddr_t addr;
|
||||
@ -159,7 +163,7 @@ H5B_new (H5F_t *f, const H5B_class_t *type)
|
||||
/*
|
||||
* Allocate file and memory data structures.
|
||||
*/
|
||||
sizeof_rkey = (type->get_sizeof_rkey)(f);
|
||||
sizeof_rkey = (type->get_sizeof_rkey)(f, udata);
|
||||
size = H5B_nodesize (f, type, &total_native_keysize, sizeof_rkey);
|
||||
if ((addr = H5MF_alloc (f, size))<0) {
|
||||
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
|
||||
@ -229,9 +233,9 @@ H5B_new (H5F_t *f, const H5B_class_t *type)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5B_t *
|
||||
H5B_load (H5F_t *f, haddr_t addr, void *_data)
|
||||
H5B_load (H5F_t *f, haddr_t addr, void *_type, void *udata)
|
||||
{
|
||||
const H5B_class_t *type = (H5B_class_t *)_data;
|
||||
const H5B_class_t *type = (H5B_class_t *)_type;
|
||||
size_t size, total_nkey_size;
|
||||
H5B_t *bt = NULL;
|
||||
intn i;
|
||||
@ -247,7 +251,7 @@ H5B_load (H5F_t *f, haddr_t addr, void *_data)
|
||||
assert (type->get_sizeof_rkey);
|
||||
|
||||
bt = H5MM_xmalloc (sizeof(H5B_t));
|
||||
bt->sizeof_rkey = (type->get_sizeof_rkey)(f);
|
||||
bt->sizeof_rkey = (type->get_sizeof_rkey)(f, udata);
|
||||
size = H5B_nodesize (f, type, &total_nkey_size, bt->sizeof_rkey);
|
||||
bt->type = type;
|
||||
bt->dirty = FALSE;
|
||||
@ -375,7 +379,8 @@ H5B_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
|
||||
assert (bt->key[i].rkey == p);
|
||||
if (bt->key[i].dirty) {
|
||||
if (bt->key[i].nkey) {
|
||||
if ((bt->type->encode)(f, bt->key[i].rkey, bt->key[i].nkey)<0) {
|
||||
if ((bt->type->encode)(f, bt, bt->key[i].rkey,
|
||||
bt->key[i].nkey)<0) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTENCODE, FAIL);
|
||||
}
|
||||
}
|
||||
@ -464,21 +469,14 @@ H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
* Perform a binary search to locate the child which contains
|
||||
* the thing for which we're searching.
|
||||
*/
|
||||
if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
|
||||
if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
rt = bt->nchildren;
|
||||
|
||||
while (lt<rt && cmp) {
|
||||
idx = (lt + rt) / 2;
|
||||
|
||||
/* the left key */
|
||||
if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
|
||||
/* the right key */
|
||||
if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
|
||||
@ -522,9 +520,11 @@ done:
|
||||
* Function: H5B_split
|
||||
*
|
||||
* Purpose: Split a single node into two nodes. If anchor is
|
||||
* H5B_ANCHOR_LT then the new node gets the right half of
|
||||
* the old node. If anchor is H5B_ANCHOR_RT then the
|
||||
* new node gets the left half of the old node.
|
||||
* H5B_INS_RIGHT then the new node gets the right half of
|
||||
* the old node. If anchor is H5B_INS_LEFT then the
|
||||
* new node gets the left half of the old node. The UDATA
|
||||
* pointer is passed to the sizeof_rkey() method but is
|
||||
* otherwise unused.
|
||||
*
|
||||
* The OLD_BT argument is a pointer to a protected B-tree
|
||||
* node.
|
||||
@ -543,7 +543,7 @@ done:
|
||||
*/
|
||||
static haddr_t
|
||||
H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
|
||||
intn anchor)
|
||||
H5B_ins_t anchor, void *udata)
|
||||
{
|
||||
H5B_t *new_bt=NULL, *tmp_bt=NULL;
|
||||
haddr_t ret_value=FAIL, new_addr=FAIL;
|
||||
@ -558,21 +558,22 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
|
||||
assert (f);
|
||||
assert (type);
|
||||
assert (old_addr>=0);
|
||||
assert (H5B_INS_LEFT==anchor || H5B_INS_RIGHT==anchor);
|
||||
|
||||
/*
|
||||
* Initialize variables.
|
||||
*/
|
||||
assert (old_bt->nchildren == 2*H5B_K(f,type));
|
||||
recsize = old_bt->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
|
||||
delta = H5B_ANCHOR_LT==anchor ? H5B_K(f,type) : 0;
|
||||
delta = H5B_INS_RIGHT==anchor ? H5B_K(f,type) : 0;
|
||||
|
||||
/*
|
||||
* Create the new B-tree node.
|
||||
*/
|
||||
if ((new_addr = H5B_new (f, type))<0) {
|
||||
if ((new_addr = H5B_new (f, type, udata))<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
if (NULL==(new_bt=H5AC_protect (f, H5AC_BT, new_addr, type))) {
|
||||
if (NULL==(new_bt=H5AC_protect (f, H5AC_BT, new_addr, type, udata))) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
new_bt->level = old_bt->level;
|
||||
@ -606,12 +607,12 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
|
||||
/*
|
||||
* Truncate the old node.
|
||||
*/
|
||||
delta = H5B_ANCHOR_LT==anchor ? 0 : H5B_K(f,type);
|
||||
delta = H5B_INS_RIGHT==anchor ? 0 : H5B_K(f,type);
|
||||
old_bt->dirty = TRUE;
|
||||
old_bt->ndirty = BOUND (0, old_bt->ndirty-delta, H5B_K(f,type));
|
||||
old_bt->nchildren = H5B_K(f,type);
|
||||
|
||||
if (H5B_ANCHOR_RT==anchor) {
|
||||
if (H5B_INS_LEFT==anchor) {
|
||||
HDmemcpy (old_bt->page + H5B_SIZEOF_HDR(f),
|
||||
old_bt->page + H5B_SIZEOF_HDR(f) + delta*recsize,
|
||||
H5B_K(f,type) * recsize);
|
||||
@ -642,12 +643,13 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
|
||||
/*
|
||||
* Update sibling pointers.
|
||||
*/
|
||||
if (H5B_ANCHOR_LT==anchor) {
|
||||
if (H5B_INS_RIGHT==anchor) {
|
||||
new_bt->left = old_addr;
|
||||
new_bt->right = old_bt->right;
|
||||
|
||||
if (old_bt->right) {
|
||||
if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->right, type))) {
|
||||
if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->right, type,
|
||||
udata))) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
tmp_bt->dirty = TRUE;
|
||||
@ -659,7 +661,8 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
|
||||
new_bt->right = old_addr;
|
||||
|
||||
if (old_bt->left) {
|
||||
if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->left, type))) {
|
||||
if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->left, type,
|
||||
udata))) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
tmp_bt->dirty = TRUE;
|
||||
@ -702,7 +705,44 @@ H5B_decode_key (H5F_t *f, H5B_t *bt, intn idx)
|
||||
FUNC_ENTER (H5B_decode_key, NULL, FAIL);
|
||||
|
||||
bt->key[idx].nkey = bt->native + idx * bt->type->sizeof_nkey;
|
||||
if ((bt->type->decode)(f, bt->key[idx].rkey, bt->key[idx].nkey)<0) {
|
||||
if ((bt->type->decode)(f, bt, bt->key[idx].rkey,
|
||||
bt->key[idx].nkey)<0) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5B_decode_keys
|
||||
*
|
||||
* Purpose: Decode keys on either side of the specified branch.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Tuesday, October 14, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5B_decode_keys (H5F_t *f, H5B_t *bt, intn idx)
|
||||
{
|
||||
FUNC_ENTER (H5B_decode_keys, NULL, FAIL);
|
||||
|
||||
assert (f);
|
||||
assert (bt);
|
||||
assert (idx>=0 && idx<bt->nchildren);
|
||||
|
||||
if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
|
||||
@ -741,6 +781,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
size_t size;
|
||||
uint8 *buf;
|
||||
haddr_t tmp_addr;
|
||||
H5B_ins_t anchor = H5B_INS_ERROR;
|
||||
|
||||
FUNC_ENTER (H5B_insert, NULL, FAIL);
|
||||
|
||||
@ -749,17 +790,18 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
*/
|
||||
assert (f);
|
||||
assert (type);
|
||||
assert (type->sizeof_nkey < sizeof lt_key);
|
||||
assert (type->sizeof_nkey <= sizeof lt_key);
|
||||
|
||||
child = H5B_insert_helper (f, addr, type, lt_key, <_key_changed,
|
||||
child = H5B_insert_helper (f, addr, type, &anchor, lt_key, <_key_changed,
|
||||
md_key, udata, rt_key, &rt_key_changed);
|
||||
if (child<0) {
|
||||
if (child<0 || anchor<0) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
if (0==child) HRETURN (addr);
|
||||
if (H5B_INS_NOOP==anchor) HRETURN (addr);
|
||||
assert (H5B_INS_RIGHT==anchor);
|
||||
|
||||
/* the current root */
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type, udata))) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
level = bt->level;
|
||||
@ -771,7 +813,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
}
|
||||
|
||||
/* the new node */
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, child, type))) {
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, child, type, udata))) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
if (!rt_key_changed) {
|
||||
@ -812,14 +854,14 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
addr = tmp_addr;
|
||||
|
||||
/* update the new child's left pointer */
|
||||
if (NULL==(bt=H5AC_find (f, H5AC_BT, child, type))) {
|
||||
if (NULL==(bt=H5AC_find (f, H5AC_BT, child, type, udata))) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
bt->dirty = TRUE;
|
||||
bt->left = addr;
|
||||
|
||||
/* clear the old root at the old address */
|
||||
if (NULL==(bt=H5AC_find (f, H5AC_BT, new_root, type))) {
|
||||
if (NULL==(bt=H5AC_find (f, H5AC_BT, new_root, type, udata))) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
bt->dirty = TRUE;
|
||||
@ -830,7 +872,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
|
||||
|
||||
/* the new root */
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, new_root, type))) {
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, new_root, type, udata))) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
bt->dirty = TRUE;
|
||||
@ -877,7 +919,7 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
*/
|
||||
static herr_t
|
||||
H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
|
||||
intn idx, haddr_t child, intn anchor, void *md_key)
|
||||
intn idx, haddr_t child, H5B_ins_t anchor, void *md_key)
|
||||
{
|
||||
size_t recsize;
|
||||
intn i;
|
||||
@ -888,7 +930,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
|
||||
bt->dirty = TRUE;
|
||||
recsize = bt->sizeof_rkey + H5F_SIZEOF_OFFSET(f);
|
||||
|
||||
if (H5B_ANCHOR_LT==anchor) {
|
||||
if (H5B_INS_RIGHT==anchor) {
|
||||
/*
|
||||
* The MD_KEY is the left key of the new node.
|
||||
*/
|
||||
@ -950,6 +992,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5B_insert_helper
|
||||
@ -985,6 +1028,7 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
|
||||
*/
|
||||
static haddr_t
|
||||
H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
H5B_ins_t *parent_ins,
|
||||
uint8 *lt_key, hbool_t *lt_key_changed,
|
||||
uint8 *md_key, void *udata,
|
||||
uint8 *rt_key, hbool_t *rt_key_changed)
|
||||
@ -992,7 +1036,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
H5B_t *bt=NULL, *twin=NULL, *tmp_bt=NULL;
|
||||
intn lt=0, idx=-1, rt, cmp=-1;
|
||||
haddr_t child_addr=0, twin_addr=0, ret_value=FAIL;
|
||||
intn anchor;
|
||||
H5B_ins_t my_ins = H5B_INS_ERROR;
|
||||
|
||||
FUNC_ENTER (H5B_insert_helper, NULL, FAIL);
|
||||
|
||||
@ -1005,35 +1049,30 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
assert (type->decode);
|
||||
assert (type->cmp);
|
||||
assert (type->new);
|
||||
assert (parent_ins && H5B_INS_ERROR==*parent_ins);
|
||||
assert (lt_key);
|
||||
assert (lt_key_changed);
|
||||
assert (rt_key);
|
||||
assert (rt_key_changed);
|
||||
|
||||
*lt_key_changed = FALSE;
|
||||
*rt_key_changed = FALSE;
|
||||
|
||||
/*
|
||||
* Use a binary search to find the child that will receive the new
|
||||
* data. When the search completes IDX points to the child that
|
||||
* should get the new data.
|
||||
*/
|
||||
if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
|
||||
if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
rt = bt->nchildren;
|
||||
|
||||
while (lt<rt && cmp) {
|
||||
idx = (lt + rt) / 2;
|
||||
|
||||
/* left key */
|
||||
if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
|
||||
/* right key */
|
||||
if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
|
||||
/* compare */
|
||||
if ((cmp=(type->cmp)(f, bt->key[idx].nkey, udata,
|
||||
bt->key[idx+1].nkey))<0) {
|
||||
rt = idx;
|
||||
@ -1042,46 +1081,14 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
}
|
||||
}
|
||||
|
||||
if (cmp<0 && idx<=0) {
|
||||
/*
|
||||
* Boundary condition: the value to insert is the new minimum
|
||||
* value in the B-tree. Insert the value in the left-most node.
|
||||
*/
|
||||
idx = 0;
|
||||
cmp = 0;
|
||||
|
||||
} else if (cmp>0 && idx+1>=bt->nchildren) {
|
||||
/*
|
||||
* Boundary condition: the value to insert is the new maximum
|
||||
* value in the B-tree. Insert the value in the right-most node.
|
||||
*/
|
||||
idx = bt->nchildren-1;
|
||||
cmp = 0;
|
||||
}
|
||||
assert (0==cmp);
|
||||
|
||||
/*
|
||||
* Ensure that both native keys exist since we may have made boundary
|
||||
* condition adjustments.
|
||||
*/
|
||||
if (bt->nchildren) {
|
||||
if (!bt->key[idx].nkey && H5B_decode_key (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
if (!bt->key[idx+1].nkey && H5B_decode_key (f, bt, idx+1)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are no children, then create a new child. This can only
|
||||
* happen at the root of the B-tree. The left and right native keys
|
||||
* are output values from the node creation function.
|
||||
*/
|
||||
if (0==bt->nchildren) {
|
||||
/*
|
||||
* The value being inserted will be the only value in this tree. We
|
||||
* must necessarily be at level zero.
|
||||
*/
|
||||
assert (0==bt->level);
|
||||
bt->key[0].nkey = bt->native;
|
||||
bt->key[1].nkey = bt->native + type->sizeof_nkey;
|
||||
|
||||
if ((child_addr=(type->new)(f, bt->key[0].nkey, udata,
|
||||
bt->key[1].nkey))<0) {
|
||||
bt->key[0].nkey = bt->key[1].nkey = NULL;
|
||||
@ -1091,28 +1098,142 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
bt->dirty = TRUE;
|
||||
bt->ndirty = 1;
|
||||
bt->child[0] = child_addr;
|
||||
|
||||
bt->key[0].dirty = TRUE;
|
||||
bt->key[1].dirty = TRUE;
|
||||
idx = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the new data in the child B-tree node or in the data node.
|
||||
*/
|
||||
if (bt->level > 0) {
|
||||
child_addr = H5B_insert_helper (f, bt->child[idx], type,
|
||||
if (type->follow_min) {
|
||||
child_addr = (type->insert)(f, bt->child[idx], &my_ins,
|
||||
bt->key[idx].nkey, lt_key_changed,
|
||||
md_key, udata,
|
||||
bt->key[idx+1].nkey, rt_key_changed);
|
||||
} else {
|
||||
my_ins = H5B_INS_NOOP;
|
||||
}
|
||||
|
||||
} else if (cmp<0 && idx<=0 && bt->level>0) {
|
||||
/*
|
||||
* The value being inserted is less than any value in this tree. Follow
|
||||
* the minimum branch out of this node to a subtree.
|
||||
*/
|
||||
idx = 0;
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
|
||||
bt->key[idx].nkey, lt_key_changed,
|
||||
md_key, udata,
|
||||
bt->key[idx+1].nkey, rt_key_changed);
|
||||
anchor = H5B_ANCHOR_LT;
|
||||
} else {
|
||||
child_addr = (type->insert)(f, bt->child[idx], &anchor,
|
||||
|
||||
} else if (cmp<0 && idx<=0 && type->follow_min) {
|
||||
/*
|
||||
* The value being inserted is less than any leaf node out of this
|
||||
* current node. Follow the minimum branch to a leaf node and let the
|
||||
* subclass handle the problem.
|
||||
*/
|
||||
idx = 0;
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
child_addr = (type->insert)(f, bt->child[idx], &my_ins,
|
||||
bt->key[idx].nkey, lt_key_changed,
|
||||
md_key, udata,
|
||||
bt->key[idx+1].nkey, rt_key_changed);
|
||||
|
||||
} else if (cmp<0 && idx<=0) {
|
||||
/*
|
||||
* The value being inserted is less than any leaf node out of the
|
||||
* current node. Create a new minimum leaf node out of this B-tree
|
||||
* node. This node is not empty (handled above).
|
||||
*/
|
||||
idx = 0;
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
my_ins = H5B_INS_LEFT;
|
||||
HDmemcpy (md_key, bt->key[idx].nkey, type->sizeof_nkey);
|
||||
child_addr = (type->new)(f, bt->key[idx].nkey, udata, md_key);
|
||||
*lt_key_changed = TRUE;
|
||||
|
||||
} else if (cmp>0 && idx+1>=bt->nchildren && bt->level>0) {
|
||||
/*
|
||||
* The value being inserted is larger than any value in this tree.
|
||||
* Follow the maximum branch out of this node to a subtree.
|
||||
*/
|
||||
idx = bt->nchildren - 1;
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
|
||||
bt->key[idx].nkey, lt_key_changed,
|
||||
md_key, udata,
|
||||
bt->key[idx+1].nkey, rt_key_changed);
|
||||
|
||||
} else if (cmp>0 && idx+1>=bt->nchildren && type->follow_max) {
|
||||
/*
|
||||
* The value being inserted is larger than any leaf node out of the
|
||||
* current node. Follow the maximum branch to a leaf node and let the
|
||||
* subclass handle the problem.
|
||||
*/
|
||||
idx = bt->nchildren - 1;
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
child_addr = (type->insert)(f, bt->child[idx], &my_ins,
|
||||
bt->key[idx].nkey, lt_key_changed,
|
||||
md_key, udata,
|
||||
bt->key[idx+1].nkey, rt_key_changed);
|
||||
|
||||
} else if (cmp>0 && idx+1>=bt->nchildren) {
|
||||
/*
|
||||
* The value being inserted is larger than any leaf node out of the
|
||||
* current node. Create a new maximum leaf node out of this B-tree
|
||||
* node.
|
||||
*/
|
||||
idx = bt->nchildren - 1;
|
||||
if (H5B_decode_keys (f, bt, idx)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
my_ins = H5B_INS_RIGHT;
|
||||
HDmemcpy (md_key, bt->key[idx+1].nkey, type->sizeof_nkey);
|
||||
child_addr = (type->new)(f, md_key, udata, bt->key[idx+1].nkey);
|
||||
*rt_key_changed = TRUE;
|
||||
|
||||
} else if (cmp) {
|
||||
/*
|
||||
* We couldn't figure out which branch to follow out of this node. THIS
|
||||
* IS A MAJOR PROBLEM THAT NEEDS TO BE FIXED --rpm.
|
||||
*/
|
||||
assert ("INTERNAL HDF5 ERROR (see rpm)" && 0);
|
||||
|
||||
} else if (bt->level>0) {
|
||||
/*
|
||||
* Follow a branch out of this node to another subtree.
|
||||
*/
|
||||
assert (idx>=0 && idx<bt->nchildren);
|
||||
child_addr = H5B_insert_helper (f, bt->child[idx], type, &my_ins,
|
||||
bt->key[idx].nkey, lt_key_changed,
|
||||
md_key, udata,
|
||||
bt->key[idx+1].nkey, rt_key_changed);
|
||||
|
||||
|
||||
} else {
|
||||
/*
|
||||
* Follow a branch out of this node to a leaf node of some other type.
|
||||
*/
|
||||
assert (idx>=0 && idx<bt->nchildren);
|
||||
child_addr = (type->insert)(f, bt->child[idx], &my_ins,
|
||||
bt->key[idx].nkey, lt_key_changed,
|
||||
md_key, udata,
|
||||
bt->key[idx+1].nkey, rt_key_changed);
|
||||
|
||||
}
|
||||
if (child_addr<0) HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
|
||||
|
||||
if (child_addr<0 || my_ins<0) {
|
||||
/* Insertion failed */
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Update the left and right keys of the current node.
|
||||
@ -1136,36 +1257,43 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the child, splitting the current node if necessary.
|
||||
*/
|
||||
if (child_addr) {
|
||||
if (H5B_INS_CHANGE==my_ins) {
|
||||
/*
|
||||
* If the child split and the left node is anchored, then the new
|
||||
* The insertion simply changed the address for the child.
|
||||
*/
|
||||
bt->child[idx] = child_addr;
|
||||
bt->dirty = TRUE;
|
||||
bt->ndirty = MAX (bt->ndirty, idx+1);
|
||||
*parent_ins = H5B_INS_NOOP;
|
||||
|
||||
} else if (H5B_INS_LEFT==my_ins || H5B_INS_RIGHT==my_ins) {
|
||||
/*
|
||||
* The child split. If the left node is anchored, then the new
|
||||
* child node gets inserted to the right of our current position.
|
||||
*/
|
||||
if (H5B_ANCHOR_LT==anchor) idx++;
|
||||
if (H5B_INS_RIGHT==my_ins) idx++;
|
||||
|
||||
if (bt->nchildren==2*H5B_K(f,type)) {
|
||||
/* Split the current node */
|
||||
if ((twin_addr = H5B_split (f, type, bt, addr, anchor))<0) {
|
||||
if ((twin_addr = H5B_split (f, type, bt, addr, my_ins, udata))<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);
|
||||
}
|
||||
if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type))) {
|
||||
if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type,
|
||||
udata))) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
if (idx<=H5B_K(f,type)) {
|
||||
tmp_bt = H5B_ANCHOR_LT==anchor ? bt : twin;
|
||||
tmp_bt = H5B_INS_RIGHT==my_ins ? bt : twin;
|
||||
} else {
|
||||
idx -= H5B_K (f, type);
|
||||
tmp_bt = H5B_ANCHOR_LT==anchor ? twin : bt;
|
||||
tmp_bt = H5B_INS_RIGHT==my_ins ? twin : bt;
|
||||
}
|
||||
} else {
|
||||
tmp_bt = bt;
|
||||
}
|
||||
|
||||
if (H5B_insert_child (f, type, tmp_bt, idx, child_addr, anchor,
|
||||
if (H5B_insert_child (f, type, tmp_bt, idx, child_addr, my_ins,
|
||||
md_key)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
|
||||
}
|
||||
@ -1177,7 +1305,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
* by the left and right node).
|
||||
*/
|
||||
if (twin) {
|
||||
if (H5B_ANCHOR_LT==anchor) {
|
||||
if (H5B_INS_RIGHT==my_ins) {
|
||||
if (!twin->key[0].nkey && H5B_decode_key (f, twin, 0)<0) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
|
||||
}
|
||||
@ -1188,7 +1316,11 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
|
||||
}
|
||||
HDmemcpy (md_key, bt->key[0].nkey, type->sizeof_nkey);
|
||||
}
|
||||
*parent_ins = H5B_INS_RIGHT;
|
||||
} else {
|
||||
*parent_ins = H5B_INS_NOOP;
|
||||
}
|
||||
|
||||
HGOTO_DONE (twin_addr);
|
||||
|
||||
done:
|
||||
@ -1241,7 +1373,7 @@ H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
assert (addr>=0);
|
||||
assert (udata);
|
||||
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type))) {
|
||||
if (NULL==(bt = H5AC_find (f, H5AC_BT, addr, type, udata))) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -1254,7 +1386,7 @@ H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
|
||||
} else {
|
||||
|
||||
for (/*void*/; addr>0; addr=next_addr) {
|
||||
if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type))) {
|
||||
if (NULL==(bt=H5AC_protect (f, H5AC_BT, addr, type, udata))) {
|
||||
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -1318,6 +1450,7 @@ H5B_nodesize (H5F_t *f, const H5B_class_t *type,
|
||||
assert (f);
|
||||
assert (type);
|
||||
assert (sizeof_rkey>0);
|
||||
assert (H5B_K (f, type)>0);
|
||||
|
||||
/*
|
||||
* Total native key size.
|
||||
@ -1356,7 +1489,7 @@ H5B_nodesize (H5F_t *f, const H5B_class_t *type,
|
||||
*/
|
||||
herr_t
|
||||
H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
|
||||
intn fwidth, H5B_class_t *type)
|
||||
intn fwidth, H5B_class_t *type, void *udata)
|
||||
{
|
||||
H5B_t *bt = NULL;
|
||||
int i;
|
||||
@ -1376,7 +1509,7 @@ H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
|
||||
/*
|
||||
* Load the tree node.
|
||||
*/
|
||||
if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type))) {
|
||||
if (NULL==(bt=H5AC_find (f, H5AC_BT, addr, type, udata))) {
|
||||
HRETURN_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,17 @@
|
||||
#define H5B_K(F,TYPE) /*K value given file and Btree subclass */ \
|
||||
((F)->shared->file_create_parms.btree_k[(TYPE)->id])
|
||||
|
||||
#define H5B_ANCHOR_LT 0 /* left node is anchored, right is new */
|
||||
#define H5B_ANCHOR_RT 1 /* right node is anchored, left is new */
|
||||
typedef enum H5B_ins_t {
|
||||
H5B_INS_ERROR =-1, /*error return value */
|
||||
H5B_INS_NOOP =0, /*insert made no changes */
|
||||
H5B_INS_LEFT =1, /*insert new node to left of cur node */
|
||||
H5B_INS_RIGHT =2, /*insert new node to right of cur node */
|
||||
H5B_INS_CHANGE =3 /*change child address for cur node */
|
||||
} H5B_ins_t;
|
||||
|
||||
typedef enum H5B_subid_t {
|
||||
H5B_SNODE_ID =0 /*B-tree is for symbol table nodes */
|
||||
H5B_SNODE_ID =0, /*B-tree is for symbol table nodes */
|
||||
H5B_ISTORE_ID =1 /*B-tree is for indexed object storage */
|
||||
} H5B_subid_t;
|
||||
|
||||
|
||||
@ -48,18 +54,21 @@ typedef enum H5B_subid_t {
|
||||
* has an array of K values indexed by the `id' class field below. The
|
||||
* array is initialized with the HDF5_BTREE_K_DEFAULT macro.
|
||||
*/
|
||||
struct H5B_t; /*forward decl*/
|
||||
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)(H5F_t*);
|
||||
haddr_t (*new)(H5F_t*,void*,void*,void*);
|
||||
intn (*cmp)(H5F_t*,void*,void*,void*);
|
||||
size_t (*get_sizeof_rkey)(H5F_t*,const void*);/*raw key size */
|
||||
haddr_t (*new)(H5F_t*,void*,void*,void*); /*create new leaf */
|
||||
intn (*cmp)(H5F_t*,void*,void*,void*); /*compare keys */
|
||||
herr_t (*found)(H5F_t*,haddr_t,const void*,void*,const void*);
|
||||
haddr_t (*insert)(H5F_t*,haddr_t,int*,void*,hbool_t*,void*,void*,
|
||||
void*,hbool_t*);
|
||||
herr_t (*list)(H5F_t*,haddr_t,void*);
|
||||
herr_t (*decode)(H5F_t*,uint8*,void*);
|
||||
herr_t (*encode)(H5F_t*,uint8*,void*);
|
||||
haddr_t (*insert)(H5F_t*,haddr_t,H5B_ins_t*,void*,hbool_t*,void*,void*,
|
||||
void*,hbool_t*); /*insert new data */
|
||||
hbool_t follow_min; /*min insert uses min leaf, not new() */
|
||||
hbool_t follow_max; /*max insert uses max leaf, not new() */
|
||||
herr_t (*list)(H5F_t*,haddr_t,void*); /*traverse leaf nodes */
|
||||
herr_t (*decode)(H5F_t*,struct H5B_t*,uint8*,void*);
|
||||
herr_t (*encode)(H5F_t*,struct H5B_t*,uint8*,void*);
|
||||
} H5B_class_t;
|
||||
|
||||
/*
|
||||
@ -91,8 +100,8 @@ typedef struct H5B_t {
|
||||
* Library prototypes.
|
||||
*/
|
||||
herr_t H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
|
||||
intn fwidth, H5B_class_t *type);
|
||||
haddr_t H5B_new (H5F_t *f, const H5B_class_t *type);
|
||||
intn fwidth, H5B_class_t *type, void *udata);
|
||||
haddr_t H5B_new (H5F_t *f, const H5B_class_t *type, void *udata);
|
||||
herr_t H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
|
||||
haddr_t H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
|
||||
herr_t H5B_list (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata);
|
||||
|
20
src/H5C.c
20
src/H5C.c
@ -146,7 +146,7 @@ hid_t H5C_get_default_atom(hobjtype_t type)
|
||||
case H5_TEMPLATE:
|
||||
if(default_file_id==FAIL)
|
||||
{
|
||||
if((default_file_id=H5Aregister_atom(H5_TEMPLATE, (const VOIDP)&default_file_create))==FAIL)
|
||||
if((default_file_id=H5Aregister_atom(H5_TEMPLATE, (const void *)&default_file_create))==FAIL)
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL);
|
||||
} /* end else */
|
||||
HGOTO_DONE(default_file_id);
|
||||
@ -324,6 +324,9 @@ done:
|
||||
Robb Matzke, 13 Aug 1997
|
||||
Removed H5_BTREE_SIZE and replaced it with H5_SYM_LEAF_K and
|
||||
H5_SYM_INTERN_K.
|
||||
|
||||
Robb Matzke, 17 Oct 1997
|
||||
Added H5_ISTORE_K.
|
||||
--------------------------------------------------------------------------*/
|
||||
herr_t H5Cgetparm(hid_t tid, file_create_param_t parm, VOIDP buf)
|
||||
{
|
||||
@ -365,6 +368,10 @@ herr_t H5Cgetparm(hid_t tid, file_create_param_t parm, VOIDP buf)
|
||||
*(uintn *)buf = template->btree_k[H5B_SNODE_ID];
|
||||
break;
|
||||
|
||||
case H5_ISTORE_K:
|
||||
*(uintn *)buf = template->btree_k[H5B_ISTORE_ID];
|
||||
break;
|
||||
|
||||
case H5_BOOTBLOCK_VER:
|
||||
*(uint8 *)buf=template->bootblock_ver;
|
||||
break;
|
||||
@ -430,6 +437,9 @@ done:
|
||||
|
||||
Robb Matzke, 15 Sep 1997
|
||||
Fixed the power-of-two test to work with any size integer.
|
||||
|
||||
Robb Matzke, 17 Oct 1997
|
||||
Added H5_ISTORE_K.
|
||||
--------------------------------------------------------------------------*/
|
||||
herr_t H5Csetparm(hid_t tid, file_create_param_t parm, const VOIDP buf)
|
||||
{
|
||||
@ -494,6 +504,14 @@ herr_t H5Csetparm(hid_t tid, file_create_param_t parm, const VOIDP buf)
|
||||
}
|
||||
template->btree_k[H5B_SNODE_ID] = val;
|
||||
break;
|
||||
|
||||
case H5_ISTORE_K:
|
||||
val = *(const uintn *)buf;
|
||||
if (val<2) {
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);
|
||||
}
|
||||
template->btree_k[H5B_ISTORE_ID] = val;
|
||||
break;
|
||||
|
||||
case H5_BOOTBLOCK_VER: /* this should be range checked */
|
||||
template->bootblock_ver=*(const uint8 *)buf;
|
||||
|
@ -34,7 +34,7 @@
|
||||
|
||||
#define H5C_BTREE_K_DEFAULT { \
|
||||
16, /* Symbol table internal nodes */ \
|
||||
0, /* unused */ \
|
||||
32, /* Indexed storage intern nodes */ \
|
||||
0, /* unused */ \
|
||||
0, /* unused */ \
|
||||
0, /* unused */ \
|
||||
|
@ -37,6 +37,7 @@ typedef enum {
|
||||
H5_LENGTH_SIZE, /* (uint8) Number of bytes for lengths */
|
||||
H5_SYM_LEAF_K, /* (uintn) 1/2 rank for symbol table leaf nodes */
|
||||
H5_SYM_INTERN_K, /* (uintn) 1/2 rank for symbol table internal nodes */
|
||||
H5_ISTORE_K, /* (uintn) 1/2 rank for indexed storage nodes */
|
||||
H5_BOOTBLOCK_VER, /* (uint8) Version # of the boot-block format */
|
||||
H5_SMALLOBJECT_VER, /* (uint8) Version # of the small-object heap format */
|
||||
H5_FREESPACE_VER, /* (uint8) Version # of the free-space info format */
|
||||
|
@ -158,7 +158,7 @@ hid_t H5D_create(hid_t owner_id, hobjtype_t type, const char *name)
|
||||
|
||||
/* Open (and create) a new file object */
|
||||
if (NULL==(new_dset->ent = H5G_create (file, name, H5D_MINHDR_SIZE))) {
|
||||
HGOTO_ERROR (H5E_DIRECTORY, H5E_CANTINIT, FAIL);
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
|
||||
/* Register the new datatype and get an ID for it */
|
||||
@ -183,14 +183,14 @@ done:
|
||||
Get the OID for accessing an existing HDF5 dataset object
|
||||
USAGE
|
||||
hoid_t H5D_find_name(grp_id, type, name)
|
||||
hid_t grp_id; IN: Atom for directory to search for dataset
|
||||
hid_t grp_id; IN: Atom for group to search for dataset
|
||||
hobjtype_t type; IN: Type of object to search for (dataset in
|
||||
this case)
|
||||
const char *name; IN: Name of the object to search for
|
||||
RETURNS
|
||||
Returns ID (atom) on success, FAIL on failure
|
||||
DESCRIPTION
|
||||
This function finds for a dataset by name in a directory.
|
||||
This function finds for a dataset by name in a group.
|
||||
--------------------------------------------------------------------------*/
|
||||
hid_t H5D_find_name(hid_t grp_id, hobjtype_t obj_type, const char *name)
|
||||
{
|
||||
@ -215,7 +215,7 @@ hid_t H5D_find_name(hid_t grp_id, hobjtype_t obj_type, const char *name)
|
||||
if(NULL==(dset=HDcalloc(1, sizeof(H5D_t))))
|
||||
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL);
|
||||
|
||||
/* Initialize file, directory, name fields */
|
||||
/* Initialize file, group, name fields */
|
||||
dset->file = file;
|
||||
dset->dirty = FALSE;
|
||||
|
||||
|
740
src/H5Distore.c
Normal file
740
src/H5Distore.c
Normal file
@ -0,0 +1,740 @@
|
||||
/*
|
||||
* Copyright (C) 1997 Spizella Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Programmer: Robb Matzke <robb@arborea.spizella.com>
|
||||
* Wednesday, October 8, 1997
|
||||
*/
|
||||
#include <H5private.h>
|
||||
#include <H5Eprivate.h>
|
||||
#include <H5Fprivate.h>
|
||||
#include <H5MFprivate.h>
|
||||
#include <H5MMprivate.h>
|
||||
#include <H5Oprivate.h>
|
||||
#include <H5Vprivate.h>
|
||||
|
||||
typedef enum H5F_isop_t {
|
||||
H5F_ISTORE_READ, /*read from file to memory */
|
||||
H5F_ISTORE_WRITE /*write from memory to file */
|
||||
} H5F_isop_t;
|
||||
|
||||
/* Does the array domain include negative indices? */
|
||||
#undef H5F_ISTORE_NEGATIVE_DOMAIN
|
||||
|
||||
|
||||
#define PABLO_MASK H5F_istore_mask
|
||||
|
||||
/* Is the interface initialized? */
|
||||
static hbool_t interface_initialize_g = FALSE;
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
|
||||
static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
|
||||
void *_rt_key);
|
||||
static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
|
||||
void *_rt_key);
|
||||
static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
|
||||
void *_udata, const void *_rt_key);
|
||||
static haddr_t H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
|
||||
void *_lt_key, hbool_t *lt_key_changed,
|
||||
void *_md_key, void *_udata,
|
||||
void *_rt_key, hbool_t *rt_key_changed);
|
||||
static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
|
||||
void *_key);
|
||||
static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
|
||||
void *_key);
|
||||
static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
|
||||
H5F_isop_t op, size_t offset_f[],
|
||||
size_t size[], size_t offset_m[],
|
||||
size_t size_m[], void *buf);
|
||||
|
||||
|
||||
/*
|
||||
* B-tree key. A key contains the minimum logical N-dimensional address and
|
||||
* the logical size of the chunk to which this key refers. The
|
||||
* fastest-varying dimension is assumed to reference individual bytes of the
|
||||
* array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
|
||||
* array with the slow varying dimension of size 100 and the fast varying
|
||||
* dimension of size 4 (the storage dimensionality has very little to do with
|
||||
* the real dimensionality).
|
||||
*
|
||||
* Only the first few values of the OFFSET and SIZE fields are actually
|
||||
* stored on disk, depending on the dimensionality.
|
||||
*
|
||||
* The storage file address is part of the B-tree and not part of the key.
|
||||
*/
|
||||
typedef struct H5F_istore_key_t {
|
||||
size_t offset[H5O_ISTORE_NDIMS]; /*logical offset to start*/
|
||||
size_t size[H5O_ISTORE_NDIMS]; /*logical chunk size */
|
||||
} H5F_istore_key_t;
|
||||
|
||||
typedef struct H5F_istore_ud1_t {
|
||||
H5F_istore_key_t key; /*key values */
|
||||
haddr_t addr; /*file address of chunk */
|
||||
H5O_istore_t mesg; /*storage message */
|
||||
} H5F_istore_ud1_t;
|
||||
|
||||
/* inherits B-tree like properties from H5B */
|
||||
H5B_class_t H5B_ISTORE[1] = {{
|
||||
H5B_ISTORE_ID, /*id */
|
||||
sizeof (H5F_istore_key_t), /*sizeof_nkey */
|
||||
H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
|
||||
H5F_istore_new, /*new */
|
||||
H5F_istore_cmp, /*cmp */
|
||||
H5F_istore_found, /*found */
|
||||
H5F_istore_insert, /*insert */
|
||||
FALSE, /*follow min branch? */
|
||||
FALSE, /*follow max branch? */
|
||||
NULL, /*list */
|
||||
H5F_istore_decode_key, /*decode */
|
||||
H5F_istore_encode_key, /*encode */
|
||||
}};
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_sizeof_rkey
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static size_t
|
||||
H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata)
|
||||
{
|
||||
const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *)_udata;
|
||||
|
||||
assert (udata);
|
||||
assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
|
||||
|
||||
return udata->mesg.ndims * (4 + 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_decode_key
|
||||
*
|
||||
* Purpose: Decodes a raw key into a native key for the B-tree
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, October 10, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
|
||||
{
|
||||
H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
|
||||
int i;
|
||||
int ndims = bt->sizeof_rkey / 8;
|
||||
|
||||
FUNC_ENTER (H5F_istore_decode_key, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (bt);
|
||||
assert (raw);
|
||||
assert (key);
|
||||
assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
|
||||
|
||||
/* decode */
|
||||
for (i=0; i<ndims; i++) {
|
||||
UINT32DECODE (raw, key->offset[i]);
|
||||
UINT32DECODE (raw, key->size[i]);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_encode_key
|
||||
*
|
||||
* Purpose: Encode a key from native format to raw format.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, October 10, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
|
||||
{
|
||||
H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
|
||||
intn ndims = bt->sizeof_rkey / 8;
|
||||
intn i;
|
||||
|
||||
FUNC_ENTER (H5F_istore_encode_key, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (bt);
|
||||
assert (raw);
|
||||
assert (key);
|
||||
assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
|
||||
|
||||
/* encode */
|
||||
for (i=0; i<ndims; i++) {
|
||||
UINT32ENCODE (raw, key->offset[i]);
|
||||
UINT32ENCODE (raw, key->size[i]);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_cmp
|
||||
*
|
||||
* Purpose: Compare the requested datum UDATA with the left and right
|
||||
* keys of the B-tree.
|
||||
*
|
||||
* Return: Success: negative if the min_corner of UDATA is less
|
||||
* than the min_corner of LT_KEY.
|
||||
*
|
||||
* positive if the min_corner of UDATA is
|
||||
* greater than or equal the min_corner of
|
||||
* RT_KEY.
|
||||
*
|
||||
* zero otherwise. The min_corner of UDATA is
|
||||
* not necessarily contained within the address
|
||||
* space represented by LT_KEY, but a key that
|
||||
* would describe the UDATA min_corner address
|
||||
* would fall lexicographically between LT_KEY
|
||||
* and RT_KEY.
|
||||
*
|
||||
* Failure: FAIL (same as UDATA < LT_KEY)
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 8, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static intn
|
||||
H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
|
||||
{
|
||||
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
|
||||
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
|
||||
assert (lt_key);
|
||||
assert (rt_key);
|
||||
assert (udata);
|
||||
assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
|
||||
|
||||
if (H5V_vector_lt (udata->mesg.ndims, udata->key.offset, lt_key->offset)) {
|
||||
return -1;
|
||||
} else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
|
||||
rt_key->offset)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_new
|
||||
*
|
||||
* Purpose: Adds a new entry to an i-storage B-tree. We can assume that
|
||||
* the domain represented by UDATA doesn't intersect the domain
|
||||
* already represented by the B-tree.
|
||||
*
|
||||
* Return: Success: Address of leaf, which is passed in from the
|
||||
* UDATA pointer.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Tuesday, October 14, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static haddr_t
|
||||
H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
|
||||
{
|
||||
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
|
||||
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
size_t nbytes;
|
||||
intn i;
|
||||
|
||||
FUNC_ENTER (H5F_istore_new, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (lt_key);
|
||||
assert (rt_key);
|
||||
assert (udata);
|
||||
assert (udata->mesg.ndims>=0 && udata->mesg.ndims<H5O_ISTORE_NDIMS);
|
||||
|
||||
/* Allocate new storage */
|
||||
nbytes = H5V_vector_reduce_product (udata->mesg.ndims, udata->key.size);
|
||||
assert (nbytes>0);
|
||||
if ((udata->addr=H5MF_alloc (f, nbytes))<0) {
|
||||
/* Couldn't allocate new file storage */
|
||||
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
|
||||
/* left key describes the UDATA, right key is a zero-size "edge" */
|
||||
for (i=0; i<udata->mesg.ndims; i++) {
|
||||
lt_key->offset[i] = udata->key.offset[i];
|
||||
lt_key->size[i] = udata->key.size[i];
|
||||
assert (udata->key.size[i]>0);
|
||||
|
||||
rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
|
||||
rt_key->size[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
FUNC_LEAVE (udata->addr);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_found
|
||||
*
|
||||
* Purpose: This function is called when the B-tree search engine has
|
||||
* found the leaf entry that points to a chunk of storage that
|
||||
* contains the beginning of the logical address space
|
||||
* represented by UDATA. The LT_KEY is the left key (the one
|
||||
* that describes the chunk) and RT_KEY is the right key (the
|
||||
* one that describes the next or last chunk).
|
||||
*
|
||||
* Return: Success: SUCCEED with information about the chunk
|
||||
* returned through the UDATA argument.
|
||||
*
|
||||
* Failure: FAIL if not found.
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Thursday, October 9, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
|
||||
void *_udata, const void *_rt_key)
|
||||
{
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *)_lt_key;
|
||||
const H5F_istore_key_t *rt_key = (const H5F_istore_key_t *)_rt_key;
|
||||
int i;
|
||||
|
||||
FUNC_ENTER (H5F_istore_found, NULL, FAIL);
|
||||
|
||||
/* Check arguments */
|
||||
assert (f);
|
||||
assert (addr>=0);
|
||||
assert (udata);
|
||||
assert (lt_key);
|
||||
assert (rt_key);
|
||||
|
||||
/* Initialize return values */
|
||||
udata->addr = addr;
|
||||
for (i=0; i<udata->mesg.ndims; i++) {
|
||||
udata->key.offset[i] = lt_key->offset[i];
|
||||
udata->key.size[i] = lt_key->size[i];
|
||||
assert (lt_key->size[i]>0);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_insert
|
||||
*
|
||||
* Purpose: This function is called when the B-tree insert engine finds
|
||||
* the node to use to insert new data. The UDATA argument
|
||||
* points to a struct that describes the logical addresses being
|
||||
* added to the file. This function allocates space for the
|
||||
* data and returns information through UDATA describing a
|
||||
* file chunk to receive (part of) the data.
|
||||
*
|
||||
* The LT_KEY is always the key describing the chunk of file
|
||||
* memory at address ADDR. On entry, UDATA describes the logical
|
||||
* addresses for which storage is being requested (through the
|
||||
* `offset' and `size' fields). On return, UDATA describes the
|
||||
* logical addresses contained in a chunk on disk.
|
||||
*
|
||||
* Return: Success: SUCCEED, with UDATA containing information
|
||||
* about the (newly allocated) chunk.
|
||||
*
|
||||
* If the storage address has changed then the
|
||||
* new address is returned.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Thursday, October 9, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static haddr_t
|
||||
H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
|
||||
void *_lt_key, hbool_t *lt_key_changed,
|
||||
void *_md_key, void *_udata,
|
||||
void *_rt_key, hbool_t *rt_key_changed)
|
||||
{
|
||||
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
|
||||
H5F_istore_key_t *md_key = (H5F_istore_key_t *)_md_key;
|
||||
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
intn i, cmp;
|
||||
haddr_t ret_value = 0;
|
||||
size_t nbytes;
|
||||
|
||||
FUNC_ENTER (H5F_istore_insert, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (addr>=0);
|
||||
assert (parent_ins);
|
||||
assert (lt_key);
|
||||
assert (lt_key_changed);
|
||||
assert (md_key);
|
||||
assert (udata);
|
||||
assert (rt_key);
|
||||
assert (rt_key_changed);
|
||||
|
||||
cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
|
||||
assert (cmp<=0);
|
||||
|
||||
if (cmp<0) {
|
||||
/* Negative indices not supported yet */
|
||||
assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
|
||||
HRETURN_ERROR (H5E_STORAGE, H5E_UNSUPPORTED, FAIL);
|
||||
|
||||
} else if (H5V_hyper_eq (udata->mesg.ndims,
|
||||
udata->key.offset, udata->key.size,
|
||||
lt_key->offset, lt_key->size)) {
|
||||
/*
|
||||
* Already exists. Just return the info.
|
||||
*/
|
||||
udata->addr = addr;
|
||||
*parent_ins = H5B_INS_NOOP;
|
||||
|
||||
} else if (H5V_hyper_disjointp (udata->mesg.ndims,
|
||||
lt_key->offset, lt_key->size,
|
||||
udata->key.offset, udata->key.size)) {
|
||||
assert (H5V_hyper_disjointp (udata->mesg.ndims,
|
||||
rt_key->offset, rt_key->size,
|
||||
udata->key.offset, udata->key.size));
|
||||
|
||||
/*
|
||||
* Split this node, inserting the new new node to the right of the
|
||||
* current node. The MD_KEY is where the split occurs.
|
||||
*/
|
||||
for (i=0, nbytes=1; i<udata->mesg.ndims; i++) {
|
||||
assert (0==udata->key.offset[i] % udata->mesg.alignment[i]);
|
||||
assert (udata->key.size[i] == udata->mesg.alignment[i]);
|
||||
md_key->offset[i] = udata->key.offset[i];
|
||||
md_key->size[i] = udata->key.size[i];
|
||||
nbytes *= udata->key.size[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate storage for the new chunk
|
||||
*/
|
||||
if ((udata->addr=ret_value=H5MF_alloc (f, nbytes))<=0) {
|
||||
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
|
||||
*parent_ins = H5B_INS_RIGHT;
|
||||
|
||||
} else {
|
||||
assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
|
||||
HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (ret_value);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_copy_hyperslab
|
||||
*
|
||||
* Purpose: Reads or writes a hyperslab to disk depending on whether OP
|
||||
* is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab
|
||||
* storage is described with ISTORE and exists in file F. The
|
||||
* file hyperslab begins at location OFFSET_F[] (an N-dimensional
|
||||
* point in the domain in terms of elements) in the file and
|
||||
* OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[]
|
||||
* elements. The dimensionality of memory is assumed to be the
|
||||
* same as the file and the total size of the multi-dimensional
|
||||
* memory buffer is SIZE_M[].
|
||||
*
|
||||
* The slowest varying dimension is always listed first in the
|
||||
* various offset and size arrays.
|
||||
*
|
||||
* A `chunk' is a hyperslab of the disk array which is stored
|
||||
* contiguously. I/O occurs in units of chunks where the size of
|
||||
* a chunk is determined by the alignment constraints specified
|
||||
* in ISTORE.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, October 17, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
|
||||
size_t offset_f[], size_t size[],
|
||||
size_t offset_m[], size_t size_m[], void *buf)
|
||||
{
|
||||
intn i, carry;
|
||||
size_t idx_cur[H5O_ISTORE_NDIMS];
|
||||
size_t idx_min[H5O_ISTORE_NDIMS];
|
||||
size_t idx_max[H5O_ISTORE_NDIMS];
|
||||
size_t sub_size[H5O_ISTORE_NDIMS];
|
||||
size_t sub_offset_f[H5O_ISTORE_NDIMS];
|
||||
size_t sub_offset_m[H5O_ISTORE_NDIMS];
|
||||
size_t sub_offset_ch[H5O_ISTORE_NDIMS];
|
||||
size_t chunk_size;
|
||||
uint8 *chunk=NULL;
|
||||
H5F_istore_ud1_t udata;
|
||||
herr_t status;
|
||||
herr_t ret_value = FAIL;
|
||||
|
||||
FUNC_ENTER (H5F_istore_copy_hyperslab, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (istore);
|
||||
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
|
||||
assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
|
||||
assert (size);
|
||||
assert (size_m);
|
||||
assert (buf);
|
||||
#ifndef NDEBUG
|
||||
for (i=0; i<istore->ndims; i++) {
|
||||
assert (!offset_f || offset_f[i]>=0);/*neg domains unsupported */
|
||||
assert (!offset_m || offset_m[i]>=0);/*mem array offset never neg */
|
||||
assert (size[i]>=0); /*size may be zero, implies no-op */
|
||||
assert (size_m[i]>0); /*destination must exist */
|
||||
/*hyperslab must fit in BUF*/
|
||||
assert ((offset_m?offset_m[i]:0)+size[i]<=size_m[i]);
|
||||
assert (istore->alignment[i]>0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Does the B-tree exist?
|
||||
*/
|
||||
if (istore->btree_addr<=0) {
|
||||
if (H5F_ISTORE_WRITE==op) {
|
||||
udata.mesg.ndims = istore->ndims;
|
||||
if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
|
||||
/* Can't create B-tree */
|
||||
HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
} else {
|
||||
H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
|
||||
HRETURN (SUCCEED);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize indices */
|
||||
for (i=0; i<istore->ndims; i++) {
|
||||
idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
|
||||
idx_max[i] = ((offset_f?offset_f[i]:0)+size[i]-1)/istore->alignment[i]+1;
|
||||
idx_cur[i] = idx_min[i];
|
||||
}
|
||||
|
||||
/* Allocate buffers */
|
||||
for (i=0, chunk_size=1; i<istore->ndims; i++) {
|
||||
chunk_size *= istore->alignment[i];
|
||||
}
|
||||
chunk = H5MM_xmalloc (chunk_size);
|
||||
|
||||
/* Initialize non-changing part of udata */
|
||||
udata.mesg = *istore;
|
||||
|
||||
/* Loop over all chunks */
|
||||
while (1) {
|
||||
|
||||
/* Read/Write chunk or create it if it doesn't exist */
|
||||
udata.mesg.ndims = istore->ndims;
|
||||
for (i=0; i<istore->ndims; i++) {
|
||||
udata.key.offset[i] = idx_cur[i] * istore->alignment[i];
|
||||
udata.key.size[i] = istore->alignment[i];
|
||||
sub_offset_f[i] = MAX ((offset_f?offset_f[i]:0), udata.key.offset[i]);
|
||||
sub_offset_m[i] = (offset_m?offset_m[i]:0) +
|
||||
sub_offset_f[i] - (offset_f?offset_f[i]:0);
|
||||
sub_size[i] = (idx_cur[i]+1)*istore->alignment[i]-sub_offset_f[i];
|
||||
sub_offset_ch[i] = sub_offset_f[i] - udata.key.offset[i];
|
||||
}
|
||||
if (H5F_ISTORE_WRITE==op) {
|
||||
status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
|
||||
assert (status>=0);
|
||||
} else {
|
||||
status = H5B_find (f, H5B_ISTORE, istore->btree_addr, &udata);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the operation is reading from the disk or if we are writing a
|
||||
* partial chunk then load the chunk from disk.
|
||||
*/
|
||||
if (H5F_ISTORE_READ==op ||
|
||||
!H5V_hyper_eq (istore->ndims,
|
||||
udata.key.offset, udata.key.size,
|
||||
sub_offset_f, sub_size)) {
|
||||
if (status>=0) {
|
||||
if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
|
||||
HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
|
||||
}
|
||||
} else {
|
||||
HDmemset (chunk, 0, chunk_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer data to/from the chunk */
|
||||
if (H5F_ISTORE_WRITE==op) {
|
||||
H5V_hyper_copy (istore->ndims, sub_size,
|
||||
udata.key.size, sub_offset_ch, chunk,
|
||||
size_m, sub_offset_m, buf);
|
||||
if (H5F_block_write (f, udata.addr, chunk_size, chunk)<0) {
|
||||
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
|
||||
}
|
||||
} else {
|
||||
H5V_hyper_copy (istore->ndims, sub_size,
|
||||
size_m, sub_offset_m, buf,
|
||||
udata.key.size, sub_offset_ch, chunk);
|
||||
}
|
||||
|
||||
/* Increment indices */
|
||||
for (i=istore->ndims-1, carry=1; i>=0 && carry; --i) {
|
||||
if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i];
|
||||
else carry = 0;
|
||||
}
|
||||
if (carry) break;
|
||||
}
|
||||
ret_value = SUCCEED;
|
||||
|
||||
|
||||
done:
|
||||
chunk = H5MM_xfree (chunk);
|
||||
FUNC_LEAVE (ret_value);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_read
|
||||
*
|
||||
* Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
|
||||
* storage array.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
|
||||
size_t offset[], size_t size[], void *buf)
|
||||
{
|
||||
FUNC_ENTER (H5F_istore_read, NULL, FAIL);
|
||||
|
||||
/* Check args */
|
||||
assert (f);
|
||||
assert (istore);
|
||||
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
|
||||
assert (size);
|
||||
assert (buf);
|
||||
|
||||
if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_READ,
|
||||
offset, size, H5V_ZERO, size, buf)<0) {
|
||||
/* hyperslab output failure */
|
||||
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_write
|
||||
*
|
||||
* Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
|
||||
* storage array.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
|
||||
size_t offset[], size_t size[], void *buf)
|
||||
{
|
||||
FUNC_ENTER (H5F_istore_write, NULL, FAIL);
|
||||
|
||||
/* Check args */
|
||||
assert (f);
|
||||
assert (istore);
|
||||
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
|
||||
assert (size);
|
||||
assert (buf);
|
||||
|
||||
if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_WRITE,
|
||||
offset, size, H5V_ZERO, size, buf)<0) {
|
||||
/* hyperslab output failure */
|
||||
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
@ -59,10 +59,10 @@ static const hdf_maj_error_messages_t hdf_maj_error_messages[] =
|
||||
{H5E_SYM, "Symbol Table"},
|
||||
{H5E_HEAP, "Heap"},
|
||||
{H5E_OHDR, "Object Header"},
|
||||
{H5E_DIRECTORY, "Directory"},
|
||||
{H5E_DATATYPE, "Datatype"},
|
||||
{H5E_DATASPACE, "Dataspace"},
|
||||
{H5E_DATASET, "Dataset"}
|
||||
{H5E_DATASET, "Dataset"},
|
||||
{H5E_STORAGE, "Data Storage"},
|
||||
};
|
||||
|
||||
static const hdf_min_error_messages_t hdf_min_error_messages[] =
|
||||
@ -104,6 +104,7 @@ static const hdf_min_error_messages_t hdf_min_error_messages[] =
|
||||
{H5E_ALIGNMENT, "Alignment error"},
|
||||
{H5E_BADMESG, "Unrecognized message"},
|
||||
{H5E_COMPLEN, "Name component is too long"},
|
||||
{H5E_CWG, "Problem with current working group"},
|
||||
{H5E_LINK, "Link count failure"},
|
||||
};
|
||||
|
||||
|
@ -38,10 +38,10 @@ typedef enum
|
||||
H5E_SYM, /* Symbol Table */
|
||||
H5E_HEAP, /* Heap */
|
||||
H5E_OHDR, /* Object Header */
|
||||
H5E_DIRECTORY, /* Directory */
|
||||
H5E_DATATYPE, /* Datatype */
|
||||
H5E_DATASPACE, /* Dataspace */
|
||||
H5E_DATASET /* Dataset */
|
||||
H5E_DATASPACE, /* Dataspace */
|
||||
H5E_DATASET, /* Dataset */
|
||||
H5E_STORAGE /* Data storage */
|
||||
}
|
||||
hdf_maj_err_code_t;
|
||||
|
||||
@ -102,9 +102,10 @@ typedef enum
|
||||
H5E_ALIGNMENT, /* Alignment error */
|
||||
H5E_BADMESG, /* Unrecognized message */
|
||||
|
||||
/* Directory related errors */
|
||||
/* Group related errors */
|
||||
H5E_CANTOPENOBJ, /* Can't open object */
|
||||
H5E_COMPLEN, /* Name component is too long */
|
||||
H5E_CWG, /* Problem with current working group */
|
||||
H5E_LINK /* Link count failure */
|
||||
}
|
||||
hdf_min_err_code_t;
|
||||
|
40
src/H5F.c
40
src/H5F.c
@ -69,7 +69,6 @@ static herr_t H5F_init_interface(void);
|
||||
static H5F_t *H5F_new (H5F_file_t *shared);
|
||||
static H5F_t *H5F_dest (H5F_t *f);
|
||||
static herr_t H5F_flush (H5F_t *f, hbool_t invalidate);
|
||||
static herr_t H5F_close (H5F_t *f);
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
NAME
|
||||
@ -500,7 +499,7 @@ H5F_dest (H5F_t *f)
|
||||
* block is written. This operation will fail
|
||||
* if the file is already open.
|
||||
*
|
||||
* Unlinking the file name from the directory hierarchy while
|
||||
* Unlinking the file name from the group directed graph while
|
||||
* the file is opened causes the file to continue to exist but
|
||||
* one will not be able to upgrade the file from read-only
|
||||
* access to read-write access by reopening it. Disk resources
|
||||
@ -508,13 +507,20 @@ H5F_dest (H5F_t *f)
|
||||
* closed. NOTE: This paragraph probably only applies to Unix;
|
||||
* deleting the file name in other OS's has undefined results.
|
||||
*
|
||||
* The CREATE_PARMS argument is optional. A null pointer will
|
||||
* cause the default file creation parameters to be used.
|
||||
*
|
||||
* Errors:
|
||||
* ATOM BADATOM Can't unatomize default template
|
||||
* id.
|
||||
* FILE BADVALUE Can't create file without write
|
||||
* intent.
|
||||
* FILE BADVALUE Can't truncate without write intent.
|
||||
* FILE CANTCREATE Can't create file.
|
||||
* FILE CANTCREATE Can't stat file.
|
||||
* FILE CANTCREATE Can't truncate file.
|
||||
* FILE CANTINIT Can't get default file create template
|
||||
* id.
|
||||
* FILE CANTINIT Can't write file boot block.
|
||||
* FILE CANTINIT Cannot determine file size.
|
||||
* FILE CANTOPENFILE Bad boot block version number.
|
||||
@ -550,7 +556,7 @@ H5F_dest (H5F_t *f)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5F_t *
|
||||
H5F_t *
|
||||
H5F_open (const char *name, uintn flags,
|
||||
const file_create_temp_t *create_parms)
|
||||
{
|
||||
@ -572,6 +578,21 @@ H5F_open (const char *name, uintn flags,
|
||||
|
||||
assert (name && *name);
|
||||
|
||||
/*
|
||||
* If no file creation parameters are supplied then use defaults.
|
||||
*/
|
||||
if (!create_parms) {
|
||||
hid_t create_temp = H5C_get_default_atom (H5_TEMPLATE);
|
||||
if (create_temp<0) {
|
||||
/* Can't get default file create template id */
|
||||
HRETURN_ERROR (H5E_FILE, H5E_CANTINIT, NULL);
|
||||
}
|
||||
if (NULL==(create_parms=H5Aatom_object (create_temp))) {
|
||||
/* Can't unatomize default template id */
|
||||
HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Does the file exist? If so, get the device and i-node values so we can
|
||||
* compare them with other files already open. On Unix (and other systems
|
||||
@ -984,11 +1005,6 @@ hid_t H5Fcreate(const char *filename, uintn flags, hid_t create_temp,
|
||||
hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
|
||||
{
|
||||
H5F_t *new_file=NULL; /* file struct for new file */
|
||||
hid_t create_temp; /* file-creation template ID */
|
||||
const file_create_temp_t *f_create_parms; /* pointer to the parameters
|
||||
* to use when creating the
|
||||
* file
|
||||
*/
|
||||
hid_t ret_value = FAIL;
|
||||
|
||||
FUNC_ENTER(H5Fopen, H5F_init_interface, FAIL);
|
||||
@ -999,10 +1015,6 @@ hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
|
||||
HGOTO_ERROR (H5E_ARGS, H5E_BADRANGE, FAIL);/*invalid file name*/
|
||||
flags = flags & H5ACC_WRITE ? H5F_ACC_WRITE : 0;
|
||||
|
||||
create_temp = H5C_get_default_atom (H5_TEMPLATE);
|
||||
if (NULL==(f_create_parms=H5Aatom_object(create_temp)))
|
||||
HGOTO_ERROR (H5E_ATOM, H5E_BADATOM, FAIL);/*can't unatomize template*/
|
||||
|
||||
#ifdef LATER
|
||||
if (access_temp<=0)
|
||||
access_temp = H5CPget_default_atom (H5_TEMPLATE);
|
||||
@ -1011,7 +1023,7 @@ hid_t H5Fopen(const char *filename, uintn flags, hid_t access_temp)
|
||||
#endif
|
||||
|
||||
/* Open the file */
|
||||
if (NULL==(new_file=H5F_open (filename, flags, f_create_parms))) {
|
||||
if (NULL==(new_file=H5F_open (filename, flags, NULL))) {
|
||||
HGOTO_ERROR (H5E_FILE, H5E_CANTOPENFILE, FAIL); /*cant open file*/
|
||||
}
|
||||
|
||||
@ -1188,7 +1200,7 @@ H5Fflush (hid_t fid, hbool_t invalidate)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
herr_t
|
||||
H5F_close (H5F_t *f)
|
||||
{
|
||||
herr_t ret_value = FAIL;
|
||||
|
740
src/H5Fistore.c
Normal file
740
src/H5Fistore.c
Normal file
@ -0,0 +1,740 @@
|
||||
/*
|
||||
* Copyright (C) 1997 Spizella Software
|
||||
* All rights reserved.
|
||||
*
|
||||
* Programmer: Robb Matzke <robb@arborea.spizella.com>
|
||||
* Wednesday, October 8, 1997
|
||||
*/
|
||||
#include <H5private.h>
|
||||
#include <H5Eprivate.h>
|
||||
#include <H5Fprivate.h>
|
||||
#include <H5MFprivate.h>
|
||||
#include <H5MMprivate.h>
|
||||
#include <H5Oprivate.h>
|
||||
#include <H5Vprivate.h>
|
||||
|
||||
typedef enum H5F_isop_t {
|
||||
H5F_ISTORE_READ, /*read from file to memory */
|
||||
H5F_ISTORE_WRITE /*write from memory to file */
|
||||
} H5F_isop_t;
|
||||
|
||||
/* Does the array domain include negative indices? */
|
||||
#undef H5F_ISTORE_NEGATIVE_DOMAIN
|
||||
|
||||
|
||||
#define PABLO_MASK H5F_istore_mask
|
||||
|
||||
/* Is the interface initialized? */
|
||||
static hbool_t interface_initialize_g = FALSE;
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static size_t H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata);
|
||||
static haddr_t H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata,
|
||||
void *_rt_key);
|
||||
static intn H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata,
|
||||
void *_rt_key);
|
||||
static herr_t H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
|
||||
void *_udata, const void *_rt_key);
|
||||
static haddr_t H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
|
||||
void *_lt_key, hbool_t *lt_key_changed,
|
||||
void *_md_key, void *_udata,
|
||||
void *_rt_key, hbool_t *rt_key_changed);
|
||||
static herr_t H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
|
||||
void *_key);
|
||||
static herr_t H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
|
||||
void *_key);
|
||||
static herr_t H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore,
|
||||
H5F_isop_t op, size_t offset_f[],
|
||||
size_t size[], size_t offset_m[],
|
||||
size_t size_m[], void *buf);
|
||||
|
||||
|
||||
/*
|
||||
* B-tree key. A key contains the minimum logical N-dimensional address and
|
||||
* the logical size of the chunk to which this key refers. The
|
||||
* fastest-varying dimension is assumed to reference individual bytes of the
|
||||
* array, so a 100-element 1-d array of 4-byte integers would really be a 2-d
|
||||
* array with the slow varying dimension of size 100 and the fast varying
|
||||
* dimension of size 4 (the storage dimensionality has very little to do with
|
||||
* the real dimensionality).
|
||||
*
|
||||
* Only the first few values of the OFFSET and SIZE fields are actually
|
||||
* stored on disk, depending on the dimensionality.
|
||||
*
|
||||
* The storage file address is part of the B-tree and not part of the key.
|
||||
*/
|
||||
typedef struct H5F_istore_key_t {
|
||||
size_t offset[H5O_ISTORE_NDIMS]; /*logical offset to start*/
|
||||
size_t size[H5O_ISTORE_NDIMS]; /*logical chunk size */
|
||||
} H5F_istore_key_t;
|
||||
|
||||
typedef struct H5F_istore_ud1_t {
|
||||
H5F_istore_key_t key; /*key values */
|
||||
haddr_t addr; /*file address of chunk */
|
||||
H5O_istore_t mesg; /*storage message */
|
||||
} H5F_istore_ud1_t;
|
||||
|
||||
/* inherits B-tree like properties from H5B */
|
||||
H5B_class_t H5B_ISTORE[1] = {{
|
||||
H5B_ISTORE_ID, /*id */
|
||||
sizeof (H5F_istore_key_t), /*sizeof_nkey */
|
||||
H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
|
||||
H5F_istore_new, /*new */
|
||||
H5F_istore_cmp, /*cmp */
|
||||
H5F_istore_found, /*found */
|
||||
H5F_istore_insert, /*insert */
|
||||
FALSE, /*follow min branch? */
|
||||
FALSE, /*follow max branch? */
|
||||
NULL, /*list */
|
||||
H5F_istore_decode_key, /*decode */
|
||||
H5F_istore_encode_key, /*encode */
|
||||
}};
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_sizeof_rkey
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static size_t
|
||||
H5F_istore_sizeof_rkey (H5F_t *f, const void *_udata)
|
||||
{
|
||||
const H5F_istore_ud1_t *udata = (const H5F_istore_ud1_t *)_udata;
|
||||
|
||||
assert (udata);
|
||||
assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
|
||||
|
||||
return udata->mesg.ndims * (4 + 4);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_decode_key
|
||||
*
|
||||
* Purpose: Decodes a raw key into a native key for the B-tree
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, October 10, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
|
||||
{
|
||||
H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
|
||||
int i;
|
||||
int ndims = bt->sizeof_rkey / 8;
|
||||
|
||||
FUNC_ENTER (H5F_istore_decode_key, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (bt);
|
||||
assert (raw);
|
||||
assert (key);
|
||||
assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
|
||||
|
||||
/* decode */
|
||||
for (i=0; i<ndims; i++) {
|
||||
UINT32DECODE (raw, key->offset[i]);
|
||||
UINT32DECODE (raw, key->size[i]);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_encode_key
|
||||
*
|
||||
* Purpose: Encode a key from native format to raw format.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, October 10, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
|
||||
{
|
||||
H5F_istore_key_t *key = (H5F_istore_key_t *)_key;
|
||||
intn ndims = bt->sizeof_rkey / 8;
|
||||
intn i;
|
||||
|
||||
FUNC_ENTER (H5F_istore_encode_key, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (bt);
|
||||
assert (raw);
|
||||
assert (key);
|
||||
assert (ndims>0 && ndims<=H5O_ISTORE_NDIMS && 8*ndims==bt->sizeof_rkey);
|
||||
|
||||
/* encode */
|
||||
for (i=0; i<ndims; i++) {
|
||||
UINT32ENCODE (raw, key->offset[i]);
|
||||
UINT32ENCODE (raw, key->size[i]);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_cmp
|
||||
*
|
||||
* Purpose: Compare the requested datum UDATA with the left and right
|
||||
* keys of the B-tree.
|
||||
*
|
||||
* Return: Success: negative if the min_corner of UDATA is less
|
||||
* than the min_corner of LT_KEY.
|
||||
*
|
||||
* positive if the min_corner of UDATA is
|
||||
* greater than or equal the min_corner of
|
||||
* RT_KEY.
|
||||
*
|
||||
* zero otherwise. The min_corner of UDATA is
|
||||
* not necessarily contained within the address
|
||||
* space represented by LT_KEY, but a key that
|
||||
* would describe the UDATA min_corner address
|
||||
* would fall lexicographically between LT_KEY
|
||||
* and RT_KEY.
|
||||
*
|
||||
* Failure: FAIL (same as UDATA < LT_KEY)
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 8, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static intn
|
||||
H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
|
||||
{
|
||||
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
|
||||
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
|
||||
assert (lt_key);
|
||||
assert (rt_key);
|
||||
assert (udata);
|
||||
assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
|
||||
|
||||
if (H5V_vector_lt (udata->mesg.ndims, udata->key.offset, lt_key->offset)) {
|
||||
return -1;
|
||||
} else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
|
||||
rt_key->offset)) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_new
|
||||
*
|
||||
* Purpose: Adds a new entry to an i-storage B-tree. We can assume that
|
||||
* the domain represented by UDATA doesn't intersect the domain
|
||||
* already represented by the B-tree.
|
||||
*
|
||||
* Return: Success: Address of leaf, which is passed in from the
|
||||
* UDATA pointer.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Tuesday, October 14, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static haddr_t
|
||||
H5F_istore_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
|
||||
{
|
||||
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
|
||||
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
size_t nbytes;
|
||||
intn i;
|
||||
|
||||
FUNC_ENTER (H5F_istore_new, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (lt_key);
|
||||
assert (rt_key);
|
||||
assert (udata);
|
||||
assert (udata->mesg.ndims>=0 && udata->mesg.ndims<H5O_ISTORE_NDIMS);
|
||||
|
||||
/* Allocate new storage */
|
||||
nbytes = H5V_vector_reduce_product (udata->mesg.ndims, udata->key.size);
|
||||
assert (nbytes>0);
|
||||
if ((udata->addr=H5MF_alloc (f, nbytes))<0) {
|
||||
/* Couldn't allocate new file storage */
|
||||
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
|
||||
/* left key describes the UDATA, right key is a zero-size "edge" */
|
||||
for (i=0; i<udata->mesg.ndims; i++) {
|
||||
lt_key->offset[i] = udata->key.offset[i];
|
||||
lt_key->size[i] = udata->key.size[i];
|
||||
assert (udata->key.size[i]>0);
|
||||
|
||||
rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
|
||||
rt_key->size[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
FUNC_LEAVE (udata->addr);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_found
|
||||
*
|
||||
* Purpose: This function is called when the B-tree search engine has
|
||||
* found the leaf entry that points to a chunk of storage that
|
||||
* contains the beginning of the logical address space
|
||||
* represented by UDATA. The LT_KEY is the left key (the one
|
||||
* that describes the chunk) and RT_KEY is the right key (the
|
||||
* one that describes the next or last chunk).
|
||||
*
|
||||
* Return: Success: SUCCEED with information about the chunk
|
||||
* returned through the UDATA argument.
|
||||
*
|
||||
* Failure: FAIL if not found.
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Thursday, October 9, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
|
||||
void *_udata, const void *_rt_key)
|
||||
{
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
const H5F_istore_key_t *lt_key = (const H5F_istore_key_t *)_lt_key;
|
||||
const H5F_istore_key_t *rt_key = (const H5F_istore_key_t *)_rt_key;
|
||||
int i;
|
||||
|
||||
FUNC_ENTER (H5F_istore_found, NULL, FAIL);
|
||||
|
||||
/* Check arguments */
|
||||
assert (f);
|
||||
assert (addr>=0);
|
||||
assert (udata);
|
||||
assert (lt_key);
|
||||
assert (rt_key);
|
||||
|
||||
/* Initialize return values */
|
||||
udata->addr = addr;
|
||||
for (i=0; i<udata->mesg.ndims; i++) {
|
||||
udata->key.offset[i] = lt_key->offset[i];
|
||||
udata->key.size[i] = lt_key->size[i];
|
||||
assert (lt_key->size[i]>0);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_insert
|
||||
*
|
||||
* Purpose: This function is called when the B-tree insert engine finds
|
||||
* the node to use to insert new data. The UDATA argument
|
||||
* points to a struct that describes the logical addresses being
|
||||
* added to the file. This function allocates space for the
|
||||
* data and returns information through UDATA describing a
|
||||
* file chunk to receive (part of) the data.
|
||||
*
|
||||
* The LT_KEY is always the key describing the chunk of file
|
||||
* memory at address ADDR. On entry, UDATA describes the logical
|
||||
* addresses for which storage is being requested (through the
|
||||
* `offset' and `size' fields). On return, UDATA describes the
|
||||
* logical addresses contained in a chunk on disk.
|
||||
*
|
||||
* Return: Success: SUCCEED, with UDATA containing information
|
||||
* about the (newly allocated) chunk.
|
||||
*
|
||||
* If the storage address has changed then the
|
||||
* new address is returned.
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Thursday, October 9, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static haddr_t
|
||||
H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
|
||||
void *_lt_key, hbool_t *lt_key_changed,
|
||||
void *_md_key, void *_udata,
|
||||
void *_rt_key, hbool_t *rt_key_changed)
|
||||
{
|
||||
H5F_istore_key_t *lt_key = (H5F_istore_key_t *)_lt_key;
|
||||
H5F_istore_key_t *md_key = (H5F_istore_key_t *)_md_key;
|
||||
H5F_istore_key_t *rt_key = (H5F_istore_key_t *)_rt_key;
|
||||
H5F_istore_ud1_t *udata = (H5F_istore_ud1_t *)_udata;
|
||||
intn i, cmp;
|
||||
haddr_t ret_value = 0;
|
||||
size_t nbytes;
|
||||
|
||||
FUNC_ENTER (H5F_istore_insert, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (addr>=0);
|
||||
assert (parent_ins);
|
||||
assert (lt_key);
|
||||
assert (lt_key_changed);
|
||||
assert (md_key);
|
||||
assert (udata);
|
||||
assert (rt_key);
|
||||
assert (rt_key_changed);
|
||||
|
||||
cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
|
||||
assert (cmp<=0);
|
||||
|
||||
if (cmp<0) {
|
||||
/* Negative indices not supported yet */
|
||||
assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
|
||||
HRETURN_ERROR (H5E_STORAGE, H5E_UNSUPPORTED, FAIL);
|
||||
|
||||
} else if (H5V_hyper_eq (udata->mesg.ndims,
|
||||
udata->key.offset, udata->key.size,
|
||||
lt_key->offset, lt_key->size)) {
|
||||
/*
|
||||
* Already exists. Just return the info.
|
||||
*/
|
||||
udata->addr = addr;
|
||||
*parent_ins = H5B_INS_NOOP;
|
||||
|
||||
} else if (H5V_hyper_disjointp (udata->mesg.ndims,
|
||||
lt_key->offset, lt_key->size,
|
||||
udata->key.offset, udata->key.size)) {
|
||||
assert (H5V_hyper_disjointp (udata->mesg.ndims,
|
||||
rt_key->offset, rt_key->size,
|
||||
udata->key.offset, udata->key.size));
|
||||
|
||||
/*
|
||||
* Split this node, inserting the new new node to the right of the
|
||||
* current node. The MD_KEY is where the split occurs.
|
||||
*/
|
||||
for (i=0, nbytes=1; i<udata->mesg.ndims; i++) {
|
||||
assert (0==udata->key.offset[i] % udata->mesg.alignment[i]);
|
||||
assert (udata->key.size[i] == udata->mesg.alignment[i]);
|
||||
md_key->offset[i] = udata->key.offset[i];
|
||||
md_key->size[i] = udata->key.size[i];
|
||||
nbytes *= udata->key.size[i];
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate storage for the new chunk
|
||||
*/
|
||||
if ((udata->addr=ret_value=H5MF_alloc (f, nbytes))<=0) {
|
||||
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
|
||||
*parent_ins = H5B_INS_RIGHT;
|
||||
|
||||
} else {
|
||||
assert ("HDF5 INTERNAL ERROR -- see rpm" && 0);
|
||||
HRETURN_ERROR (H5E_IO, H5E_UNSUPPORTED, FAIL);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (ret_value);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_copy_hyperslab
|
||||
*
|
||||
* Purpose: Reads or writes a hyperslab to disk depending on whether OP
|
||||
* is H5F_ISTORE_READ or H5F_ISTORE_WRITE. The hyperslab
|
||||
* storage is described with ISTORE and exists in file F. The
|
||||
* file hyperslab begins at location OFFSET_F[] (an N-dimensional
|
||||
* point in the domain in terms of elements) in the file and
|
||||
* OFFSET_M[] in memory pointed to by BUF. Its size is SIZE[]
|
||||
* elements. The dimensionality of memory is assumed to be the
|
||||
* same as the file and the total size of the multi-dimensional
|
||||
* memory buffer is SIZE_M[].
|
||||
*
|
||||
* The slowest varying dimension is always listed first in the
|
||||
* various offset and size arrays.
|
||||
*
|
||||
* A `chunk' is a hyperslab of the disk array which is stored
|
||||
* contiguously. I/O occurs in units of chunks where the size of
|
||||
* a chunk is determined by the alignment constraints specified
|
||||
* in ISTORE.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, October 17, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5F_istore_copy_hyperslab (H5F_t *f, H5O_istore_t *istore, H5F_isop_t op,
|
||||
size_t offset_f[], size_t size[],
|
||||
size_t offset_m[], size_t size_m[], void *buf)
|
||||
{
|
||||
intn i, carry;
|
||||
size_t idx_cur[H5O_ISTORE_NDIMS];
|
||||
size_t idx_min[H5O_ISTORE_NDIMS];
|
||||
size_t idx_max[H5O_ISTORE_NDIMS];
|
||||
size_t sub_size[H5O_ISTORE_NDIMS];
|
||||
size_t sub_offset_f[H5O_ISTORE_NDIMS];
|
||||
size_t sub_offset_m[H5O_ISTORE_NDIMS];
|
||||
size_t sub_offset_ch[H5O_ISTORE_NDIMS];
|
||||
size_t chunk_size;
|
||||
uint8 *chunk=NULL;
|
||||
H5F_istore_ud1_t udata;
|
||||
herr_t status;
|
||||
herr_t ret_value = FAIL;
|
||||
|
||||
FUNC_ENTER (H5F_istore_copy_hyperslab, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (istore);
|
||||
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
|
||||
assert (H5F_ISTORE_READ==op || H5F_ISTORE_WRITE==op);
|
||||
assert (size);
|
||||
assert (size_m);
|
||||
assert (buf);
|
||||
#ifndef NDEBUG
|
||||
for (i=0; i<istore->ndims; i++) {
|
||||
assert (!offset_f || offset_f[i]>=0);/*neg domains unsupported */
|
||||
assert (!offset_m || offset_m[i]>=0);/*mem array offset never neg */
|
||||
assert (size[i]>=0); /*size may be zero, implies no-op */
|
||||
assert (size_m[i]>0); /*destination must exist */
|
||||
/*hyperslab must fit in BUF*/
|
||||
assert ((offset_m?offset_m[i]:0)+size[i]<=size_m[i]);
|
||||
assert (istore->alignment[i]>0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Does the B-tree exist?
|
||||
*/
|
||||
if (istore->btree_addr<=0) {
|
||||
if (H5F_ISTORE_WRITE==op) {
|
||||
udata.mesg.ndims = istore->ndims;
|
||||
if ((istore->btree_addr=H5B_new (f, H5B_ISTORE, &udata))<0) {
|
||||
/* Can't create B-tree */
|
||||
HGOTO_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
} else {
|
||||
H5V_hyper_fill (istore->ndims, size, size_m, offset_m, buf, 0);
|
||||
HRETURN (SUCCEED);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize indices */
|
||||
for (i=0; i<istore->ndims; i++) {
|
||||
idx_min[i] = (offset_f?offset_f[i]:0) / istore->alignment[i];
|
||||
idx_max[i] = ((offset_f?offset_f[i]:0)+size[i]-1)/istore->alignment[i]+1;
|
||||
idx_cur[i] = idx_min[i];
|
||||
}
|
||||
|
||||
/* Allocate buffers */
|
||||
for (i=0, chunk_size=1; i<istore->ndims; i++) {
|
||||
chunk_size *= istore->alignment[i];
|
||||
}
|
||||
chunk = H5MM_xmalloc (chunk_size);
|
||||
|
||||
/* Initialize non-changing part of udata */
|
||||
udata.mesg = *istore;
|
||||
|
||||
/* Loop over all chunks */
|
||||
while (1) {
|
||||
|
||||
/* Read/Write chunk or create it if it doesn't exist */
|
||||
udata.mesg.ndims = istore->ndims;
|
||||
for (i=0; i<istore->ndims; i++) {
|
||||
udata.key.offset[i] = idx_cur[i] * istore->alignment[i];
|
||||
udata.key.size[i] = istore->alignment[i];
|
||||
sub_offset_f[i] = MAX ((offset_f?offset_f[i]:0), udata.key.offset[i]);
|
||||
sub_offset_m[i] = (offset_m?offset_m[i]:0) +
|
||||
sub_offset_f[i] - (offset_f?offset_f[i]:0);
|
||||
sub_size[i] = (idx_cur[i]+1)*istore->alignment[i]-sub_offset_f[i];
|
||||
sub_offset_ch[i] = sub_offset_f[i] - udata.key.offset[i];
|
||||
}
|
||||
if (H5F_ISTORE_WRITE==op) {
|
||||
status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
|
||||
assert (status>=0);
|
||||
} else {
|
||||
status = H5B_find (f, H5B_ISTORE, istore->btree_addr, &udata);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the operation is reading from the disk or if we are writing a
|
||||
* partial chunk then load the chunk from disk.
|
||||
*/
|
||||
if (H5F_ISTORE_READ==op ||
|
||||
!H5V_hyper_eq (istore->ndims,
|
||||
udata.key.offset, udata.key.size,
|
||||
sub_offset_f, sub_size)) {
|
||||
if (status>=0) {
|
||||
if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
|
||||
HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
|
||||
}
|
||||
} else {
|
||||
HDmemset (chunk, 0, chunk_size);
|
||||
}
|
||||
}
|
||||
|
||||
/* Transfer data to/from the chunk */
|
||||
if (H5F_ISTORE_WRITE==op) {
|
||||
H5V_hyper_copy (istore->ndims, sub_size,
|
||||
udata.key.size, sub_offset_ch, chunk,
|
||||
size_m, sub_offset_m, buf);
|
||||
if (H5F_block_write (f, udata.addr, chunk_size, chunk)<0) {
|
||||
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
|
||||
}
|
||||
} else {
|
||||
H5V_hyper_copy (istore->ndims, sub_size,
|
||||
size_m, sub_offset_m, buf,
|
||||
udata.key.size, sub_offset_ch, chunk);
|
||||
}
|
||||
|
||||
/* Increment indices */
|
||||
for (i=istore->ndims-1, carry=1; i>=0 && carry; --i) {
|
||||
if (++idx_cur[i]>=idx_max[i]) idx_cur[i] = idx_min[i];
|
||||
else carry = 0;
|
||||
}
|
||||
if (carry) break;
|
||||
}
|
||||
ret_value = SUCCEED;
|
||||
|
||||
|
||||
done:
|
||||
chunk = H5MM_xfree (chunk);
|
||||
FUNC_LEAVE (ret_value);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_read
|
||||
*
|
||||
* Purpose: Reads a multi-dimensional buffer from (part of) an indexed raw
|
||||
* storage array.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_istore_read (H5F_t *f, struct H5O_istore_t *istore,
|
||||
size_t offset[], size_t size[], void *buf)
|
||||
{
|
||||
FUNC_ENTER (H5F_istore_read, NULL, FAIL);
|
||||
|
||||
/* Check args */
|
||||
assert (f);
|
||||
assert (istore);
|
||||
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
|
||||
assert (size);
|
||||
assert (buf);
|
||||
|
||||
if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_READ,
|
||||
offset, size, H5V_ZERO, size, buf)<0) {
|
||||
/* hyperslab output failure */
|
||||
HRETURN_ERROR (H5E_IO, H5E_READERROR, FAIL);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5F_istore_write
|
||||
*
|
||||
* Purpose: Writes a multi-dimensional buffer to (part of) an indexed raw
|
||||
* storage array.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
H5F_istore_write (H5F_t *f, struct H5O_istore_t *istore,
|
||||
size_t offset[], size_t size[], void *buf)
|
||||
{
|
||||
FUNC_ENTER (H5F_istore_write, NULL, FAIL);
|
||||
|
||||
/* Check args */
|
||||
assert (f);
|
||||
assert (istore);
|
||||
assert (istore->ndims>0 && istore->ndims<=H5O_ISTORE_NDIMS);
|
||||
assert (size);
|
||||
assert (buf);
|
||||
|
||||
if (H5F_istore_copy_hyperslab (f, istore, H5F_ISTORE_WRITE,
|
||||
offset, size, H5V_ZERO, size, buf)<0) {
|
||||
/* hyperslab output failure */
|
||||
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
#define _H5Fprivate_H
|
||||
#include <H5Fpublic.h>
|
||||
|
||||
/* Private headers needed by this file */
|
||||
/* This is a near top-level header! Try not to include much! */
|
||||
#include <H5private.h>
|
||||
|
||||
/* Maximum size of boot-block buffer */
|
||||
@ -397,6 +397,7 @@ typedef struct H5F_t {
|
||||
uintn intent; /* The flags passed to H5F_open() */
|
||||
char *name; /* Name used to open file */
|
||||
H5F_file_t *shared; /* The shared file info */
|
||||
struct H5G_cwgstk_t *cwg_stack; /* CWG stack for push/pop functions */
|
||||
} H5F_t;
|
||||
|
||||
|
||||
@ -446,12 +447,20 @@ typedef struct H5F_t {
|
||||
case 2: UINT16DECODE(p,l); break; \
|
||||
}
|
||||
|
||||
struct H5O_istore_t; /*forward decl for prototype arguments*/
|
||||
|
||||
/* Private functions, not part of the publicly documented API */
|
||||
void H5F_encode_length_unusual(const H5F_t *f, uint8 **p, uint8 *l);
|
||||
void H5F_encode_offset_unusual(const H5F_t *f, uint8 **p, uint8 *o);
|
||||
H5F_t *H5F_open (const char *name, uintn flags,
|
||||
const file_create_temp_t *create_parms);
|
||||
herr_t H5F_close (H5F_t *f);
|
||||
herr_t H5F_block_read (H5F_t *f, haddr_t addr, size_t size, void *buf);
|
||||
herr_t H5F_block_write (H5F_t *f, haddr_t addr, size_t size, void *buf);
|
||||
herr_t H5F_istore_read (H5F_t *f, struct H5O_istore_t *mesg,
|
||||
size_t offset[], size_t size[], void *buf);
|
||||
herr_t H5F_istore_write (H5F_t *f, struct H5O_istore_t *mesg,
|
||||
size_t offset[], size_t size[], void *buf);
|
||||
herr_t H5F_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
|
||||
intn fwidth);
|
||||
|
||||
|
@ -410,7 +410,7 @@ H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent)
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 29 1997
|
||||
*
|
||||
* Modifications:
|
||||
|
@ -39,29 +39,32 @@
|
||||
#define PABLO_MASK H5G_node_mask
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static herr_t H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key);
|
||||
static herr_t H5G_node_encode_key (H5F_t *f, uint8 *raw, void *_key);
|
||||
static herr_t H5G_node_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
|
||||
void *_key);
|
||||
static herr_t H5G_node_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
|
||||
void *_key);
|
||||
static size_t H5G_node_size (H5F_t *f);
|
||||
static haddr_t H5G_node_new (H5F_t *f, void *_lt_key, void *_udata,
|
||||
void *_rt_key);
|
||||
static herr_t H5G_node_flush (H5F_t *f, hbool_t destroy, haddr_t addr,
|
||||
H5G_node_t *sym);
|
||||
static H5G_node_t *H5G_node_load (H5F_t *f, haddr_t addr, void *_data);
|
||||
static H5G_node_t *H5G_node_load (H5F_t *f, haddr_t addr, void *_udata1,
|
||||
void *_udata2);
|
||||
static intn H5G_node_cmp (H5F_t *f, void *_lt_key, void *_udata,
|
||||
void *_rt_key);
|
||||
static herr_t H5G_node_found (H5F_t *f, haddr_t addr,
|
||||
const void *_lt_key, void *_udata,
|
||||
const void *_rt_key);
|
||||
static haddr_t H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
|
||||
static haddr_t H5G_node_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
|
||||
void *_lt_key, hbool_t *lt_key_changed,
|
||||
void *_md_key, void *_udata,
|
||||
void *_rt_key, hbool_t *rt_key_changed);
|
||||
static herr_t H5G_node_list (H5F_t *f, haddr_t addr, void *_udata);
|
||||
static size_t H5G_node_sizeof_rkey (H5F_t *f);
|
||||
static size_t H5G_node_sizeof_rkey (H5F_t *f, const void *_udata);
|
||||
|
||||
/* H5G inherits cache-like properties from H5AC */
|
||||
const H5AC_class_t H5AC_SNODE[1] = {{
|
||||
(void*(*)(H5F_t*,haddr_t,void*))H5G_node_load,
|
||||
(void*(*)(H5F_t*,haddr_t,void*,void*))H5G_node_load,
|
||||
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5G_node_flush,
|
||||
}};
|
||||
|
||||
@ -74,6 +77,8 @@ H5B_class_t H5B_SNODE[1] = {{
|
||||
H5G_node_cmp, /*cmp */
|
||||
H5G_node_found, /*found */
|
||||
H5G_node_insert, /*insert */
|
||||
TRUE, /*follow min branch? */
|
||||
TRUE, /*follow max branch? */
|
||||
H5G_node_list, /*list */
|
||||
H5G_node_decode_key, /*decode */
|
||||
H5G_node_encode_key, /*encode */
|
||||
@ -102,7 +107,7 @@ static intn interface_initialize_g = FALSE;
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static size_t
|
||||
H5G_node_sizeof_rkey (H5F_t *f)
|
||||
H5G_node_sizeof_rkey (H5F_t *f, const void *udata __attribute__((unused)))
|
||||
{
|
||||
return H5F_SIZEOF_OFFSET(f);
|
||||
}
|
||||
@ -126,7 +131,7 @@ H5G_node_sizeof_rkey (H5F_t *f)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key)
|
||||
H5G_node_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
|
||||
{
|
||||
H5G_node_key_t *key = (H5G_node_key_t *)_key;
|
||||
|
||||
@ -160,7 +165,7 @@ H5G_node_decode_key (H5F_t *f, uint8 *raw, void *_key)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5G_node_encode_key (H5F_t *f, uint8 *raw, void *_key)
|
||||
H5G_node_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
|
||||
{
|
||||
H5G_node_key_t *key = (H5G_node_key_t *)_key;
|
||||
|
||||
@ -378,12 +383,12 @@ H5G_node_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5G_node_t *
|
||||
H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
|
||||
H5G_node_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
|
||||
{
|
||||
H5G_node_t *sym = NULL;
|
||||
size_t size = 0;
|
||||
uint8 *buf = NULL, *p = NULL;
|
||||
H5G_ac_ud1_t *ac_udata = (H5G_ac_ud1_t*)_udata;
|
||||
H5G_ac_ud1_t *ac_udata = (H5G_ac_ud1_t*)_udata1;
|
||||
H5G_node_t *ret_value = NULL; /*for error handling*/
|
||||
|
||||
FUNC_ENTER (H5G_node_load, NULL, NULL);
|
||||
@ -394,6 +399,7 @@ H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
|
||||
assert (f);
|
||||
assert (addr>=0);
|
||||
assert (ac_udata);
|
||||
assert (NULL==_udata2);
|
||||
|
||||
/*
|
||||
* Initialize variables.
|
||||
@ -453,21 +459,21 @@ H5G_node_load (H5F_t *f, haddr_t addr, void *_udata)
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_node_cmp
|
||||
*
|
||||
* Purpose: Compares two keys from a B-tree node (LEFT and RIGHT)
|
||||
* Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY)
|
||||
* against another key (not necessarily the same type)
|
||||
* pointed to by UDATA.
|
||||
*
|
||||
* Return: Success: negative if the UDATA key is less than
|
||||
* or equal to the LEFT key.
|
||||
* or equal to the LT_KEY
|
||||
*
|
||||
* positive if the UDATA key is greater
|
||||
* than the RIGHT key.
|
||||
* than the RT_KEY.
|
||||
*
|
||||
* zero if the UDATA key falls between
|
||||
* the LEFT key (exclusive) and the
|
||||
* RIGHT key (inclusive).
|
||||
* the LT_KEY (exclusive) and the
|
||||
* RT_KEY (inclusive).
|
||||
*
|
||||
* Failure: FAIL (same as LT < RT)
|
||||
* Failure: FAIL (same as UDATA < LT_KEY)
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* matzke@llnl.gov
|
||||
@ -551,13 +557,13 @@ H5G_node_found (H5F_t *f, haddr_t addr, const void *_lt_key,
|
||||
assert (addr>=0);
|
||||
assert (bt_udata);
|
||||
|
||||
ac_udata.dir_addr = bt_udata->dir_addr;
|
||||
ac_udata.grp_addr = bt_udata->grp_addr;
|
||||
ac_udata.heap_addr = bt_udata->heap_addr;
|
||||
|
||||
/*
|
||||
* Load the symbol table node for exclusive access.
|
||||
*/
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -656,7 +662,7 @@ done:
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static haddr_t
|
||||
H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
|
||||
H5G_node_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
|
||||
void *_lt_key, hbool_t *lt_key_changed,
|
||||
void *_md_key, void *_udata,
|
||||
void *_rt_key, hbool_t *rt_key_changed)
|
||||
@ -692,20 +698,12 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
|
||||
bt_udata->node_ptr = NULL;
|
||||
bt_udata->entry_ptr = NULL;
|
||||
|
||||
/*
|
||||
* Symbol tables are always split so the new symbol table node is
|
||||
* to the right of the old one.
|
||||
*/
|
||||
*anchor = H5B_ANCHOR_LT;
|
||||
*lt_key_changed = FALSE;
|
||||
*rt_key_changed = FALSE;
|
||||
|
||||
/*
|
||||
* Load the symbol node.
|
||||
*/
|
||||
ac_udata.dir_addr = bt_udata->dir_addr;
|
||||
ac_udata.grp_addr = bt_udata->grp_addr;
|
||||
ac_udata.heap_addr = bt_udata->heap_addr;
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -746,12 +744,13 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
|
||||
* node and return the address of the new right node (the
|
||||
* left node is at the same address as the original node).
|
||||
*/
|
||||
*anchor = H5B_INS_RIGHT;
|
||||
|
||||
/* The right node */
|
||||
if ((new_node = H5G_node_new (f, NULL, NULL, NULL))<0) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
|
||||
}
|
||||
if (NULL==(snrt=H5AC_find (f, H5AC_SNODE, new_node, &ac_udata))) {
|
||||
if (NULL==(snrt=H5AC_find (f, H5AC_SNODE, new_node, &ac_udata, NULL))) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
HDmemcpy (snrt->entry, sn->entry + H5G_NODE_K(f),
|
||||
@ -789,6 +788,7 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
|
||||
|
||||
} else {
|
||||
/* Where to insert the new entry? */
|
||||
*anchor = H5B_INS_NOOP;
|
||||
sn->dirty = TRUE;
|
||||
insert_into = sn;
|
||||
insert_addr = addr;
|
||||
@ -809,7 +809,7 @@ H5G_node_insert (H5F_t *f, haddr_t addr, intn *anchor,
|
||||
H5G_shadow_move (f, bt_udata->entry.shadow,
|
||||
bt_udata->name,
|
||||
insert_into->entry + idx,
|
||||
bt_udata->dir_addr);
|
||||
bt_udata->grp_addr);
|
||||
}
|
||||
|
||||
/* Move entries */
|
||||
@ -837,7 +837,8 @@ done:
|
||||
if (H5AC_unprotect (f, H5AC_SNODE, addr, sn)<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_PROTECT, FAIL);
|
||||
}
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, insert_addr, &ac_udata))) {
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, insert_addr, &ac_udata,
|
||||
NULL))) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
assert (sn==bt_udata->node_ptr);
|
||||
@ -852,7 +853,7 @@ done:
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5G_node_list
|
||||
*
|
||||
* Purpose: This function gets called during a directory list operation.
|
||||
* Purpose: This function gets called during a group list operation.
|
||||
* It should fill in data in the UDATA struct.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
@ -886,9 +887,9 @@ H5G_node_list (H5F_t *f, haddr_t addr, void *_udata)
|
||||
assert (addr>=0);
|
||||
assert (bt_udata);
|
||||
|
||||
ac_udata.dir_addr = bt_udata->dir_addr;
|
||||
ac_udata.grp_addr = bt_udata->grp_addr;
|
||||
ac_udata.heap_addr = bt_udata->heap_addr;
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata))) {
|
||||
if (NULL==(sn=H5AC_protect (f, H5AC_SNODE, addr, &ac_udata, NULL))) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -978,21 +979,21 @@ H5G_node_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
|
||||
* We have absolutely no idea where the object header for the symbol table
|
||||
* to which this node belongs is located. In fact, if the file is corrupt,
|
||||
* there may not even be an object header for that symbol table. So we
|
||||
* supply `-1' as the directory address which causes no open objects to be
|
||||
* supply `-1' as the group address which causes no open objects to be
|
||||
* associated with the node. For that reason, we flush this node from the
|
||||
* cache when we're done so if some later caller knows the header address
|
||||
* they'll be able to access the open objects.
|
||||
*/
|
||||
ac_udata.dir_addr = -1;
|
||||
ac_udata.grp_addr = -1;
|
||||
ac_udata.heap_addr = heap;
|
||||
|
||||
/*
|
||||
* If we couldn't load the symbol table node, then try loading the
|
||||
* B-tree node.
|
||||
*/
|
||||
if (NULL==(sn=H5AC_find(f, H5AC_SNODE, addr, &ac_udata))) {
|
||||
if (NULL==(sn=H5AC_find(f, H5AC_SNODE, addr, &ac_udata, NULL))) {
|
||||
H5ECLEAR; /*discard that error*/
|
||||
status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE);
|
||||
status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE, NULL);
|
||||
if (status<0) HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
|
||||
HRETURN (SUCCEED);
|
||||
}
|
||||
|
30
src/H5Gpkg.h
30
src/H5Gpkg.h
@ -20,7 +20,7 @@
|
||||
#include <H5Gprivate.h>
|
||||
|
||||
#define H5G_NODE_VERS 1 /*symbol table node version number */
|
||||
#define H5G_SIZE_HINT 1024 /*default root dir size hint */
|
||||
#define H5G_SIZE_HINT 1024 /*default root grp size hint */
|
||||
#define H5G_NODE_K(F) ((F)->shared->file_create_parms.sym_leaf_k)
|
||||
#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
|
||||
#define H5G_DEFAULT_ROOT_SIZE 32
|
||||
@ -44,7 +44,7 @@ struct H5G_entry_t {
|
||||
* A symbol table node is a collection of symbol table entries. It can
|
||||
* be thought of as the lowest level of the B-link tree that points to
|
||||
* a collection of symbol table entries that belong to a specific symbol
|
||||
* table or directory.
|
||||
* table or group.
|
||||
*/
|
||||
typedef struct H5G_node_t {
|
||||
hbool_t dirty; /*has cache been modified? */
|
||||
@ -61,7 +61,7 @@ typedef struct H5G_node_t {
|
||||
*/
|
||||
struct H5G_shadow_t {
|
||||
char *name; /*name for this entry */
|
||||
haddr_t dir_addr; /*hdr addr for dir containing shadow */
|
||||
haddr_t grp_addr; /*hdr addr for group containing shadow */
|
||||
uintn nrefs; /*reference counter */
|
||||
H5G_entry_t entry; /*local copy of symbol table entry */
|
||||
H5G_entry_t *main; /*main entry in stab node if cached */
|
||||
@ -77,6 +77,16 @@ typedef struct H5G_node_key_t {
|
||||
off_t offset; /*offset into heap for name */
|
||||
} H5G_node_key_t;
|
||||
|
||||
/*
|
||||
* Each file has a stack of open groups with the latest entry on the
|
||||
* stack the current working group. If the stack is empty then the
|
||||
* current working group is the root object.
|
||||
*/
|
||||
typedef struct H5G_cwgstk_t {
|
||||
H5G_entry_t *handle; /*a handle to an open group */
|
||||
struct H5G_cwgstk_t *next; /*next item (earlier) on stack */
|
||||
} H5G_cwgstk_t;
|
||||
|
||||
/*
|
||||
* These operations can be passed down from the H5G_stab layer to the
|
||||
* H5G_node layer through the B-tree layer.
|
||||
@ -96,7 +106,7 @@ typedef struct H5G_bt_ud1_t {
|
||||
/* downward */
|
||||
H5G_oper_t operation; /*what operation to perform */
|
||||
const char *name; /*points to temporary memory */
|
||||
haddr_t dir_addr; /*symbol table header address */
|
||||
haddr_t grp_addr; /*symbol table header address */
|
||||
haddr_t heap_addr; /*symbol table heap address */
|
||||
|
||||
/* downward for INSERT */
|
||||
@ -119,7 +129,7 @@ typedef struct H5G_bt_ud2_t {
|
||||
H5G_entry_t *entry; /*array of entries, alloc'd by caller */
|
||||
char **name; /*array of string ptrs, allocd by caller*/
|
||||
intn maxentries; /*size of the ADDR and NAME arrays */
|
||||
haddr_t dir_addr; /*symbol table header address */
|
||||
haddr_t grp_addr; /*symbol table header address */
|
||||
haddr_t heap_addr; /*heap address */
|
||||
|
||||
/* upward */
|
||||
@ -137,15 +147,15 @@ extern H5B_class_t H5B_SNODE[1];
|
||||
*/
|
||||
typedef struct H5G_ac_ud1_t {
|
||||
haddr_t heap_addr;
|
||||
haddr_t dir_addr;
|
||||
haddr_t grp_addr;
|
||||
} H5G_ac_ud1_t;
|
||||
|
||||
/* The cache subclass */
|
||||
extern const H5AC_class_t H5AC_SNODE[1];
|
||||
|
||||
/*
|
||||
* Functions that understand symbol tables but not directories. The
|
||||
* functions that understand directories are exported to the rest of
|
||||
* Functions that understand symbol tables but not names. The
|
||||
* functions that understand names are exported to the rest of
|
||||
* the library and appear in H5Gprivate.h.
|
||||
*/
|
||||
haddr_t H5G_stab_new (H5F_t *f, H5G_entry_t *self, size_t init);
|
||||
@ -160,7 +170,7 @@ intn H5G_stab_list (H5F_t *f, H5G_entry_t *self, intn maxentries,
|
||||
* Functions that understand shadow entries.
|
||||
*/
|
||||
herr_t H5G_shadow_sync (H5G_entry_t *ent);
|
||||
H5G_entry_t *H5G_shadow_open (H5F_t *f, H5G_entry_t *dir,
|
||||
H5G_entry_t *H5G_shadow_open (H5F_t *f, H5G_entry_t *grp,
|
||||
H5G_entry_t *ent);
|
||||
herr_t H5G_shadow_close (H5F_t *f, H5G_entry_t *ent);
|
||||
hbool_t H5G_shadow_p (H5G_entry_t *ent);
|
||||
@ -170,7 +180,7 @@ herr_t H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym,
|
||||
H5G_shadow_t *H5G_shadow_list (H5F_t *f, haddr_t stab_header_addr);
|
||||
herr_t H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow,
|
||||
const char *new_name, H5G_entry_t *new_entry,
|
||||
haddr_t dir_addr);
|
||||
haddr_t grp_addr);
|
||||
|
||||
/*
|
||||
* Functions that understand symbol table entries.
|
||||
|
@ -82,14 +82,15 @@ typedef struct H5G_entry_t H5G_entry_t;
|
||||
* Library prototypes... These are the ones that other packages routinely
|
||||
* call.
|
||||
*/
|
||||
H5G_entry_t *H5G_mkdir (H5F_t *f, const char *name, size_t size_hint);
|
||||
herr_t H5G_pushd (H5F_t *f, const char *name);
|
||||
herr_t H5G_popd (H5F_t *f);
|
||||
H5G_entry_t *H5G_new (H5F_t *f, const char *name, size_t size_hint);
|
||||
herr_t H5G_set (H5F_t *f, const char *name);
|
||||
herr_t H5G_push (H5F_t *f, const char *name);
|
||||
herr_t H5G_pop (H5F_t *f);
|
||||
H5G_entry_t *H5G_create (H5F_t *f, const char *name, size_t ohdr_hint);
|
||||
H5G_entry_t *H5G_open (H5F_t *f, const char *name);
|
||||
herr_t H5G_close (H5F_t *f, H5G_entry_t *ent);
|
||||
herr_t H5G_find (H5F_t *f, H5G_entry_t *cwd, H5G_entry_t *dir_ent,
|
||||
const char *name, H5G_entry_t *ent);
|
||||
herr_t H5G_find (H5F_t *f, const char *name, H5G_entry_t *grp_ent,
|
||||
H5G_entry_t *ent);
|
||||
herr_t H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
|
||||
herr_t H5G_ent_decode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
|
||||
|
||||
|
@ -19,15 +19,19 @@
|
||||
#define _H5Gpublic_H
|
||||
|
||||
/* Public headers needed by this file */
|
||||
#include <sys/types.h>
|
||||
#include <H5public.h>
|
||||
|
||||
/* Default root directory size */
|
||||
#define H5G_DEFAULT_ROOT SIZE 256
|
||||
#include <H5Apublic.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
herr_t H5Gnew (hid_t file, const char *name, size_t size_hint);
|
||||
herr_t H5Gset (hid_t file, const char *name);
|
||||
herr_t H5Gpush (hid_t file, const char *name);
|
||||
herr_t H5Gpop (hid_t file);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -29,7 +29,7 @@
|
||||
static hbool_t interface_initialize_g = FALSE;
|
||||
|
||||
typedef struct H5G_hash_t {
|
||||
haddr_t dir_addr;
|
||||
haddr_t grp_addr;
|
||||
H5G_shadow_t *head;
|
||||
struct H5G_hash_t *next;
|
||||
struct H5G_hash_t *prev;
|
||||
@ -81,15 +81,15 @@ H5G_shadow_check (H5F_t *f)
|
||||
shadow_error = TRUE;
|
||||
}
|
||||
|
||||
/* Valid directory addresses */
|
||||
if (shadow->dir_addr<0 || (shadow->dir_addr==0 && idx!=0)) {
|
||||
fprintf (stderr, "dir_addr=%lu, ",
|
||||
(unsigned long)(shadow->dir_addr));
|
||||
/* Valid group addresses */
|
||||
if (shadow->grp_addr<0 || (shadow->grp_addr==0 && idx!=0)) {
|
||||
fprintf (stderr, "grp_addr=%lu, ",
|
||||
(unsigned long)(shadow->grp_addr));
|
||||
shadow_error = TRUE;
|
||||
} else if (shadow->dir_addr!=hash->dir_addr) {
|
||||
fprintf (stderr, "dir_addr=%lu (not %lu), ",
|
||||
(unsigned long)(shadow->dir_addr),
|
||||
(unsigned long)(hash->dir_addr));
|
||||
} else if (shadow->grp_addr!=hash->grp_addr) {
|
||||
fprintf (stderr, "grp_addr=%lu (not %lu), ",
|
||||
(unsigned long)(shadow->grp_addr),
|
||||
(unsigned long)(hash->grp_addr));
|
||||
}
|
||||
|
||||
/* Linked to symbol table entry */
|
||||
@ -107,9 +107,9 @@ H5G_shadow_check (H5F_t *f)
|
||||
|
||||
/* If an error occurred then print other info */
|
||||
if (shadow_error) {
|
||||
fprintf (stderr, "idx=%u, shadow=0x%08lx, dir_addr=%lu\n",
|
||||
fprintf (stderr, "idx=%u, shadow=0x%08lx, grp_addr=%lu\n",
|
||||
idx, (unsigned long)shadow,
|
||||
(unsigned long)(shadow->dir_addr));
|
||||
(unsigned long)(shadow->grp_addr));
|
||||
nerrors++;
|
||||
}
|
||||
}
|
||||
@ -247,7 +247,7 @@ H5G_shadow_sync (H5G_entry_t *ent)
|
||||
* Function: H5G_shadow_list
|
||||
*
|
||||
* Purpose: Returns a doubly linked list of shadows for the symbol
|
||||
* table whose header address is DIR_ADDR.
|
||||
* table whose header address is GRP_ADDR.
|
||||
*
|
||||
* Return: Success: Ptr shadow list or null.
|
||||
*
|
||||
@ -261,15 +261,15 @@ H5G_shadow_sync (H5G_entry_t *ent)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
H5G_shadow_t *
|
||||
H5G_shadow_list (H5F_t *f, haddr_t dir_addr)
|
||||
H5G_shadow_list (H5F_t *f, haddr_t grp_addr)
|
||||
{
|
||||
uintn idx = dir_addr % f->shared->nshadows;
|
||||
uintn idx = grp_addr % f->shared->nshadows;
|
||||
H5G_hash_t *bucket = NULL;
|
||||
|
||||
FUNC_ENTER (H5G_shadows, NULL, NULL);
|
||||
|
||||
for (bucket=f->shared->shadow[idx]; bucket; bucket=bucket->next) {
|
||||
if (bucket->dir_addr==dir_addr) {
|
||||
if (bucket->grp_addr==grp_addr) {
|
||||
HRETURN (bucket->head);
|
||||
}
|
||||
}
|
||||
@ -317,7 +317,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
|
||||
H5G_shadow_check (f);
|
||||
#endif
|
||||
|
||||
if ((shadow=H5G_shadow_list (f, ac_udata->dir_addr))) {
|
||||
if ((shadow=H5G_shadow_list (f, ac_udata->grp_addr))) {
|
||||
heap_addr = ac_udata->heap_addr;
|
||||
|
||||
while (i<sym->nsyms && shadow) {
|
||||
@ -352,7 +352,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
|
||||
* object, open the object (again) and return a handle
|
||||
* to it.
|
||||
*
|
||||
* DIR can be the null pointer if `ent' is the root entry.
|
||||
* GRP can be the null pointer if `ent' is the root entry.
|
||||
*
|
||||
* Return: Success: Handle to open object
|
||||
*
|
||||
@ -366,7 +366,7 @@ H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
H5G_entry_t *
|
||||
H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
|
||||
H5G_shadow_open (H5F_t *f, H5G_entry_t *grp, H5G_entry_t *ent)
|
||||
{
|
||||
H5G_shadow_t *shadow = NULL;
|
||||
H5O_stab_t stab;
|
||||
@ -376,15 +376,15 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
|
||||
uintn idx;
|
||||
H5O_name_t name_mesg = {NULL};
|
||||
H5G_entry_t *ret_value = NULL;
|
||||
haddr_t dir_addr;
|
||||
haddr_t grp_addr;
|
||||
|
||||
FUNC_ENTER (H5G_shadow_open, NULL, NULL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (ent==f->shared->root_sym || dir);
|
||||
assert (ent==f->shared->root_sym || grp);
|
||||
assert (ent);
|
||||
dir_addr = dir ? dir->header : 0;
|
||||
grp_addr = grp ? grp->header : 0;
|
||||
|
||||
if ((shadow = ent->shadow)) {
|
||||
/*
|
||||
@ -396,7 +396,7 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
|
||||
|
||||
|
||||
shadow = H5MM_xcalloc (1, sizeof(H5G_shadow_t));
|
||||
if (ent==f->shared->root_sym && 0==dir_addr) {
|
||||
if (ent==f->shared->root_sym && 0==grp_addr) {
|
||||
/*
|
||||
* We're opening the root entry.
|
||||
*/
|
||||
@ -411,7 +411,7 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
|
||||
/*
|
||||
* Some entry other than the root.
|
||||
*/
|
||||
if (NULL==H5O_read (f, NO_ADDR, dir, H5O_STAB, 0, &stab)) {
|
||||
if (NULL==H5O_read (f, NO_ADDR, grp, H5O_STAB, 0, &stab)) {
|
||||
HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, NULL);
|
||||
}
|
||||
if (NULL==(s=H5H_peek (f, stab.heap_addr, ent->name_off))) {
|
||||
@ -428,18 +428,18 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *dir, H5G_entry_t *ent)
|
||||
shadow->nrefs = 1;
|
||||
shadow->entry = *ent;
|
||||
shadow->entry.dirty = FALSE;
|
||||
shadow->dir_addr = dir_addr;
|
||||
shadow->grp_addr = grp_addr;
|
||||
|
||||
/*
|
||||
* Link it into the shadow heap
|
||||
*/
|
||||
idx = dir_addr % f->shared->nshadows;
|
||||
idx = grp_addr % f->shared->nshadows;
|
||||
for (hash=f->shared->shadow[idx]; hash; hash=hash->next) {
|
||||
if (hash->dir_addr==dir_addr) break;
|
||||
if (hash->grp_addr==grp_addr) break;
|
||||
}
|
||||
if (!hash) {
|
||||
hash = H5MM_xcalloc (1, sizeof(H5G_hash_t));
|
||||
hash->dir_addr = dir_addr;
|
||||
hash->grp_addr = grp_addr;
|
||||
hash->next = f->shared->shadow[idx];
|
||||
f->shared->shadow[idx] = hash;
|
||||
if (hash->next) hash->next->prev = hash;
|
||||
@ -524,7 +524,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
|
||||
/* clean the shadow */
|
||||
if (1==shadow->nrefs && ent->dirty) {
|
||||
if (!shadow->main &&
|
||||
NULL==H5G_stab_find (f, shadow->dir_addr, NULL, shadow->name)) {
|
||||
NULL==H5G_stab_find (f, shadow->grp_addr, NULL, shadow->name)) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
|
||||
}
|
||||
assert (shadow->main);
|
||||
@ -540,9 +540,9 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
|
||||
H5G_shadow_dissociate (ent);
|
||||
|
||||
/* find symtabs shadow list */
|
||||
idx = shadow->dir_addr % f->shared->nshadows;
|
||||
idx = shadow->grp_addr % f->shared->nshadows;
|
||||
for (hash=f->shared->shadow[idx]; hash; hash=hash->next) {
|
||||
if (hash->dir_addr==shadow->dir_addr) break;
|
||||
if (hash->grp_addr==shadow->grp_addr) break;
|
||||
}
|
||||
assert (hash);
|
||||
|
||||
@ -577,7 +577,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
|
||||
* Function: H5G_shadow_move
|
||||
*
|
||||
* Purpose: Moves the SHADOW for some entry to correspond to a
|
||||
* NEW_ENTRY. The DIR_ADDR is the address for the directory
|
||||
* NEW_ENTRY. The GRP_ADDR is the address for the group
|
||||
* which contains NEW_ENTRY.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
@ -593,7 +593,7 @@ H5G_shadow_close (H5F_t *f, H5G_entry_t *ent)
|
||||
*/
|
||||
herr_t
|
||||
H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
|
||||
H5G_entry_t *new_entry, haddr_t dir_addr)
|
||||
H5G_entry_t *new_entry, haddr_t grp_addr)
|
||||
{
|
||||
H5G_hash_t *hash;
|
||||
uintn idx;
|
||||
@ -602,29 +602,29 @@ H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
|
||||
|
||||
assert (shadow);
|
||||
assert (new_entry);
|
||||
assert (dir_addr>0);
|
||||
assert (grp_addr>0);
|
||||
|
||||
if (0==shadow->dir_addr) {
|
||||
if (0==shadow->grp_addr) {
|
||||
/*
|
||||
* We're moving the shadow for the root object. This simplifies things
|
||||
* greatly since it implies that this is the only shadow currently
|
||||
* defined for the entire file.
|
||||
*/
|
||||
idx = dir_addr % f->shared->nshadows;
|
||||
idx = grp_addr % f->shared->nshadows;
|
||||
assert (NULL==f->shared->shadow[idx]); /*Nothing at new idx... */
|
||||
hash = f->shared->shadow[0];
|
||||
assert (hash); /*..but root idx has something. */
|
||||
assert (0==hash->dir_addr); /*..and it's the root something */
|
||||
assert (0==hash->grp_addr); /*..and it's the root something */
|
||||
assert (NULL==hash->next); /*..and just that */
|
||||
assert (hash->head==shadow); /*..and exactly that */
|
||||
|
||||
/* Move root entry to new hash bucket */
|
||||
f->shared->shadow[idx] = hash;
|
||||
f->shared->shadow[0] = NULL;
|
||||
hash->dir_addr = dir_addr;
|
||||
hash->grp_addr = grp_addr;
|
||||
|
||||
/* Associate SHADOW with NEW_ENTRY */
|
||||
shadow->dir_addr = dir_addr;
|
||||
shadow->grp_addr = grp_addr;
|
||||
shadow->main = new_entry;
|
||||
new_entry->shadow = shadow;
|
||||
|
||||
@ -636,7 +636,7 @@ H5G_shadow_move (H5F_t *f, H5G_shadow_t *shadow, const char *new_name,
|
||||
/*
|
||||
* Other shadows never move.
|
||||
*/
|
||||
assert (shadow->dir_addr==dir_addr);
|
||||
assert (shadow->grp_addr==grp_addr);
|
||||
shadow->main = new_entry;
|
||||
new_entry->shadow = shadow;
|
||||
}
|
||||
@ -682,7 +682,7 @@ H5G_shadow_flush (H5F_t *f, hbool_t invalidate)
|
||||
*/
|
||||
if (shadow->entry.dirty) {
|
||||
if (!shadow->main &&
|
||||
NULL==H5G_stab_find (f, shadow->dir_addr, NULL,
|
||||
NULL==H5G_stab_find (f, shadow->grp_addr, NULL,
|
||||
shadow->name)) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
|
||||
}
|
||||
@ -698,12 +698,12 @@ H5G_shadow_flush (H5F_t *f, hbool_t invalidate)
|
||||
* some object before closing the file. Since this is hard to
|
||||
* debug, we'll be nice and print the names here. We don't know
|
||||
* the full name, but we'll print the file address (relative to
|
||||
* the boot block) of the object header for the directory that
|
||||
* the boot block) of the object header for the group that
|
||||
* contains the open object.
|
||||
*/
|
||||
if (invalidate) {
|
||||
fprintf (stderr, "Open object <%lu>/%s",
|
||||
(unsigned long)(shadow->dir_addr),
|
||||
fprintf (stderr, "Warning: open object <%lu>/%s",
|
||||
(unsigned long)(shadow->grp_addr),
|
||||
shadow->name);
|
||||
if (shadow->nrefs>1) {
|
||||
fprintf (stderr, " (%d times)", shadow->nrefs);
|
||||
|
@ -87,14 +87,14 @@ H5G_stab_new (H5F_t *f, H5G_entry_t *self, size_t init)
|
||||
}
|
||||
|
||||
/* Create the B-tree */
|
||||
if ((stab.btree_addr = H5B_new (f, H5B_SNODE))<0) {
|
||||
if ((stab.btree_addr = H5B_new (f, H5B_SNODE, NULL))<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create B-tree*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Create symbol table object header. It has a zero link count
|
||||
* since nothing refers to it yet. The link count will be
|
||||
* incremented if the object is added to the directory hierarchy.
|
||||
* incremented if the object is added to the group directed graph.
|
||||
*/
|
||||
if ((addr = H5O_new (f, 0, 4+2*H5F_SIZEOF_OFFSET(f)))<0) {
|
||||
HRETURN_ERROR (H5E_SYM, H5E_CANTINIT, FAIL); /*can't create header*/
|
||||
@ -169,7 +169,7 @@ H5G_stab_find (H5F_t *f, haddr_t addr, H5G_entry_t *self,
|
||||
udata.operation = H5G_OPER_FIND;
|
||||
udata.name = name;
|
||||
udata.heap_addr = stab.heap_addr;
|
||||
udata.dir_addr = addr;
|
||||
udata.grp_addr = addr;
|
||||
udata.node_ptr = NULL;
|
||||
|
||||
/* search the B-tree */
|
||||
@ -245,7 +245,7 @@ H5G_stab_insert (H5F_t *f, H5G_entry_t *self, const char *name,
|
||||
udata.operation = H5G_OPER_INSERT;
|
||||
udata.name = name;
|
||||
udata.heap_addr = stab.heap_addr;
|
||||
udata.dir_addr = self->header;
|
||||
udata.grp_addr = self->header;
|
||||
udata.entry = *ent;
|
||||
udata.entry.name_off = -1;
|
||||
udata.node_ptr = NULL;
|
||||
@ -326,7 +326,7 @@ H5G_stab_list (H5F_t *f, H5G_entry_t *self, intn maxentries,
|
||||
}
|
||||
udata.entry = entries;
|
||||
udata.name = names;
|
||||
udata.dir_addr = self->header;
|
||||
udata.grp_addr = self->header;
|
||||
udata.heap_addr = stab.heap_addr;
|
||||
udata.maxentries = maxentries;
|
||||
udata.nsyms = 0;
|
||||
|
21
src/H5H.c
21
src/H5H.c
@ -45,14 +45,14 @@ typedef struct H5H_t {
|
||||
} H5H_t;
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static H5H_t *H5H_load (H5F_t *f, haddr_t addr, void *udata);
|
||||
static H5H_t *H5H_load (H5F_t *f, haddr_t addr, void *udata1, void *udata2);
|
||||
static herr_t H5H_flush (H5F_t *f, hbool_t dest, haddr_t addr, H5H_t *heap);
|
||||
|
||||
/*
|
||||
* H5H inherits cache-like properties from H5AC
|
||||
*/
|
||||
static const H5AC_class_t H5AC_HEAP[1] = {{
|
||||
(void*(*)(H5F_t*,haddr_t,void*))H5H_load,
|
||||
(void*(*)(H5F_t*,haddr_t,void*,void*))H5H_load,
|
||||
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5H_flush,
|
||||
}};
|
||||
|
||||
@ -161,7 +161,7 @@ H5H_new (H5F_t *f, H5H_type_t heap_type, size_t size_hint)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5H_t *
|
||||
H5H_load (H5F_t *f, haddr_t addr, void *udata)
|
||||
H5H_load (H5F_t *f, haddr_t addr, void *udata1, void *udata2)
|
||||
{
|
||||
uint8 hdr[20], *p;
|
||||
H5H_t *heap=NULL;
|
||||
@ -175,7 +175,8 @@ H5H_load (H5F_t *f, haddr_t addr, void *udata)
|
||||
assert (f);
|
||||
assert (addr>0);
|
||||
assert (H5H_SIZEOF_HDR(f) <= sizeof hdr);
|
||||
assert (!udata);
|
||||
assert (!udata1);
|
||||
assert (!udata2);
|
||||
|
||||
if (H5F_block_read (f, addr, H5H_SIZEOF_HDR(f), hdr)<0) {
|
||||
HRETURN_ERROR (H5E_HEAP, H5E_READERROR, NULL);
|
||||
@ -395,7 +396,7 @@ H5H_read (H5F_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
|
||||
assert (addr>0);
|
||||
assert (offset>=0);
|
||||
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
|
||||
}
|
||||
assert (offset<heap->mem_alloc);
|
||||
@ -455,7 +456,7 @@ H5H_peek (H5F_t *f, haddr_t addr, off_t offset)
|
||||
assert (addr>0);
|
||||
assert (offset>=0);
|
||||
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, NULL);
|
||||
}
|
||||
assert (offset<heap->mem_alloc);
|
||||
@ -536,7 +537,7 @@ H5H_insert (H5F_t *f, haddr_t addr, size_t buf_size, const void *buf)
|
||||
need = buf_size;
|
||||
H5H_ALIGN (need);
|
||||
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
heap->dirty += 1;
|
||||
@ -686,7 +687,7 @@ H5H_write (H5F_t *f, haddr_t addr, off_t offset, size_t size,
|
||||
assert (offset>=0);
|
||||
assert (buf);
|
||||
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
assert (offset<heap->mem_alloc);
|
||||
@ -748,7 +749,7 @@ H5H_remove (H5F_t *f, haddr_t addr, off_t offset, size_t size)
|
||||
assert (offset>=0);
|
||||
assert (size>0);
|
||||
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
|
||||
if (NULL==(heap=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
assert (offset<heap->mem_alloc);
|
||||
@ -864,7 +865,7 @@ H5H_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth)
|
||||
assert (indent>=0);
|
||||
assert (fwidth>=0);
|
||||
|
||||
if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL))) {
|
||||
if (NULL==(h=H5AC_find (f, H5AC_HEAP, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_HEAP, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
|
43
src/H5O.c
43
src/H5O.c
@ -26,7 +26,7 @@
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static herr_t H5O_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh);
|
||||
static H5O_t *H5O_load (H5F_t *f, haddr_t addr, void *_data);
|
||||
static H5O_t *H5O_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2);
|
||||
static intn H5O_find_in_ohdr (H5F_t *f, haddr_t addr,
|
||||
const H5O_class_t **type_p, intn sequence);
|
||||
static intn H5O_alloc (H5F_t *f, H5O_t *oh, const H5O_class_t *type,
|
||||
@ -36,7 +36,7 @@ static intn H5O_alloc_new_chunk (H5F_t *f, H5O_t *oh, size_t size);
|
||||
|
||||
/* H5O inherits cache-like properties from H5AC */
|
||||
static const H5AC_class_t H5AC_OHDR[1] = {{
|
||||
(void*(*)(H5F_t*,haddr_t,void*))H5O_load,
|
||||
(void*(*)(H5F_t*,haddr_t,void*,void*))H5O_load,
|
||||
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5O_flush,
|
||||
}};
|
||||
|
||||
@ -45,17 +45,17 @@ static intn interface_initialize_g = FALSE;
|
||||
|
||||
/* ID to type mapping */
|
||||
static const H5O_class_t *const message_type_g[] = {
|
||||
H5O_NULL, /*0x0000 Null */
|
||||
H5O_SIM_DIM, /*0x0001 Simple dimensionality */
|
||||
H5O_NULL, /*0x0000 Null */
|
||||
H5O_SIM_DIM, /*0x0001 Simple dimensionality */
|
||||
NULL, /*0x0002 Data space (fiber bundle?) */
|
||||
H5O_SIM_DTYPE, /*0x0003 Simple data type */
|
||||
H5O_SIM_DTYPE, /*0x0003 Simple data type */
|
||||
NULL, /*0x0004 Compound data type */
|
||||
H5O_STD_STORE, /*0x0005 Data storage -- standard object */
|
||||
H5O_STD_STORE, /*0x0005 Data storage -- standard object */
|
||||
NULL, /*0x0006 Data storage -- compact object */
|
||||
NULL, /*0x0007 Data storage -- external object */
|
||||
NULL, /*0x0008 Data storage -- indexed object */
|
||||
NULL, /*0x0009 Data storage -- chunked object */
|
||||
NULL, /*0x000A Data storage -- sparse object */
|
||||
H5O_ISTORE, /*0x0008 Data storage -- indexed object */
|
||||
NULL, /*0x0009 Not assigned */
|
||||
NULL, /*0x000A Not assigned */
|
||||
NULL, /*0x000B Data storage -- compressed object */
|
||||
NULL, /*0x000C Attribute list */
|
||||
H5O_NAME, /*0x000D Object name */
|
||||
@ -105,7 +105,7 @@ H5O_new (H5F_t *f, intn nlink, size_t size_hint)
|
||||
HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL);
|
||||
}
|
||||
|
||||
/* allocate the object header in fill in header fields */
|
||||
/* allocate the object header and fill in header fields */
|
||||
oh = H5MM_xcalloc (1, sizeof(H5O_t));
|
||||
oh->dirty = TRUE;
|
||||
oh->version = H5O_VERSION;
|
||||
@ -165,7 +165,7 @@ H5O_new (H5F_t *f, intn nlink, size_t size_hint)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5O_t *
|
||||
H5O_load (H5F_t *f, haddr_t addr, void *_data)
|
||||
H5O_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
|
||||
{
|
||||
H5O_t *oh = NULL;
|
||||
H5O_t *ret_value = (void*)1; /*kludge for HGOTO_ERROR*/
|
||||
@ -182,7 +182,8 @@ H5O_load (H5F_t *f, haddr_t addr, void *_data)
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (addr>=0);
|
||||
assert (!_data);
|
||||
assert (!_udata1);
|
||||
assert (!_udata2);
|
||||
|
||||
/* allocate ohdr and init chunk list */
|
||||
oh = H5MM_xcalloc (1, sizeof(H5O_t));
|
||||
@ -454,7 +455,7 @@ H5O_flush (H5F_t *f, hbool_t destroy, haddr_t addr, H5O_t *oh)
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -513,7 +514,7 @@ H5O_link (H5F_t *f, H5G_entry_t *ent, intn adjust)
|
||||
addr = H5G_ent_addr (ent);
|
||||
|
||||
/* get header */
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -600,7 +601,7 @@ H5O_read (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
|
||||
#endif
|
||||
|
||||
/* copy the message to the user-supplied buffer */
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
|
||||
}
|
||||
retval = (type->copy)(oh->mesg[idx].native, mesg);
|
||||
@ -643,7 +644,7 @@ H5O_find_in_ohdr (H5F_t *f, haddr_t addr, const H5O_class_t **type_p,
|
||||
assert (type_p);
|
||||
|
||||
/* load the object header */
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -710,7 +711,7 @@ H5O_peek (H5F_t *f, haddr_t addr, const H5O_class_t *type, intn sequence)
|
||||
if ((idx = H5O_find_in_ohdr (f, addr, &type, sequence))<0) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_NOTFOUND, NULL);
|
||||
}
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL);
|
||||
}
|
||||
|
||||
@ -767,7 +768,7 @@ H5O_modify (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
|
||||
assert (mesg);
|
||||
if (addr<=0) addr = H5G_ent_addr (ent);
|
||||
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -842,7 +843,7 @@ H5O_modify (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 28 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -865,7 +866,7 @@ H5O_remove (H5F_t *f, haddr_t addr, H5G_entry_t *ent,
|
||||
if (addr<=0) addr = H5G_ent_addr (ent);
|
||||
|
||||
/* load the object header */
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
@ -1309,7 +1310,7 @@ H5O_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent, intn fwidth)
|
||||
assert (indent>=0);
|
||||
assert (fwidth>=0);
|
||||
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL))) {
|
||||
if (NULL==(oh=H5AC_find (f, H5AC_OHDR, addr, NULL, NULL))) {
|
||||
HRETURN_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL);
|
||||
}
|
||||
|
||||
|
271
src/H5Oistore.c
Normal file
271
src/H5Oistore.c
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright (C) 1997 NCSA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Programmer: Robb Matzke <matzke@llnl.gov>
|
||||
* Wednesday, October 8, 1997
|
||||
*/
|
||||
#include <H5private.h>
|
||||
#include <H5Eprivate.h>
|
||||
#include <H5MMprivate.h>
|
||||
#include <H5Oprivate.h>
|
||||
|
||||
#define PABLO_MASK H5O_istore_mask
|
||||
|
||||
/* PRIVATE PROTOTYPES */
|
||||
static void *H5O_istore_decode (H5F_t *f, size_t raw_size, const uint8 *p);
|
||||
static herr_t H5O_istore_encode (H5F_t *f, size_t size, uint8 *p,
|
||||
const void *_mesg);
|
||||
static void *H5O_istore_copy (const void *_mesg, void *_dest);
|
||||
static size_t H5O_istore_size (H5F_t *f, const void *_mesg);
|
||||
static herr_t H5O_istore_debug (H5F_t *f, const void *_mesg, FILE *stream,
|
||||
intn indent, intn fwidth);
|
||||
|
||||
/* This message derives from H5O */
|
||||
const H5O_class_t H5O_ISTORE[1] = {{
|
||||
H5O_ISTORE_ID, /*message id number */
|
||||
"istore", /*message name for debugging */
|
||||
sizeof(H5O_istore_t), /*native message size */
|
||||
H5G_NOTHING_CACHED, /*symtab entry `type' field */
|
||||
H5O_istore_decode, /*decode message */
|
||||
H5O_istore_encode, /*encode message */
|
||||
NULL, /*get messsage from stab entry */
|
||||
NULL, /*put message into stab entry */
|
||||
H5O_istore_copy, /*copy the native value */
|
||||
H5O_istore_size, /*size of message on disk */
|
||||
NULL, /*reset method */
|
||||
H5O_istore_debug, /*debug the message */
|
||||
}};
|
||||
|
||||
/* Is the interface initialized? */
|
||||
static hbool_t interface_initialize_g = FALSE;
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_istore_decode
|
||||
*
|
||||
* Purpose: Decode an indexed storage message and return a pointer to a
|
||||
* new one created with malloc().
|
||||
*
|
||||
* Return: Success: Ptr to new message in native order.
|
||||
*
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 8, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void *
|
||||
H5O_istore_decode (H5F_t *f, size_t raw_size, const uint8 *p)
|
||||
{
|
||||
H5O_istore_t *mesg = NULL;
|
||||
intn i;
|
||||
|
||||
FUNC_ENTER (H5O_istore_decode, NULL, NULL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (p);
|
||||
|
||||
/* decode */
|
||||
mesg = H5MM_xcalloc (1, sizeof(H5O_istore_t));
|
||||
H5F_decode_offset (f, p, mesg->btree_addr);
|
||||
mesg->ndims = *p++;
|
||||
assert (raw_size == H5O_istore_size (f, mesg));
|
||||
|
||||
/* Reserved bytes */
|
||||
p += 7;
|
||||
|
||||
/* Read the min_corner, max_corner, and alignment values */
|
||||
for (i=0; i<mesg->ndims; i++) {
|
||||
UINT32DECODE (p, mesg->alignment[i]);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (mesg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_istore_encode
|
||||
*
|
||||
* Purpose: Encodes a message.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 8, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5O_istore_encode (H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg)
|
||||
{
|
||||
const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
|
||||
int i;
|
||||
|
||||
FUNC_ENTER (H5O_istore_encode, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (mesg);
|
||||
assert (mesg->ndims>0 && mesg->ndims<=H5O_ISTORE_NDIMS);
|
||||
assert (raw_size == H5O_istore_size (f, _mesg));
|
||||
assert (p);
|
||||
|
||||
/* encode B-tree offset */
|
||||
H5F_encode_offset (f, p, mesg->btree_addr);
|
||||
|
||||
/* number of dimensions */
|
||||
*p++ = mesg->ndims;
|
||||
|
||||
/* reserved bytes should be zero */
|
||||
for (i=0; i<7; i++) *p++ = 0;
|
||||
|
||||
/* min_corner, max_corner, and alignment */
|
||||
for (i=0; i<mesg->ndims; i++) {
|
||||
UINT32ENCODE (p, mesg->alignment[i]);
|
||||
}
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_istore_copy
|
||||
*
|
||||
* Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
|
||||
* necessary.
|
||||
*
|
||||
* Return: Success: Ptr to _DEST
|
||||
*
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 8, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void *
|
||||
H5O_istore_copy (const void *_mesg, void *_dest)
|
||||
{
|
||||
const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
|
||||
H5O_istore_t *dest = (H5O_istore_t *)_dest;
|
||||
|
||||
FUNC_ENTER (H5O_istore_copy, NULL, NULL);
|
||||
|
||||
/* check args */
|
||||
assert (mesg);
|
||||
if (!dest) dest = H5MM_xcalloc (1, sizeof(H5O_istore_t));
|
||||
|
||||
/* copy */
|
||||
*dest = *mesg;
|
||||
|
||||
FUNC_LEAVE ((void*)dest);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_istore_size
|
||||
*
|
||||
* Purpose: Returns the size of the raw message in bytes not counting the
|
||||
* message type or size fields, but only the data fields. This
|
||||
* function doesn't take into account message alignment.
|
||||
*
|
||||
* Return: Success: Message data size in bytes
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 8, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static size_t
|
||||
H5O_istore_size (H5F_t *f, const void *_mesg)
|
||||
{
|
||||
const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
|
||||
size_t ret_value = FAIL;
|
||||
|
||||
FUNC_ENTER (H5O_istore_size, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (mesg);
|
||||
assert (mesg->ndims>0 && mesg->ndims<=H5O_ISTORE_NDIMS);
|
||||
|
||||
ret_value = H5F_SIZEOF_OFFSET (f) + /* B-tree address */
|
||||
1 + /* max dimension index */
|
||||
7 + /* reserved bytes */
|
||||
mesg->ndims * 4; /* alignment */
|
||||
|
||||
FUNC_LEAVE (ret_value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: H5O_istore_debug
|
||||
*
|
||||
* Purpose: Prints debugging info for a message.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 8, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
H5O_istore_debug (H5F_t *f, const void *_mesg, FILE *stream, intn indent,
|
||||
intn fwidth)
|
||||
{
|
||||
const H5O_istore_t *mesg = (const H5O_istore_t *)_mesg;
|
||||
intn i;
|
||||
|
||||
FUNC_ENTER (H5O_istore_debug, NULL, FAIL);
|
||||
|
||||
/* check args */
|
||||
assert (f);
|
||||
assert (mesg);
|
||||
assert (stream);
|
||||
assert (indent>=0);
|
||||
assert (fwidth>=0);
|
||||
|
||||
fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
|
||||
"B-tree address:",
|
||||
(unsigned long)(mesg->btree_addr));
|
||||
fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
|
||||
"Number of dimensions:",
|
||||
(unsigned long)(mesg->ndims));
|
||||
|
||||
/* Alignment */
|
||||
fprintf (stream, "%*s%-*s {", indent, "", fwidth,
|
||||
"Alignment:");
|
||||
for (i=0; i<mesg->ndims; i++) {
|
||||
fprintf (stream, "%s%lu", i?", ":"",
|
||||
(unsigned long)(mesg->alignment[i]));
|
||||
}
|
||||
fprintf (stream, "}\n");
|
||||
|
||||
FUNC_LEAVE (SUCCEED);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Created: H5Oname.c
|
||||
* Aug 12 1997
|
||||
* Robb Matzke <robb@maya.nuance.com>
|
||||
* Robb Matzke <matzke@llnl.gov>
|
||||
*
|
||||
* Purpose: Object name message.
|
||||
*
|
||||
@ -62,7 +62,7 @@ static hbool_t interface_initialize_g = FALSE;
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -101,7 +101,7 @@ H5O_name_decode (H5F_t *f, size_t raw_size, const uint8 *p)
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -144,7 +144,7 @@ H5O_name_encode (H5F_t *f, size_t raw_size, uint8 *p, const void *_mesg)
|
||||
* Failure: NULL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -184,7 +184,7 @@ H5O_name_copy (const void *_mesg, void *_dest)
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -219,7 +219,7 @@ H5O_name_size (H5F_t *f, const void *_mesg)
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
@ -253,7 +253,7 @@ H5O_name_reset (void *_mesg)
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* robb@maya.nuance.com
|
||||
* matzke@llnl.gov
|
||||
* Aug 12 1997
|
||||
*
|
||||
* Modifications:
|
||||
|
@ -115,10 +115,23 @@ typedef h5_atomic_type_t H5O_sim_dtype_t;
|
||||
#define H5O_STD_STORE_ID 0x0005
|
||||
extern const H5O_class_t H5O_STD_STORE[1];
|
||||
|
||||
typedef struct H5O_std_store {
|
||||
haddr_t off;
|
||||
haddr_t len;
|
||||
} H5O_std_store_t;
|
||||
typedef struct H5O_std_store_t {
|
||||
haddr_t off;
|
||||
haddr_t len;
|
||||
} H5O_std_store_t;
|
||||
|
||||
/*
|
||||
* Indexed Data Storage message.
|
||||
*/
|
||||
#define H5O_ISTORE_ID 0x0008
|
||||
#define H5O_ISTORE_NDIMS 32
|
||||
extern const H5O_class_t H5O_ISTORE[1];
|
||||
|
||||
typedef struct H5O_istore_t {
|
||||
haddr_t btree_addr; /*file address of B-tree */
|
||||
uintn ndims; /*num dimensions in stored data */
|
||||
size_t alignment[H5O_ISTORE_NDIMS]; /*algn in logical space */
|
||||
} H5O_istore_t;
|
||||
|
||||
/*
|
||||
* Object name message.
|
||||
|
@ -205,7 +205,7 @@ H5O_sim_dtype_fast (const H5G_cache_t *cache, void *mesg)
|
||||
method is required for simple datatypes, as they can be cached in the
|
||||
symbol-table entry)
|
||||
--------------------------------------------------------------------------*/
|
||||
static herr_t
|
||||
static hbool_t
|
||||
H5O_sim_dtype_cache (H5G_type_t *cache_type, H5G_cache_t *cache,
|
||||
const void *mesg)
|
||||
{
|
||||
|
@ -1,5 +1,11 @@
|
||||
/* src/H5config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
#undef const
|
||||
|
||||
/* Define as __inline if that's what the C compiler calls it. */
|
||||
#undef inline
|
||||
|
||||
/* Define to `long' if <sys/types.h> doesn't define. */
|
||||
#undef off_t
|
||||
|
||||
@ -13,6 +19,12 @@
|
||||
byte first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* Define if the __attribute__(()) extension is present */
|
||||
/* #define HAVE_ATTRIBUTE */
|
||||
|
||||
/* Define if the compiler understands the __FUNCTION__ keyword. */
|
||||
/* #define HAVE_FUNCTION */
|
||||
|
||||
/* The number of bytes in a double. */
|
||||
#undef SIZEOF_DOUBLE
|
||||
|
||||
|
@ -63,8 +63,19 @@
|
||||
#define MACIO 2
|
||||
#define WINNTIO 3
|
||||
#define PAGEBUFIO 4
|
||||
#define FILELIB POSIXBUFIO
|
||||
#ifndef FILELIB
|
||||
# define FILELIB POSIXBUFIO
|
||||
#endif
|
||||
|
||||
/* Does the compiler support the __attribute__(()) syntax? */
|
||||
#ifndef HAVE_ATTRIBUTE
|
||||
# define __attribute__(X) /*void*/
|
||||
#endif
|
||||
|
||||
/* Does the compiler expand __FUNCTION__? */
|
||||
#ifndef HAVE_FUNCTION
|
||||
# define __FUNCTION__ "NoFuntionName"
|
||||
#endif
|
||||
|
||||
/* number of members in an array */
|
||||
#ifndef NELMTS
|
||||
@ -359,6 +370,7 @@ typedef off_t haddr_t;
|
||||
/*
|
||||
* And now for a couple non-Posix functions...
|
||||
*/
|
||||
extern char *strdup (const char *s);
|
||||
#define HDstrdup(S) strdup(S)
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
|
@ -14,10 +14,10 @@ LIB=libhdf5.a
|
||||
PROGS=debug
|
||||
|
||||
# Source and object files for the library (lexicographically)...
|
||||
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5G.c \
|
||||
H5Gent.c H5Gnode.c H5Gshad.c H5Gstab.c H5H.c H5M.c H5MF.c H5MM.c \
|
||||
H5O.c H5Ocont.c H5Oname.c H5Onull.c H5Osdtyp.c H5Osdim.c H5Ostab.c \
|
||||
H5Ostdst.c H5P.c H5T.c
|
||||
LIB_SRC=H5.c H5A.c H5AC.c H5B.c H5C.c H5D.c H5Dconv.c H5E.c H5F.c H5Fistore.c \
|
||||
H5G.c H5Gent.c H5Gnode.c H5Gshad.c H5Gstab.c H5H.c H5M.c H5MF.c \
|
||||
H5MM.c H5O.c H5Ocont.c H5Oistore.c H5Oname.c H5Onull.c H5Osdtyp.c \
|
||||
H5Osdim.c H5Ostab.c H5Ostdst.c H5P.c H5T.c H5V.c
|
||||
|
||||
LIB_OBJ=$(LIB_SRC:.c=.o)
|
||||
|
||||
@ -35,7 +35,7 @@ PUB_HDR=H5public.h H5Apublic.h H5ACpublic.h H5Bpublic.h H5Cpublic.h \
|
||||
PRIVATE_HDR=H5private.h H5Aprivate.h H5ACprivate.h H5Bprivate.h \
|
||||
H5Cprivate.h H5Dprivate.h H5Eprivate.h H5Fprivate.h H5Gprivate.h \
|
||||
H5Gpkg.h H5Hprivate.h H5Mprivate.h H5MFprivate.h H5MMprivate.h \
|
||||
H5Oprivate.h H5Pprivate.h H5Tprivate.h
|
||||
H5Oprivate.h H5Pprivate.h H5Tprivate.h H5Vprivate.h
|
||||
|
||||
# How to build the programs...
|
||||
debug: debug.o $(LIB)
|
||||
|
@ -10,18 +10,38 @@
|
||||
CPPFLAGS=-I. -I../src @CPPFLAGS@
|
||||
|
||||
# These are our main targets:
|
||||
PROGS=testhdf5
|
||||
PROGS=testhdf5 hyperslab istore
|
||||
TESTS=$(PROGS)
|
||||
|
||||
# Source and object files for programs...
|
||||
PROG_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5t.c th5p.c th5d.c
|
||||
# Source and object files for programs... The PROG_SRC list contains all the
|
||||
# source files and is used for things like dependencies, archiving, etc. The
|
||||
# other source lists are for the individual tests, the files of which may
|
||||
# overlap with other tests.
|
||||
PROG_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5t.c th5p.c \
|
||||
th5d.c hyperslab.c istore.c
|
||||
PROG_OBJ=$(PROG_SRC:.c=.o)
|
||||
|
||||
TESTHDF5_SRC=testhdf5.c tfile.c theap.c tmeta.c tohdr.c tstab.c th5t.c \
|
||||
th5p.c th5d.c
|
||||
TESTHDF5_OBJ=$(TESTHDF5_SRC:.c=.o)
|
||||
|
||||
HYPERSLAB_SRC=hyperslab.c
|
||||
HYPERSLAB_OBJ=$(HYPERSLAB_SRC:.c=.o)
|
||||
|
||||
ISTORE_SRC=istore.c
|
||||
ISTORE_OBJ=$(ISTORE_SRC:.c=.o)
|
||||
|
||||
# Private header files (not to be installed)...
|
||||
PRIVATE_HDR=testhdf5.h
|
||||
|
||||
# How to build the programs...
|
||||
testhdf5: $(PROG_OBJ) ../src/libhdf5.a
|
||||
$(CC) $(CFLAGS) -o $@ $(PROG_OBJ) ../src/libhdf5.a $(LIBS)
|
||||
testhdf5: $(TESTHDF5_OBJ) ../src/libhdf5.a
|
||||
$(CC) $(CFLAGS) -o $@ $(TESTHDF5_OBJ) ../src/libhdf5.a $(LIBS)
|
||||
|
||||
hyperslab: $(HYPERSLAB_OBJ) ../src/libhdf5.a
|
||||
$(CC) $(CFLAGS) -o $@ $(HYPERSLAB_OBJ) ../src/libhdf5.a $(LIBS)
|
||||
|
||||
istore: $(ISTORE_OBJ) ../src/libhdf5.a
|
||||
$(CC) $(CFLAGS) -o $@ $(ISTORE_OBJ) ../src/libhdf5.a $(LIBS)
|
||||
|
||||
@CONCLUDE@
|
||||
|
431
test/istore.c
Normal file
431
test/istore.c
Normal file
@ -0,0 +1,431 @@
|
||||
/*
|
||||
* Copyright (C) 1997 NCSA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Programmer: Robb Matzke <matzke@llnl.gov>
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Purpose: Tests various aspects of indexed raw data storage.
|
||||
*/
|
||||
#include <H5private.h>
|
||||
#include <H5Fprivate.h>
|
||||
#include <H5Gprivate.h>
|
||||
#include <H5MMprivate.h>
|
||||
#include <H5Oprivate.h>
|
||||
#include <H5Vprivate.h>
|
||||
|
||||
#define FILENAME "istore.h5"
|
||||
|
||||
#define AT() printf (" at %s:%d in %s()...\n", \
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: print_array
|
||||
*
|
||||
* Purpose: Prints the values in an array
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Friday, October 10, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
print_array (uint8 *array, size_t nx, size_t ny, size_t nz)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
for (i=0; i<nx; i++) {
|
||||
if (nz>1) {
|
||||
printf ("i=%d:\n", i);
|
||||
} else {
|
||||
printf ("%03d:", i);
|
||||
}
|
||||
|
||||
for (j=0; j<ny; j++) {
|
||||
if (nz>1) printf ("%03d:", j);
|
||||
for (k=0; k<nz; k++) {
|
||||
printf (" %3d", *array++);
|
||||
}
|
||||
if (nz>1) printf ("\n");
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: new_object
|
||||
*
|
||||
* Purpose: Creates a new object that refers to a indexed storage of raw
|
||||
* data. No raw data is stored.
|
||||
*
|
||||
* Return: Success: Handle to a new open object.
|
||||
*
|
||||
* Failure: NULL, error message printed.
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static H5G_entry_t *
|
||||
new_object (H5F_t *f, const char *name, size_t ndims)
|
||||
{
|
||||
H5G_entry_t *handle = NULL;
|
||||
H5O_istore_t istore;
|
||||
intn i;
|
||||
|
||||
/* Create the object symbol table entry and header */
|
||||
if (NULL==(handle=H5G_create (f, name, 64))) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" H5G_create (f, name=\"%s\") = NULL\n", name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add the indexed-storage message */
|
||||
memset (&istore, 0, sizeof istore);
|
||||
istore.ndims = ndims;
|
||||
for (i=0; i<ndims; i++) istore.alignment[i] = 2;
|
||||
|
||||
if (H5O_modify (f, H5O_NO_ADDR, handle, H5O_ISTORE, H5O_NEW_MESG,
|
||||
&istore)<0) {
|
||||
printf ("*FAILED*\n");
|
||||
if (!isatty (1)) {
|
||||
AT();
|
||||
printf (" H5G_modify istore message failure\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_create
|
||||
*
|
||||
* Purpose: Creates a named object that refers to indexed storage of raw
|
||||
* data. No raw data is stored.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
test_create (H5F_t *f, const char *prefix)
|
||||
{
|
||||
H5G_entry_t *handle = NULL;
|
||||
intn i;
|
||||
char name[256];
|
||||
|
||||
printf ("%-70s", "Testing istore create");
|
||||
fflush (stdout);
|
||||
|
||||
for (i=1; i<=H5O_ISTORE_NDIMS; i++) {
|
||||
sprintf (name, "%s_%02d", prefix, i);
|
||||
if (NULL==(handle=new_object (f, name, i))) return FAIL;
|
||||
H5G_close (f, handle);
|
||||
}
|
||||
|
||||
puts (" PASSED");
|
||||
return SUCCEED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: test_extend
|
||||
*
|
||||
* Purpose: Creates an empty object and then writes to it in such a way
|
||||
* as to always extend the object's domain.
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
test_extend (H5F_t *f, const char *prefix,
|
||||
size_t nx, size_t ny, size_t nz)
|
||||
{
|
||||
H5G_entry_t *handle = NULL;
|
||||
int i, j, k, ndims, ctr;
|
||||
uint8 *buf=NULL, *check=NULL, *whole=NULL;
|
||||
char dims[64], s[256], name[256];
|
||||
size_t offset[3];
|
||||
size_t max_corner[3];
|
||||
size_t size[3];
|
||||
size_t whole_size[3];
|
||||
H5O_istore_t istore;
|
||||
|
||||
if (!nz) {
|
||||
if (!ny) {
|
||||
ndims = 1;
|
||||
ny = nz = 1;
|
||||
sprintf (dims, "%d", nx);
|
||||
} else {
|
||||
ndims = 2;
|
||||
nz = 1;
|
||||
sprintf (dims, "%dx%d", nx, ny);
|
||||
}
|
||||
} else {
|
||||
ndims = 3;
|
||||
sprintf (dims, "%dx%dx%d", nx, ny, nz);
|
||||
}
|
||||
|
||||
|
||||
sprintf (s, "Testing istore extend: %s", dims);
|
||||
printf ("%-70s", s);
|
||||
fflush (stdout);
|
||||
buf = H5MM_xmalloc (nx*ny*nz);
|
||||
check = H5MM_xmalloc (nx*ny*nz);
|
||||
whole = H5MM_xcalloc (nx*ny*nz, 1);
|
||||
|
||||
/* Build the new empty object */
|
||||
sprintf (name, "%s_%s", prefix, dims);
|
||||
if (NULL==(handle=new_object (f, name, ndims))) {
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Cannot create %d-d object `%s'\n", ndims, name);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
if (NULL==H5O_read (f, H5O_NO_ADDR, handle, H5O_ISTORE, 0, &istore)) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Unable to read istore message\n");
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
if (ndims!=istore.ndims) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Header read error: istore.ndims != %d\n", ndims);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
whole_size[0] = nx;
|
||||
whole_size[1] = ny;
|
||||
whole_size[2] = nz;
|
||||
max_corner[0] = 0;
|
||||
max_corner[1] = 0;
|
||||
max_corner[2] = 0;
|
||||
|
||||
for (ctr=0; H5V_vector_lt (ndims, max_corner, whole_size); ctr++) {
|
||||
|
||||
/* Size and location */
|
||||
if (0==ctr) {
|
||||
offset[0] = offset[1] = offset[2] = 0;
|
||||
size[0] = size[1] = size[2] = 1;
|
||||
} else {
|
||||
for (i=0; i<ndims; i++) {
|
||||
if (ctr % ndims == i) {
|
||||
offset[i] = max_corner[i];
|
||||
size[i] = 1;
|
||||
if (offset[i]+size[i]>whole_size[i]) continue;
|
||||
} else {
|
||||
offset[i] = 0;
|
||||
size[i] = max_corner[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (0==ctr) printf ("\n");
|
||||
printf (" Insert: ctr=%d, corner=(%d", ctr, offset[0]);
|
||||
if (ndims>1) printf (",%d", offset[1]);
|
||||
if (ndims>2) printf (",%d", offset[2]);
|
||||
printf ("), size=(%d", size[0]);
|
||||
if (ndims>1) printf (",%d", size[1]);
|
||||
if (ndims>2) printf (",%d", size[2]);
|
||||
printf (")\n");
|
||||
#endif
|
||||
|
||||
/* Fill the source array */
|
||||
memset (buf, 128+ctr, size[0]*size[1]*size[2]);
|
||||
|
||||
/* Write to disk */
|
||||
if (H5F_istore_write (f, &istore, offset, size, buf)<0) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Write failed: ctr=%d\n", ctr);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Read from disk */
|
||||
memset (check, 0xff, size[0]*size[1]*size[2]);
|
||||
if (H5F_istore_read (f, &istore, offset, size, check)<0) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Read failed: ctr=%d\n", ctr);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
if (memcmp (buf, check, size[0]*size[1]*size[2])) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Read check failed: ctr=%d\n", ctr);
|
||||
printf (" Wrote:\n");
|
||||
print_array (buf, size[0], size[1], size[2]);
|
||||
printf (" Read:\n");
|
||||
print_array (buf, size[0], size[1], size[2]);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Write to `whole' buffer for later checking */
|
||||
H5V_hyper_copy (ndims, size,
|
||||
whole_size, offset, whole, /*dst*/
|
||||
size, H5V_ZERO, buf); /*src*/
|
||||
|
||||
/* Update max corner */
|
||||
for (i=0; i<ndims; i++) {
|
||||
max_corner[i] = MAX (max_corner[i], offset[i]+size[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the object header */
|
||||
H5O_modify (f, H5O_NO_ADDR, handle, H5O_ISTORE, 0, &istore);
|
||||
|
||||
|
||||
/* Now read the entire array back out and check it */
|
||||
memset (buf, 0xff, nx*ny*nz);
|
||||
if (H5F_istore_read (f, &istore, H5V_ZERO, whole_size, buf)<0) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Read failed for whole array\n");
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
for (i=0; i<nx; i++) {
|
||||
for (j=0; j<ny; j++) {
|
||||
for (k=0; k<nz; k++) {
|
||||
if (whole[i*ny*nz + j*nz + k] != buf[i*ny*nz + j*nz + k]) {
|
||||
puts ("*FAILED*");
|
||||
if (!isatty (1)) {
|
||||
AT ();
|
||||
printf (" Check failed at i=%d", i);
|
||||
if (ndims>1) printf (", j=%d", j);
|
||||
if (ndims>2) printf (", k=%d\n", k);
|
||||
printf (" Check array is:\n");
|
||||
print_array (whole, nx, ny, nz);
|
||||
printf (" Value read is:\n");
|
||||
print_array (buf, nx, ny, nz);
|
||||
}
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
H5G_close (f, handle);
|
||||
puts (" PASSED");
|
||||
H5MM_xfree (buf);
|
||||
H5MM_xfree (check);
|
||||
H5MM_xfree (whole);
|
||||
return SUCCEED;
|
||||
|
||||
error:
|
||||
H5MM_xfree (buf);
|
||||
H5MM_xfree (check);
|
||||
H5MM_xfree (whole);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: main
|
||||
*
|
||||
* Purpose: Tests indexed storage stuff.
|
||||
*
|
||||
* Return: Success: exit(0)
|
||||
*
|
||||
* Failure: exit(non-zero)
|
||||
*
|
||||
* Programmer: Robb Matzke
|
||||
* Wednesday, October 15, 1997
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
H5F_t *f;
|
||||
herr_t status;
|
||||
int nerrors = 0;
|
||||
|
||||
/* Create the test file */
|
||||
if (NULL==(f=H5F_open (FILENAME, H5F_ACC_CREAT|H5F_ACC_WRITE|H5F_ACC_TRUNC,
|
||||
NULL))) {
|
||||
printf ("Cannot create file %s; test aborted\n", FILENAME);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*----------------------
|
||||
* INDEXED STORAGE TESTS
|
||||
*----------------------
|
||||
*/
|
||||
status = test_create (f, "test_create_1");
|
||||
nerrors += status<0 ? 1 : 0;
|
||||
|
||||
status = test_extend (f, "test_extend_1", 10, 0, 0);
|
||||
nerrors += status<0 ? 1 : 0;
|
||||
status = test_extend (f, "test_extend_1", 10, 10, 0);
|
||||
nerrors += status<0 ? 1 : 0;
|
||||
status = test_extend (f, "test_extend_1", 10, 10, 10);
|
||||
nerrors += status<0 ? 1 : 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Close the test file and exit */
|
||||
H5F_close (f);
|
||||
if (nerrors) {
|
||||
printf ("***** %d I-STORE TEST%s FAILED! *****\n",
|
||||
nerrors, 1==nerrors?"":"S");
|
||||
if (isatty (1)) {
|
||||
printf ("(Redirect output to a pager or a file to see "
|
||||
"debug output)\n");
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
|
||||
printf ("All i-store tests passed.\n");
|
||||
exit (0);
|
||||
}
|
12
test/tstab.c
12
test/tstab.c
@ -84,7 +84,7 @@ test_1 (void)
|
||||
*/
|
||||
HDmemset (&dir_ent, 0, sizeof(H5G_entry_t));
|
||||
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
|
||||
status = H5G_find (f, NULL, &dir_ent, "/", &ent1);
|
||||
status = H5G_find (f, "/", &dir_ent, &ent1);
|
||||
CHECK_I (status, "H5G_find");
|
||||
VERIFY (dir_ent.header, 0, "H5G_find");
|
||||
VERIFY (ent1.header, obj1->header, "H5G_find");
|
||||
@ -107,7 +107,7 @@ test_1 (void)
|
||||
|
||||
/* try to read the first object */
|
||||
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
|
||||
status = H5G_find (f, NULL, NULL, "/Root Object", &ent1);
|
||||
status = H5G_find (f, "/Root Object", NULL, &ent1);
|
||||
CHECK_I (status, "H5G_find");
|
||||
VERIFY (ent1.header, obj1->header, "H5G_find");
|
||||
|
||||
@ -151,7 +151,7 @@ test_1 (void)
|
||||
*/
|
||||
HDmemset (&dir_ent, 0, sizeof(H5G_entry_t));
|
||||
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
|
||||
status = H5G_find (f, NULL, &dir_ent, "/", &ent1);
|
||||
status = H5G_find (f, "/", &dir_ent, &ent1);
|
||||
CHECK_I (status, "H5G_find");
|
||||
VERIFY (dir_ent.header, 0, "H5G_find");
|
||||
VERIFY (ent1.header, obj1->header, "H5G_find");
|
||||
@ -163,7 +163,7 @@ test_1 (void)
|
||||
/* now as `/foo' */
|
||||
HDmemset (&dir_ent, 0, sizeof(H5G_entry_t));
|
||||
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
|
||||
status = H5G_find (f, NULL, &dir_ent, "/foo", &ent1);
|
||||
status = H5G_find (f, "/foo", &dir_ent, &ent1);
|
||||
CHECK_I (status, "H5G_find");
|
||||
VERIFY (dir_ent.header, 0, "H5G_find");
|
||||
VERIFY (ent1.header, obj1->header, "H5G_find");
|
||||
@ -185,7 +185,7 @@ test_1 (void)
|
||||
|
||||
/* try to read the first object */
|
||||
HDmemset (&ent1, 0, sizeof(H5G_entry_t));
|
||||
status = H5G_find (f, NULL, NULL, "/foo", &ent1);
|
||||
status = H5G_find (f, "/foo", NULL, &ent1);
|
||||
CHECK_I (status, "H5G_find");
|
||||
VERIFY (ent1.header, obj1->header, "H5G_find");
|
||||
|
||||
@ -243,7 +243,7 @@ test_2 (void)
|
||||
* Create a directory that has so many entries that the root
|
||||
* of the B-tree ends up splitting.
|
||||
*/
|
||||
obj1 = H5G_mkdir (f, "/big", nsyms*12+2);
|
||||
obj1 = H5G_new (f, "/big", nsyms*12+2);
|
||||
CHECK_PTR (obj1, "H5G_mkdir");
|
||||
H5G_close (f, obj1);
|
||||
obj1 = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user