[svn-r135] ./config/linux

./config/freebsd2.2.1
        Rewritten to be more flexible.

./src/H5AC.c
./src/H5ACprivate.h
./src/H5F.c
./src/H5H.c
./src/H5Gpkg.h
./src/H5Gshad.c
./src/H5O.c
./test/istore.c
./test/tstab.c
        Accumulates cache statistics and displays the results on
        stderr when the file is closed if it was opened with
        H5F_ACC_DEBUG passed into H5F_open()

./src/H5B.c
./src/H5Bprivate.h
./src/H5Fistore.c
./src/H5Gnode.c
        Added more debugging which is turned on if H5B_DEBUG is
        defined on the compile command (see config/linux).

        Fixed a couple of bugs with left insertions which are used by
        the indexed storage stuff.

./src/H5Flow.c
        Fixed a memory leak.

./src/H5Fprivate.h
        Fixed warnings about shifting more than size of object.

./src/H5Fstdio.c
        Fixed seek optimizations back to the way Quincey originally
        had them.

./src/H5V.c
        Removed unused variables.
This commit is contained in:
Robb Matzke 1997-11-07 00:16:53 -05:00
parent 833e82fec5
commit 7389762766
22 changed files with 771 additions and 273 deletions

View File

@ -48,6 +48,7 @@
./src/H5Eprivate.h
./src/H5Epublic.h
./src/H5F.c
./src/H5Fcore.c
./src/H5Fistore.c
./src/H5Flow.c
./src/H5Fsec2.c

View File

@ -1,5 +1,51 @@
#!/bin/sh
# Site configuration -- do not distribute this file.
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"
# Based on the setting of environment variable `HDF5_MODE' we set the
# compiler flags unless they're already set. Its value can be one or
# more of the following words:
#
# $warn -- Generates compiler warnings. You should always
# include this since it has no effect on the speed of
# the code produced.
#
# $debug -- Compiles in code to check for invariant conditions
# and turns on the `-g' flag for interactive
# debugging. It also turns off seek optimizations in
# the low-level file driver. This version of the
# library can be significantly slower than a production
# version.
#
# $production -- Compiles an optimized version of the library
# and disables code that checks for invariant
# conditions. It also turns on various optimizations
# such as seek optimizations in the low level file
# driver.
#
# $profile -- Compiles code with the `-pg' flag which
# produces a `gmon.out' file when the library
# runs. The gprof(1) command can read that file
# and produce detailed run-time statistics.
#
# If HDF5_MODE is undefined then we use the value
#
# $debug $warn -DH5F_LOW_DFLT=H5F_LOW_SEC2
#
warn="-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
profile="-pg"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_OPT_SEEK=0 -fverbose-asm"
production="-O3 -DNDEBUG -DH5F_OPT_SEEK=1 -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"
default_mode='$debug $warn -DH5F_LOW_DFLT=H5F_LOW_SEC2'
# Don't set CFLAGS if the user already did.
if test -z "$CFLAGS"; then
CFLAGS="`eval echo ${HDF5_MODE:-$default_mode}`"
export CFLAGS
fi

View File

@ -1,17 +1,51 @@
#!/bin/sh
# 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 -DH5F_LOW_DFLT=H5F_LOW_STDIO -DH5F_OPT_SEEK=1 -fverbose-asm"
CFLAGS_PROFILE="-pg"
CFLAGS_PRODUCTION="-O3 -UH5AC_DEBUG_PROTECT -DNDEBUG -DH5F_LOW_DFLT=H5F_LOW_STDIO -DH5F_OPT_SEEK=1 -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"
# Based on the setting of environment variable `HDF5_MODE' we set the
# compiler flags unless they're already set. Its value can be one or
# more of the following words:
#
# $warn -- Generates compiler warnings. You should always
# include this since it has no effect on the speed of
# the code produced.
#
# $debug -- Compiles in code to check for invariant conditions
# and turns on the `-g' flag for interactive
# debugging. It also turns off seek optimizations in
# the low-level file driver. This version of the
# library can be significantly slower than a production
# version.
#
# $production -- Compiles an optimized version of the library
# and disables code that checks for invariant
# conditions. It also turns on various optimizations
# such as seek optimizations in the low level file
# driver.
#
# $profile -- Compiles code with the `-pg' flag which
# produces a `gmon.out' file when the library
# runs. The gprof(1) command can read that file
# and produce detailed run-time statistics.
#
# If HDF5_MODE is undefined then we use the value
#
# $debug $warn -DH5F_LOW_DFLT=H5F_LOW_SEC2
#
if test "x$CFLAGS" = "x"; then
# Uncomment the following line for a production version of the library.
#CFLAGS="-pipe $CFLAGS_PRODUCTION $CFLAGS_WARN"
warn="-Wall -Wshadow -Wpointer-arith -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs"
# Uncomment the following line for normal development
CFLAGS="-pipe $CFLAGS_DEBUG $CFLAGS_WARN"
profile="-pg"
debug="-g -DH5AC_DEBUG -DH5B_DEBUG -DH5F_OPT_SEEK=0 -fverbose-asm"
production="-O3 -DNDEBUG -DH5F_OPT_SEEK=1 -finline-functions -funroll-loops -malign-double -fomit-frame-pointer"
default_mode='$debug $warn -DH5F_LOW_DFLT=H5F_LOW_SEC2'
# Don't set CFLAGS if the user already did.
if test -z "$CFLAGS"; then
CFLAGS="`eval echo ${HDF5_MODE:-$default_mode}`"
export CFLAGS
fi

View File

@ -36,7 +36,9 @@
* accesses protected objects. NDEBUG must not be defined in order for
* this to have any effect.
*/
/* #define H5AC_DEBUG_PROTECT */
#ifdef NDEBUG
# undef H5AC_DEBUG
#endif
/*
* Private file-scope variables.
@ -120,7 +122,7 @@ H5AC_dest (H5F_t *f)
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
#if defined(H5AC_DEBUG_PROTECT) && !defined(NDEBUG)
#ifdef H5AC_DEBUG
{
intn i;
for (i=0; i<cache->nslots; i++) {
@ -151,7 +153,7 @@ H5AC_dest (H5F_t *f)
* 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
* If H5AC_DEBUG is defined then this function also
* checks that the requested object is not currently
* protected since it is illegal to modify a protected object
* except through the pointer returned by H5AC_protect().
@ -174,11 +176,15 @@ H5AC_dest (H5F_t *f)
* what type of object is at the address and calls this function with
* various type identifiers until one succeeds (cf., the debugger).
*
* Robb Matzke, 30 Oct 1997
* Keeps track of hits, misses, and flushes per object type so we have
* some cache performance diagnostics.
*
*-------------------------------------------------------------------------
*/
void *
H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *udata1, void *udata2)
const void *udata1, void *udata2)
{
unsigned idx;
herr_t status;
@ -202,8 +208,10 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* Return right away if the item is in the cache.
*/
if (slot->type==type && slot->addr==addr) {
cache->diagnostics[type->id].nhits++;
HRETURN (slot->thing);
}
cache->diagnostics[type->id].nmisses++;
/*
* Fail if the item in the cache is at the correct address but is
@ -213,7 +221,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
HRETURN_ERROR (H5E_CACHE, H5E_BADTYPE, NULL);
}
#if defined(H5AC_DEBUG_PROTECT) && !defined(NDEBUG)
#ifdef H5AC_DEBUG
/*
* Check that the requested thing isn't protected, for protected things
* can only be modified through the pointer already handed out by the
@ -251,6 +259,7 @@ H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
}
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, NULL);
}
cache->diagnostics[slot->type->id].nflushes++;
}
/*
@ -396,6 +405,7 @@ H5AC_flush (H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
map = H5MM_xfree (map);
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
cache->diagnostics[slot->type->id].nflushes++;
if (destroy) slot->type = NULL;
}
}
@ -420,6 +430,7 @@ H5AC_flush (H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
if (status<0) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
cache->diagnostics[cache->slot[i].type->id].nflushes++;
if (destroy) cache->slot[i].type = NULL;
}
@ -435,7 +446,7 @@ H5AC_flush (H5F_t *f, const H5AC_class_t *type, haddr_t addr, hbool_t destroy)
* exist on disk yet, but it must have an address and disk
* space reserved.
*
* If H5AC_DEBUG_PROTECT is defined then this function checks
* If H5AC_DEBUG is defined then this function checks
* that the object being inserted isn't a protected object.
*
* Return: Success: SUCCEED
@ -469,9 +480,9 @@ H5AC_set (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
assert (thing);
idx = H5AC_HASH (f, addr);
cache = f->shared->cache;
slot =cache->slot + idx;
slot = cache->slot + idx;
#if defined(H5AC_DEBUG_PROTECT) && !defined(NDEBUG)
#ifdef H5AC_DEBUG
{
intn i;
for (i=0; i<slot->nprots; i++) {
@ -486,11 +497,13 @@ H5AC_set (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
if (status<0) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
cache->diagnostics[slot->type->id].nflushes++;
}
slot->type = type;
slot->addr = addr;
slot->thing = thing;
cache->diagnostics[type->id].ninits++;
FUNC_LEAVE (SUCCEED);
}
@ -502,7 +515,7 @@ H5AC_set (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
* Purpose: Use this function to notify the cache that an object's
* file address changed.
*
* If H5AC_DEBUG_PROTECT is defined then this function checks
* If H5AC_DEBUG is defined then this function checks
* that the old and new addresses don't correspond to the
* address of a protected object.
*
@ -538,7 +551,7 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
new_idx = H5AC_HASH (f, new_addr);
cache = f->shared->cache;
#if defined(H5AC_DEBUG_PROTECT) && !defined(NDEBUG)
#ifdef H5AC_DEBUG
{
int i;
@ -574,6 +587,7 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
if (status<0) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
cache->diagnostics[cache->slot[new_idx].type->id].nflushes++;
}
/*
@ -599,7 +613,7 @@ H5AC_rename (H5F_t *f, const H5AC_class_t *type,
* The caller must call H5AC_unprotect() when finished with
* the pointer.
*
* If H5AC_DEBUG_PROTECT is defined then we check that the
* If H5AC_DEBUG is defined then we check that the
* requested object isn't already protected.
*
* Return: Success: Ptr to the object.
@ -616,12 +630,19 @@ 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 *udata1, void *udata2)
const void *udata1, void *udata2)
{
int idx;
void *thing = NULL;
H5AC_t *cache = NULL;
H5AC_slot_t *slot = NULL;
#ifdef H5AC_DEBUG
static ncalls = 0;
if (0==ncalls++) {
fprintf (stderr, "HDF5-DIAG: debugging cache (expensive)\n");
}
#endif
FUNC_ENTER (H5AC_protect, NULL, NULL);
@ -639,6 +660,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
/*
* The object is already cached; simply remove it from the cache.
*/
cache->diagnostics[slot->type->id].nhits++;
thing = slot->thing;
slot->type = NULL;
slot->addr = 0;
@ -651,7 +673,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
HRETURN_ERROR (H5E_CACHE, H5E_BADTYPE, NULL);
} else {
#if defined(H5AC_DEBUG_PROTECT) && !defined(NDEBUG)
#ifdef H5AC_DEBUG
/*
* Check that the requested thing isn't protected, for protected things
* can only be modified through the pointer already handed out by the
@ -667,12 +689,13 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* Load a new thing. If it can't be loaded, then return an error
* without preempting anything.
*/
cache->diagnostics[type->id].nmisses++;
if (NULL==(thing=(type->load)(f, addr, udata1, udata2))) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTLOAD, NULL);
}
}
#if defined(H5AC_DEBUG_PROTECT) && !defined(NDEBUG)
#ifdef H5AC_DEBUG
/*
* Add the protected object to the protect debugging fields of the
* cache.
@ -701,7 +724,7 @@ H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
* same as the corresponding call to H5AC_protect() and the
* THING argument should be the value returned by H5AC_protect().
*
* If H5AC_DEBUG_PROTECT is defined then this function fails
* If H5AC_DEBUG is defined then this function fails
* if the TYPE and ADDR arguments are not what was used when the
* object was protected or if the object was never protected.
*
@ -750,9 +773,10 @@ H5AC_unprotect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
if (status<0) {
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
cache->diagnostics[slot->type->id].nflushes++;
}
#if defined(H5AC_DEBUG_PROTECT) && !defined(NDEBUG)
#ifdef H5AC_DEBUG
/*
* Remove the object's protect data to indicate that it is no longer
* protected.
@ -782,3 +806,72 @@ H5AC_unprotect (H5F_t *f, const H5AC_class_t *type, haddr_t addr, void *thing)
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5AC_debug
*
* Purpose: Prints debugging info about the cache.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
* Thursday, October 30, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
H5AC_debug (H5F_t *f)
{
H5AC_subid_t i;
char s[32];
H5AC_t *cache = f->shared->cache;
double miss_rate;
FUNC_ENTER (H5AC_debug, NULL, FAIL);
fprintf (stderr, "HDF5-DIAG: cache diagnostics for %s\n", f->name);
fprintf (stderr, " %18s %8s %8s %8s %8s+%-8s\n",
"", "Hits", "Misses", "MissRate", "Inits", "Flushes");
for (i=0; i<H5AC_NTYPES; i++) {
switch (i) {
case H5AC_BT_ID:
strcpy (s, "B-tree nodes");
break;
case H5AC_SNODE_ID:
strcpy (s, "symbol table nodes");
break;
case H5AC_HEAP_ID:
strcpy (s, "heaps");
break;
case H5AC_OHDR_ID:
strcpy (s, "object headers");
break;
default:
sprintf (s, "unknown id %d", i);
}
if (cache->diagnostics[i].nhits) {
miss_rate = 100.0 * cache->diagnostics[i].nmisses /
cache->diagnostics[i].nhits;
} else {
miss_rate = 0.0;
}
fprintf (stderr, " %18s: %8d %8d %7.2f%% %8d%+-9d\n", s,
cache->diagnostics[i].nhits,
cache->diagnostics[i].nmisses,
miss_rate,
cache->diagnostics[i].ninits,
cache->diagnostics[i].nflushes-cache->diagnostics[i].ninits);
}
FUNC_LEAVE (SUCCEED);
}

View File

@ -38,8 +38,18 @@
* function is also responsible for freeing memory allocated
* by the LOAD method if the DEST argument is non-zero.
*/
typedef enum H5AC_subid_t {
H5AC_BT_ID =0, /*B-tree nodes */
H5AC_SNODE_ID =1, /*symbol table nodes */
H5AC_HEAP_ID =2, /*object or name heap */
H5AC_OHDR_ID =3, /*object header */
H5AC_NTYPES =4 /*THIS MUST BE LAST!*/
} H5AC_subid_t;
typedef struct H5AC_class_t {
void *(*load)(H5F_t*, haddr_t addr, void *udata1, void *udata2);
H5AC_subid_t id;
void *(*load)(H5F_t*, haddr_t addr, const void *udata1,
void *udata2);
herr_t (*flush)(H5F_t*, hbool_t dest, haddr_t addr, void *thing);
} H5AC_class_t;
@ -70,17 +80,22 @@ typedef struct H5AC_t {
intn nslots; /*number of cache slots */
H5AC_slot_t *slot; /*the cache slots */
intn nprots; /*number of protected objects */
struct {
uintn nhits; /*number of cache hits */
uintn nmisses; /*number of cache misses */
uintn ninits; /*number of cache initializations */
uintn nflushes; /*number of flushes to disk */
} diagnostics[H5AC_NTYPES]; /*diagnostics for each type of object */
} H5AC_t;
/*
* Library prototypes.
*/
herr_t H5AC_dest (H5F_t *f);
void *H5AC_find_f (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *udata1, void *udata2);
const void *udata1, void *udata2);
void * H5AC_protect (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *udata1, void *udata2);
const 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,
@ -90,11 +105,13 @@ herr_t H5AC_rename (H5F_t *f, const H5AC_class_t *type, haddr_t old,
haddr_t new);
herr_t H5AC_set (H5F_t *f, const H5AC_class_t *type, haddr_t addr,
void *thing);
herr_t H5AC_debug (H5F_t *f);
#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 : \
((F)->shared->cache->diagnostics[(TYPE)->id].nhits++, \
(F)->shared->cache->slot[H5AC_HASH(F,ADDR)].thing) : \
H5AC_find_f (F, TYPE, ADDR, UDATA1, UDATA2))

334
src/H5B.c
View File

@ -94,6 +94,15 @@
#include <H5MFprivate.h> /*File memory management */
#include <H5MMprivate.h> /*Core memory management */
/*
* Define this constant if you want to check B-tree consistency after each
* B-tree operation. Note that this slows down the library considerably!
* Debugging the B-tree depends on assert() being enabled.
*/
#ifdef NDEBUG
# undef H5B_DEBUG
#endif
#define PABLO_MASK H5B_mask
#define BOUND(MIN,X,MAX) ((X)<(MIN)?(MIN):((X)>(MAX)?(MAX):(X)))
@ -108,15 +117,21 @@ static herr_t H5B_insert_child (H5F_t *f, const H5B_class_t *type,
H5B_t *bt, intn idx, haddr_t child,
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 *_type, void *udata);
static H5B_t *H5B_load (H5F_t *f, haddr_t addr, const 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);
#ifdef H5B_DEBUG
static herr_t H5B_assert (H5F_t *f, haddr_t addr, const H5B_class_t *type,
void *udata);
#endif
/* H5B inherits cache-like properties from H5AC */
static const H5AC_class_t H5AC_BT[1] = {{
(void*(*)(H5F_t*,haddr_t,void*,void*))H5B_load,
H5AC_BT_ID,
(void*(*)(H5F_t*,haddr_t,const void*,void*))H5B_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5B_flush,
}};
@ -211,6 +226,9 @@ H5B_new (H5F_t *f, const H5B_class_t *type, void *udata)
HRETURN_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
}
#ifdef H5B_DEBUG
H5B_assert (f, addr, type, udata);
#endif
FUNC_LEAVE (addr);
}
@ -233,9 +251,9 @@ H5B_new (H5F_t *f, const H5B_class_t *type, void *udata)
*-------------------------------------------------------------------------
*/
static H5B_t *
H5B_load (H5F_t *f, haddr_t addr, void *_type, void *udata)
H5B_load (H5F_t *f, haddr_t addr, const void *_type, void *udata)
{
const H5B_class_t *type = (H5B_class_t *)_type;
const H5B_class_t *type = (const H5B_class_t *)_type;
size_t size, total_nkey_size;
H5B_t *bt = NULL;
intn i;
@ -461,7 +479,7 @@ H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
assert (f);
assert (type);
assert (type->decode);
assert (type->cmp);
assert (type->cmp3);
assert (type->found);
assert (addr>=0);
@ -481,8 +499,8 @@ H5B_find (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
}
/* compare */
if ((cmp=(type->cmp)(f, bt->key[idx].nkey, udata,
bt->key[idx+1].nkey))<0) {
if ((cmp=(type->cmp3)(f, bt->key[idx].nkey, udata,
bt->key[idx+1].nkey))<0) {
rt = idx;
} else {
lt = idx+1;
@ -519,12 +537,12 @@ done:
/*-------------------------------------------------------------------------
* Function: H5B_split
*
* Purpose: Split a single node into two nodes. If anchor is
* 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.
* Purpose: Split a single node into two nodes. The old node will
* contain the left children and the new node will contain the
* right children.
*
* 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,11 +561,11 @@ done:
*/
static haddr_t
H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
H5B_ins_t anchor, void *udata)
void *udata)
{
H5B_t *new_bt=NULL, *tmp_bt=NULL;
haddr_t ret_value=FAIL, new_addr=FAIL;
intn i, delta;
intn i, k;
size_t recsize = 0;
FUNC_ENTER (H5B_split, NULL, FAIL);
@ -558,14 +576,13 @@ 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_INS_RIGHT==anchor ? H5B_K(f,type) : 0;
k = H5B_K(f,type);
/*
* Create the new B-tree node.
@ -582,94 +599,47 @@ H5B_split (H5F_t *f, H5B_class_t *type, H5B_t *old_bt, haddr_t old_addr,
* Copy data from the old node to the new node.
*/
HDmemcpy (new_bt->page + H5B_SIZEOF_HDR(f),
old_bt->page + H5B_SIZEOF_HDR(f) + delta*recsize,
H5B_K(f,type) * recsize + new_bt->sizeof_rkey);
old_bt->page + H5B_SIZEOF_HDR(f) + k*recsize,
k*recsize + new_bt->sizeof_rkey);
HDmemcpy (new_bt->native,
old_bt->native + delta * type->sizeof_nkey,
(H5B_K(f,type)+1) * type->sizeof_nkey);
old_bt->native + k*type->sizeof_nkey,
(k+1) * type->sizeof_nkey);
for (i=0; i<=2*H5B_K(f,type); i++) {
for (i=0; i<=k; i++) {
/* key */
if (i<=H5B_K(f,type)) {
new_bt->key[i].dirty = old_bt->key[delta+i].dirty;
if (old_bt->key[delta+i].nkey) {
new_bt->key[i].nkey = new_bt->native + i*type->sizeof_nkey;
}
new_bt->key[i].dirty = old_bt->key[k+i].dirty;
if (old_bt->key[k+i].nkey) {
new_bt->key[i].nkey = new_bt->native + i*type->sizeof_nkey;
}
/* child */
if (i<H5B_K(f,type)) {
new_bt->child[i] = old_bt->child[delta+i];
if (i<k) {
new_bt->child[i] = old_bt->child[k+i];
}
}
new_bt->ndirty = BOUND (0, old_bt->ndirty-delta, H5B_K(f,type));
new_bt->nchildren = H5B_K(f,type);
new_bt->ndirty = new_bt->nchildren = k;
/*
* Truncate the old node.
*/
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);
old_bt->ndirty = old_bt->nchildren = k;
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);
HDmemmove (old_bt->native,
old_bt->native + delta * type->sizeof_nkey,
(H5B_K(f,type)+1) * type->sizeof_nkey);
for (i=0; i<=2*H5B_K(f,type); i++) {
if (i<=H5B_K(f,type)) {
old_bt->key[i].dirty = old_bt->key[delta+i].dirty;
if (old_bt->key[delta+i].nkey) {
old_bt->key[i].nkey = old_bt->native + i * type->sizeof_nkey;
} else {
old_bt->key[i].nkey = NULL;
}
} else {
old_bt->key[i].nkey = NULL;
}
if (i<H5B_K(f,type)) {
old_bt->child[i] = old_bt->child[delta+i];
} else if (i<2*H5B_K(f,type)) {
old_bt->child[i] = 0;
}
}
}
/*
* Update sibling pointers.
*/
if (H5B_INS_RIGHT==anchor) {
new_bt->left = old_addr;
new_bt->right = old_bt->right;
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,
udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
tmp_bt->dirty = TRUE;
tmp_bt->left = new_addr;
if (old_bt->right) {
if (NULL==(tmp_bt=H5AC_find (f, H5AC_BT, old_bt->right, type,
udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
}
old_bt->right = new_addr;
} else {
new_bt->left = old_bt->left;
new_bt->right = old_addr;
if (old_bt->left) {
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;
tmp_bt->right = new_addr;
}
old_bt->left = new_addr;
tmp_bt->dirty = TRUE;
tmp_bt->left = new_addr;
}
old_bt->right = new_addr;
HGOTO_DONE (new_addr);
done:
@ -894,6 +864,9 @@ H5B_insert (H5F_t *f, H5B_class_t *type, haddr_t addr, void *udata)
bt->key[2].nkey = bt->native + 2 * type->sizeof_nkey;
HDmemcpy (bt->key[2].nkey, rt_key, type->sizeof_nkey);
#ifdef H5B_DEBUG
H5B_assert (f, new_root, type, udata);
#endif
FUNC_LEAVE (new_root);
}
@ -964,8 +937,8 @@ H5B_insert_child (H5F_t *f, const H5B_class_t *type, H5B_t *bt,
idx*recsize + bt->sizeof_rkey),
(bt->nchildren-idx) * recsize);
HDmemmove (bt->native + idx + 2,
bt->native + idx + 1,
HDmemmove (bt->native + (idx+2)*type->sizeof_nkey,
bt->native + (idx+1)*type->sizeof_nkey,
(bt->nchildren-idx) * type->sizeof_nkey);
for (i=bt->nchildren; i>idx; --i) {
@ -1047,7 +1020,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
assert (addr>=0);
assert (type);
assert (type->decode);
assert (type->cmp);
assert (type->cmp3);
assert (type->new);
assert (parent_ins && H5B_INS_ERROR==*parent_ins);
assert (lt_key);
@ -1073,8 +1046,8 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
if (H5B_decode_keys (f, bt, idx)<0) {
HRETURN_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
if ((cmp=(type->cmp)(f, bt->key[idx].nkey, udata,
bt->key[idx+1].nkey))<0) {
if ((cmp=(type->cmp3)(f, bt->key[idx].nkey, udata,
bt->key[idx+1].nkey))<0) {
rt = idx;
} else {
lt = idx+1;
@ -1089,7 +1062,7 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
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,
if ((child_addr=(type->new)(f, H5B_INS_FIRST, bt->key[0].nkey, udata,
bt->key[1].nkey))<0) {
bt->key[0].nkey = bt->key[1].nkey = NULL;
HGOTO_ERROR (H5E_BTREE, H5E_CANTINIT, FAIL);
@ -1152,7 +1125,8 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
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);
child_addr = (type->new)(f, H5B_INS_LEFT, bt->key[idx].nkey,
udata, md_key);
*lt_key_changed = TRUE;
} else if (cmp>0 && idx+1>=bt->nchildren && bt->level>0) {
@ -1196,7 +1170,8 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
}
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);
child_addr = (type->new)(f, H5B_INS_RIGHT, md_key,
udata, bt->key[idx+1].nkey);
*rt_key_changed = TRUE;
} else if (cmp) {
@ -1267,35 +1242,31 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
*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.
*/
/* Make sure IDX is the slot number for the new node. */
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, my_ins, udata))<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);
/* If this node is full then split it before inserting the new child. */
if (bt->nchildren==2*H5B_K (f, type)) {
if ((twin_addr=H5B_split (f, type, bt, addr, udata))<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTSPLIT, FAIL);/*can't split node*/
}
if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type,
udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);
if (NULL==(twin=H5AC_protect (f, H5AC_BT, twin_addr, type, udata))) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTLOAD, FAIL);/*can't load B-tree*/
}
if (idx<=H5B_K(f,type)) {
tmp_bt = H5B_INS_RIGHT==my_ins ? bt : twin;
if (idx<=H5B_K (f, type)) {
tmp_bt = bt;
} else {
idx -= H5B_K (f, type);
tmp_bt = H5B_INS_RIGHT==my_ins ? twin : bt;
tmp_bt = twin;
}
} else {
tmp_bt = bt;
}
/* Insert the child */
if (H5B_insert_child (f, type, tmp_bt, idx, child_addr, my_ins,
md_key)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);
HGOTO_ERROR (H5E_BTREE, H5E_CANTINSERT, FAIL);/*can't insert child*/
}
}
@ -1305,18 +1276,24 @@ H5B_insert_helper (H5F_t *f, haddr_t addr, H5B_class_t *type,
* by the left and right node).
*/
if (twin) {
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);
}
HDmemcpy (md_key, twin->key[0].nkey, type->sizeof_nkey);
} else {
if (!bt->key[0].nkey && H5B_decode_key (f, bt, 0)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
HDmemcpy (md_key, bt->key[0].nkey, type->sizeof_nkey);
if (!twin->key[0].nkey && H5B_decode_key (f, twin, 0)<0) {
HGOTO_ERROR (H5E_BTREE, H5E_CANTDECODE, FAIL);
}
HDmemcpy (md_key, twin->key[0].nkey, type->sizeof_nkey);
*parent_ins = H5B_INS_RIGHT;
#ifndef NDEBUG
/*
* The max key in the original left node must be equal to the min key
* in the new node.
*/
if (!bt->key[bt->nchildren].nkey) {
herr_t status = H5B_decode_key (f, bt, bt->nchildren);
assert (status>=0);
cmp = (type->cmp2)(f, bt->key[bt->nchildren].nkey, udata,
twin->key[0].nkey);
assert (0==cmp);
}
#endif
} else {
*parent_ins = H5B_INS_NOOP;
}
@ -1554,3 +1531,120 @@ H5B_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5B_assert
*
* Purpose: Verifies that the tree is structured correctly.
*
* Return: Success: SUCCEED
*
* Failure: aborts if something is wrong.
*
* Programmer: Robb Matzke
* Tuesday, November 4, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
#ifdef H5B_DEBUG
static herr_t
H5B_assert (H5F_t *f, haddr_t addr, const H5B_class_t *type, void *udata)
{
H5B_t *bt = NULL;
intn i, ncell, cmp;
static int ncalls=0;
herr_t status;
/* A queue of child data */
struct child_t {
haddr_t addr;
int level;
struct child_t *next;
} *head=NULL, *tail=NULL, *prev=NULL, *cur=NULL, *tmp=NULL;
FUNC_ENTER (H5B_assert, NULL, FAIL);
if (0==ncalls++) {
fprintf (stderr, "HDF5-DIAG: debugging B-trees (expensive)\n");
}
/* Initialize the queue */
bt = H5AC_find (f, H5AC_BT, addr, type, udata);
assert (bt);
cur = H5MM_xcalloc (1, sizeof(struct child_t));
cur->addr = addr;
cur->level = bt->level;
head = tail = cur;
/*
* Do a breadth-first search of the tree. New nodes are added to the end
* of the queue as the `cur' pointer is advanced toward the end. We don't
* remove any nodes from the queue because we need them in the uniqueness
* test.
*/
for (ncell=0; cur; ncell++) {
bt = H5AC_protect (f, H5AC_BT, cur->addr, type, udata);
assert (bt);
/* Check node header */
assert (bt->ndirty>=0 && bt->ndirty<=bt->nchildren);
assert (bt->level==cur->level);
if (cur->next && cur->next->level==bt->level) {
assert (bt->right==cur->next->addr);
} else {
assert (bt->right==0);
}
if (prev && prev->level==bt->level) {
assert (bt->left==prev->addr);
} else {
assert (bt->left==0);
}
if (cur->level>0) {
for (i=0; i<bt->nchildren; i++) {
/*
* Check that child nodes haven't already been seen. If they
* have then the tree has a cycle.
*/
for (tmp=head; tmp; tmp=tmp->next) {
assert (tmp->addr != bt->child[i]);
}
/* Add the child node to the end of the queue */
tmp = H5MM_xcalloc (1, sizeof(struct child_t));
tmp->addr = bt->child[i];
tmp->level = bt->level - 1;
tail->next = tmp;
tail = tmp;
/* Check that the keys are monotonically increasing */
status = H5B_decode_keys (f, bt, i);
assert (status>=0);
cmp = (type->cmp2)(f, bt->key[i].nkey, udata, bt->key[i+1].nkey);
assert (cmp<0);
}
}
/* Release node */
status = H5AC_unprotect (f, H5AC_BT, cur->addr, bt);
assert (status>=0);
/* Advance current location in queue */
prev = cur;
cur = cur->next;
}
/* Free all entries from queue */
while (head) {
tmp = head->next;
H5MM_xfree (head);
head = tmp;
}
FUNC_LEAVE (SUCCEED);
}
#endif /* H5B_DEBUG */

View File

@ -38,7 +38,8 @@ typedef enum H5B_ins_t {
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_CHANGE =3, /*change child address for cur node */
H5B_INS_FIRST =4 /*insert first node in (sub)tree */
} H5B_ins_t;
typedef enum H5B_subid_t {
@ -59,8 +60,9 @@ 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*,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 */
haddr_t (*new)(H5F_t*,H5B_ins_t,void*,void*,void*); /*new leaf */
intn (*cmp2)(H5F_t*,void*,void*,void*); /*compare 2 keys */
intn (*cmp3)(H5F_t*,void*,void*,void*); /*compare 3 keys */
herr_t (*found)(H5F_t*,haddr_t,const void*,void*,const void*);
haddr_t (*insert)(H5F_t*,haddr_t,H5B_ins_t*,void*,hbool_t*,void*,void*,
void*,hbool_t*); /*insert new data */

View File

@ -29,10 +29,12 @@ 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_node (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 haddr_t H5F_istore_new_node (H5F_t *f, H5B_ins_t, void *_lt_key,
void *_udata, void *_rt_key);
static intn H5F_istore_cmp2 (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static intn H5F_istore_cmp3 (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5F_istore_found (H5F_t *f, 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,
@ -82,7 +84,8 @@ H5B_class_t H5B_ISTORE[1] = {{
sizeof (H5F_istore_key_t), /*sizeof_nkey */
H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
H5F_istore_new_node, /*new */
H5F_istore_cmp, /*cmp */
H5F_istore_cmp2, /*cmp2 */
H5F_istore_cmp3, /*cmp3 */
H5F_istore_found, /*found */
H5F_istore_insert, /*insert */
FALSE, /*follow min branch? */
@ -209,10 +212,51 @@ H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5F_istore_cmp
* Function: H5F_istore_cmp2
*
* Purpose: Compares two keys sort of like strcmp(). The UDATA pointer
* is only to supply extra information not carried in the keys
* (in this case, the dimensionality).
*
* Return: Success: -1 if LT_KEY is less than RT_KEY;
* 1 if LT_KEY is greater than RT_KEY;
* 0 if LT_KEY and RT_KEY are equal.
*
* Failure: FAIL (same as LT_KEY<RT_KEY)
*
* Programmer: Robb Matzke
* Thursday, November 6, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static intn
H5F_istore_cmp2 (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;
intn cmp;
FUNC_ENTER (H5F_istore_cmp2, NULL, FAIL);
assert (lt_key);
assert (rt_key);
assert (udata);
assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
cmp = H5V_vector_cmp (udata->mesg.ndims, lt_key->offset, rt_key->offset);
FUNC_LEAVE (cmp);
}
/*-------------------------------------------------------------------------
* Function: H5F_istore_cmp3
*
* Purpose: Compare the requested datum UDATA with the left and right
* keys of the B-tree.
@ -241,11 +285,14 @@ H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
*-------------------------------------------------------------------------
*/
static intn
H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5F_istore_cmp3 (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;
intn cmp = 0;
FUNC_ENTER (H5F_istore_cmp3, NULL, FAIL);
assert (lt_key);
assert (rt_key);
@ -253,13 +300,13 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
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;
cmp = -1;
} else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
rt_key->offset)) {
return 1;
} else {
return 0;
cmp = 1;
}
FUNC_LEAVE (cmp);
}
@ -283,7 +330,8 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
*-------------------------------------------------------------------------
*/
static haddr_t
H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5F_istore_new_node (H5F_t *f, H5B_ins_t op,
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;
@ -308,16 +356,25 @@ H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
}
/* left key describes the UDATA, right key is a zero-size "edge" */
/* Initialize the key(s) */
for (i=0; i<udata->mesg.ndims; i++) {
/*
* The left key describes the storage of the UDATA chunk being inserted
* into the tree.
*/
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;
}
/*
* The right key might already be present. If not, then add
* a zero-width chunk.
*/
if (H5B_INS_LEFT!=op) {
rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
rt_key->size[i] = 0;
}
}
FUNC_LEAVE (udata->addr);
}
@ -351,7 +408,6 @@ H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_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);
@ -361,7 +417,6 @@ H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
assert (addr>=0);
assert (udata);
assert (lt_key);
assert (rt_key);
/* Initialize return values */
udata->addr = addr;
@ -434,7 +489,7 @@ H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
assert (rt_key);
assert (rt_key_changed);
cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
cmp = H5F_istore_cmp3 (f, lt_key, udata, rt_key);
assert (cmp<=0);
if (cmp<0) {
@ -531,9 +586,8 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
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 offset_wrt_chunk[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;
@ -585,14 +639,25 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
/* Read/Write chunk or create it if it doesn't exist */
udata.mesg.ndims = istore->ndims;
for (i=0; i<istore->ndims; i++) {
/* The location and size of the chunk being accessed */
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];
/* The offset and size wrt the chunk */
offset_wrt_chunk[i] = MAX ((offset_f?offset_f[i]:0),
udata.key.offset[i]) -
udata.key.offset[i];
sub_size[i] = MIN ((idx_cur[i]+1)*istore->alignment[i],
(offset_f?offset_f[i]:0)+size[i]) -
(udata.key.offset[i]+offset_wrt_chunk[i]);
/* Offset into mem buffer */
sub_offset_m[i] = udata.key.offset[i] + offset_wrt_chunk[i] +
(offset_m?offset_m[i]:0) -
(offset_f?offset_f[i]:0);
}
if (H5F_ISTORE_WRITE==op) {
status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
assert (status>=0);
@ -605,10 +670,9 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
* 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) {
!H5V_vector_zerop (istore->ndims, offset_wrt_chunk) ||
!H5V_vector_eq (istore->ndims, sub_size, udata.key.size)) {
if (status>=0 && udata.addr>0) {
if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
}
@ -620,7 +684,7 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
/* 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,
udata.key.size, offset_wrt_chunk, 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);
@ -628,7 +692,7 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
} else {
H5V_hyper_copy (istore->ndims, sub_size,
size_m, sub_offset_m, buf,
udata.key.size, sub_offset_ch, chunk);
udata.key.size, offset_wrt_chunk, chunk);
}
/* Increment indices */

View File

@ -1191,13 +1191,14 @@ H5F_close (H5F_t *f)
herr_t ret_value = FAIL;
FUNC_ENTER (H5F_close, H5F_init_interface, FAIL);
if (-2==(ret_value=H5F_flush (f, TRUE))) {
/*objects are still open, but don't fail yet*/
} else if (ret_value<0) {
/*can't flush cache*/
HRETURN_ERROR (H5E_CACHE, H5E_CANTFLUSH, FAIL);
}
if (f->intent & H5F_ACC_DEBUG) H5AC_debug (f);
H5F_low_close (f->shared->file_handle);
H5F_dest (f);

View File

@ -29,10 +29,12 @@ 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_node (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 haddr_t H5F_istore_new_node (H5F_t *f, H5B_ins_t, void *_lt_key,
void *_udata, void *_rt_key);
static intn H5F_istore_cmp2 (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static intn H5F_istore_cmp3 (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static herr_t H5F_istore_found (H5F_t *f, 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,
@ -82,7 +84,8 @@ H5B_class_t H5B_ISTORE[1] = {{
sizeof (H5F_istore_key_t), /*sizeof_nkey */
H5F_istore_sizeof_rkey, /*get_sizeof_rkey */
H5F_istore_new_node, /*new */
H5F_istore_cmp, /*cmp */
H5F_istore_cmp2, /*cmp2 */
H5F_istore_cmp3, /*cmp3 */
H5F_istore_found, /*found */
H5F_istore_insert, /*insert */
FALSE, /*follow min branch? */
@ -209,10 +212,51 @@ H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
* Function: H5F_istore_cmp
* Function: H5F_istore_cmp2
*
* Purpose: Compares two keys sort of like strcmp(). The UDATA pointer
* is only to supply extra information not carried in the keys
* (in this case, the dimensionality).
*
* Return: Success: -1 if LT_KEY is less than RT_KEY;
* 1 if LT_KEY is greater than RT_KEY;
* 0 if LT_KEY and RT_KEY are equal.
*
* Failure: FAIL (same as LT_KEY<RT_KEY)
*
* Programmer: Robb Matzke
* Thursday, November 6, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static intn
H5F_istore_cmp2 (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;
intn cmp;
FUNC_ENTER (H5F_istore_cmp2, NULL, FAIL);
assert (lt_key);
assert (rt_key);
assert (udata);
assert (udata->mesg.ndims>0 && udata->mesg.ndims<=H5O_ISTORE_NDIMS);
cmp = H5V_vector_cmp (udata->mesg.ndims, lt_key->offset, rt_key->offset);
FUNC_LEAVE (cmp);
}
/*-------------------------------------------------------------------------
* Function: H5F_istore_cmp3
*
* Purpose: Compare the requested datum UDATA with the left and right
* keys of the B-tree.
@ -241,11 +285,14 @@ H5F_istore_encode_key (H5F_t *f, H5B_t *bt, uint8 *raw, void *_key)
*-------------------------------------------------------------------------
*/
static intn
H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5F_istore_cmp3 (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;
intn cmp = 0;
FUNC_ENTER (H5F_istore_cmp3, NULL, FAIL);
assert (lt_key);
assert (rt_key);
@ -253,13 +300,13 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
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;
cmp = -1;
} else if (H5V_vector_ge (udata->mesg.ndims, udata->key.offset,
rt_key->offset)) {
return 1;
} else {
return 0;
cmp = 1;
}
FUNC_LEAVE (cmp);
}
@ -283,7 +330,8 @@ H5F_istore_cmp (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
*-------------------------------------------------------------------------
*/
static haddr_t
H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5F_istore_new_node (H5F_t *f, H5B_ins_t op,
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;
@ -308,16 +356,25 @@ H5F_istore_new_node (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
HRETURN_ERROR (H5E_IO, H5E_CANTINIT, FAIL);
}
/* left key describes the UDATA, right key is a zero-size "edge" */
/* Initialize the key(s) */
for (i=0; i<udata->mesg.ndims; i++) {
/*
* The left key describes the storage of the UDATA chunk being inserted
* into the tree.
*/
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;
}
/*
* The right key might already be present. If not, then add
* a zero-width chunk.
*/
if (H5B_INS_LEFT!=op) {
rt_key->offset[i] = udata->key.offset[i] + udata->key.size[i];
rt_key->size[i] = 0;
}
}
FUNC_LEAVE (udata->addr);
}
@ -351,7 +408,6 @@ H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_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);
@ -361,7 +417,6 @@ H5F_istore_found (H5F_t *f, haddr_t addr, const void *_lt_key,
assert (addr>=0);
assert (udata);
assert (lt_key);
assert (rt_key);
/* Initialize return values */
udata->addr = addr;
@ -434,7 +489,7 @@ H5F_istore_insert (H5F_t *f, haddr_t addr, H5B_ins_t *parent_ins,
assert (rt_key);
assert (rt_key_changed);
cmp = H5F_istore_cmp (f, lt_key, udata, rt_key);
cmp = H5F_istore_cmp3 (f, lt_key, udata, rt_key);
assert (cmp<=0);
if (cmp<0) {
@ -531,9 +586,8 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
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 offset_wrt_chunk[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;
@ -585,14 +639,25 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
/* Read/Write chunk or create it if it doesn't exist */
udata.mesg.ndims = istore->ndims;
for (i=0; i<istore->ndims; i++) {
/* The location and size of the chunk being accessed */
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];
/* The offset and size wrt the chunk */
offset_wrt_chunk[i] = MAX ((offset_f?offset_f[i]:0),
udata.key.offset[i]) -
udata.key.offset[i];
sub_size[i] = MIN ((idx_cur[i]+1)*istore->alignment[i],
(offset_f?offset_f[i]:0)+size[i]) -
(udata.key.offset[i]+offset_wrt_chunk[i]);
/* Offset into mem buffer */
sub_offset_m[i] = udata.key.offset[i] + offset_wrt_chunk[i] +
(offset_m?offset_m[i]:0) -
(offset_f?offset_f[i]:0);
}
if (H5F_ISTORE_WRITE==op) {
status = H5B_insert (f, H5B_ISTORE, istore->btree_addr, &udata);
assert (status>=0);
@ -605,10 +670,9 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
* 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) {
!H5V_vector_zerop (istore->ndims, offset_wrt_chunk) ||
!H5V_vector_eq (istore->ndims, sub_size, udata.key.size)) {
if (status>=0 && udata.addr>0) {
if (H5F_block_read (f, udata.addr, chunk_size, chunk)<0) {
HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
}
@ -620,7 +684,7 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
/* 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,
udata.key.size, offset_wrt_chunk, 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);
@ -628,7 +692,7 @@ H5F_istore_copy_hyperslab (H5F_t *f, const H5O_istore_t *istore, H5F_isop_t op,
} else {
H5V_hyper_copy (istore->ndims, sub_size,
size_m, sub_offset_m, buf,
udata.key.size, sub_offset_ch, chunk);
udata.key.size, offset_wrt_chunk, chunk);
}
/* Increment indices */

View File

@ -108,8 +108,11 @@ H5F_low_close (H5F_low_t *lf)
{
FUNC_ENTER (H5F_low_close, NULL, NULL);
if (lf && (lf->type->close)(lf)<0) {
HRETURN_ERROR (H5E_IO, H5E_CLOSEERROR, NULL); /*close failed*/
if (lf) {
if ((lf->type->close)(lf)<0) {
H5MM_xfree (lf);
HRETURN_ERROR (H5E_IO, H5E_CLOSEERROR, NULL); /*close failed*/
}
H5MM_xfree (lf);
}

View File

@ -51,6 +51,7 @@
#define H5F_ACC_CREAT 0x0002 /* Create non-existing files */
#define H5F_ACC_EXCL 0x0004 /* Fail if file exists */
#define H5F_ACC_TRUNC 0x0008 /* Truncate existing file */
#define H5F_ACC_DEBUG 0x00010 /* Print debug info */
/*
@ -138,22 +139,22 @@
/* WE DON'T CHECK FOR OVERFLOW! */ \
int64 _n = 0; \
intn _i; \
uint8 *_p = (uint8*)(p)+8; \
(p) += 8; \
for (_i=0; _i<sizeof(int64); _i++, _n<<=8) { \
_n |= *(--_p); \
_n |= *(--p); \
} \
(p) = (uint8*)(p)+8; \
(p) += 8; \
}
# define UINT64DECODE(p, n) { \
/* WE DON'T CHECK FOR OVERFLOW! */ \
uint64 _n = 0; \
intn _i; \
uint8 *_p = (uint8*)(p)+8; \
(p) += 8; \
for (_i=0; _i<sizeof(uint64); _i++, _n<<=8) { \
_n |= *(--_p); \
_n |= *(--p); \
} \
(p) = (uint8*)(p)+8; \
(p) += 8; \
}
#else

View File

@ -182,7 +182,7 @@ H5F_stdio_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
* Seek to the correct file position.
*/
if (!H5F_OPT_SEEK ||
lf->u.stdio.op==H5F_OP_UNKNOWN ||
lf->u.stdio.op!=H5F_OP_READ ||
lf->u.stdio.cur!=addr) {
if (fseek (lf->u.stdio.f, addr, SEEK_SET)<0) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*fseek failed*/
@ -237,13 +237,15 @@ H5F_stdio_read (H5F_low_t *lf, haddr_t addr, size_t size, uint8 *buf)
static herr_t
H5F_stdio_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
{
int status;
FUNC_ENTER (H5F_stdio_write, NULL, FAIL);
/*
* Seek to the correct file position.
*/
if (!H5F_OPT_SEEK ||
lf->u.stdio.op==H5F_OP_UNKNOWN ||
lf->u.stdio.op!=H5F_OP_WRITE ||
lf->u.stdio.cur!=addr) {
if (fseek (lf->u.stdio.f, addr, SEEK_SET)<0) {
HRETURN_ERROR (H5E_IO, H5E_SEEKERROR, FAIL); /*fseek failed*/
@ -256,7 +258,8 @@ H5F_stdio_write (H5F_low_t *lf, haddr_t addr, size_t size, const uint8 *buf)
* advanced by the number of bytes read. Otherwise nobody knows where it
* is.
*/
if (size != fwrite (buf, 1, size, lf->u.stdio.f)) {
status = fwrite (buf, 1, size, lf->u.stdio.f);
if (size != status) {
lf->u.stdio.op = H5F_OP_UNKNOWN;
HRETURN_ERROR (H5E_IO, H5E_WRITEERROR, FAIL); /*fwrite failed*/
}

View File

@ -44,14 +44,16 @@ static herr_t H5G_node_decode_key (H5F_t *f, H5B_t *bt, uint8 *raw,
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 haddr_t H5G_node_new (H5F_t *f, H5B_ins_t op, 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 *_udata1,
static H5G_node_t *H5G_node_load (H5F_t *f, haddr_t addr, const void *_udata1,
void *_udata2);
static intn H5G_node_cmp (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static intn H5G_node_cmp2 (H5F_t *f, void *_lt_key, void *_udata,
void *_rt_key);
static intn H5G_node_cmp3 (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);
@ -64,8 +66,9 @@ 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*,void*))H5G_node_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5G_node_flush,
H5AC_SNODE_ID,
(void*(*)(H5F_t*,haddr_t,const void*,void*))H5G_node_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5G_node_flush,
}};
/* H5G inherits B-tree like properties from H5B */
@ -74,7 +77,8 @@ H5B_class_t H5B_SNODE[1] = {{
sizeof (H5G_node_key_t), /*sizeof_nkey */
H5G_node_sizeof_rkey, /*get_sizeof_rkey */
H5G_node_new, /*new */
H5G_node_cmp, /*cmp */
H5G_node_cmp2, /*cmp2 */
H5G_node_cmp3, /*cmp3 */
H5G_node_found, /*found */
H5G_node_insert, /*insert */
TRUE, /*follow min branch? */
@ -227,7 +231,8 @@ H5G_node_size (H5F_t *f)
*-------------------------------------------------------------------------
*/
static haddr_t
H5G_node_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
H5G_node_new (H5F_t *f, H5B_ins_t op,
void *_lt_key, void *_udata, void *_rt_key)
{
H5G_node_key_t *lt_key = (H5G_node_key_t*)_lt_key;
H5G_node_key_t *rt_key = (H5G_node_key_t*)_rt_key;
@ -241,6 +246,7 @@ H5G_node_new (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
* Check arguments.
*/
assert (f);
assert (H5B_INS_FIRST==op);
sym = H5MM_xcalloc (1, sizeof(H5G_node_t));
size = H5G_node_size (f);
@ -383,12 +389,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 *_udata1, void *_udata2)
H5G_node_load (H5F_t *f, haddr_t addr, const 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*)_udata1;
const H5G_ac_ud1_t *ac_udata = (const H5G_ac_ud1_t*)_udata1;
H5G_node_t *ret_value = NULL; /*for error handling*/
FUNC_ENTER (H5G_node_load, NULL, NULL);
@ -457,7 +463,58 @@ H5G_node_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
/*-------------------------------------------------------------------------
* Function: H5G_node_cmp
* Function: H5G_node_cmp2
*
* Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY).
* The UDATA pointer supplies extra data not contained in the
* keys (in this case, the heap address).
*
* Return: Success: negative if LT_KEY is less than RT_KEY.
*
* positive if LT_KEY is greater than RT_KEY.
*
* zero if LT_KEY and RT_KEY are equal.
*
* Failure: FAIL (same as LT_KEY<RT_KEY)
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Jun 23 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static intn
H5G_node_cmp2 (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
{
H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *)_udata;
H5G_node_key_t *lt_key = (H5G_node_key_t *)_lt_key;
H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key;
const char *s1, *s2;
intn cmp;
FUNC_ENTER (H5G_node_cmp2, NULL, FAIL);
assert (udata);
assert (lt_key);
assert (rt_key);
if (NULL==(s1=H5H_peek (f, udata->heap_addr, lt_key->offset))) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
}
if (NULL==(s2=H5H_peek (f, udata->heap_addr, rt_key->offset))) {
HRETURN_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL);
}
cmp = HDstrcmp (s1, s2);
FUNC_LEAVE (cmp);
}
/*-------------------------------------------------------------------------
* Function: H5G_node_cmp3
*
* Purpose: Compares two keys from a B-tree node (LT_KEY and RT_KEY)
* against another key (not necessarily the same type)
@ -484,14 +541,14 @@ 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)
H5G_node_cmp3 (H5F_t *f, void *_lt_key, void *_udata, void *_rt_key)
{
H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *)_udata;
H5G_node_key_t *lt_key = (H5G_node_key_t *)_lt_key;
H5G_node_key_t *rt_key = (H5G_node_key_t *)_rt_key;
const char *s;
FUNC_ENTER (H5G_node_cmp, NULL, FAIL);
FUNC_ENTER (H5G_node_cmp3, NULL, FAIL);
/* left side */
if (NULL==(s=H5H_peek (f, udata->heap_addr, lt_key->offset))) {
@ -747,7 +804,7 @@ H5G_node_insert (H5F_t *f, haddr_t addr, H5B_ins_t *anchor,
*anchor = H5B_INS_RIGHT;
/* The right node */
if ((new_node = H5G_node_new (f, NULL, NULL, NULL))<0) {
if ((new_node = H5G_node_new (f, H5B_INS_FIRST, NULL, NULL, NULL))<0) {
HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL);
}
if (NULL==(snrt=H5AC_find (f, H5AC_SNODE, new_node, &ac_udata, NULL))) {
@ -841,7 +898,8 @@ done:
NULL))) {
HGOTO_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
}
assert (sn==bt_udata->node_ptr);
bt_udata->node_ptr = sn;
bt_udata->entry_ptr = sn->entry + idx;
} else {
/* keep the node protected until we get back to H5G_stab_insert() */
}
@ -991,7 +1049,7 @@ H5G_node_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
* 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, NULL))) {
if (NULL==(sn=H5AC_protect(f, H5AC_SNODE, addr, &ac_udata, NULL))) {
H5ECLEAR; /*discard that error*/
status = H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE, NULL);
if (status<0) HRETURN_ERROR (H5E_SYM, H5E_CANTLOAD, FAIL);
@ -1028,6 +1086,7 @@ H5G_node_debug (H5F_t *f, haddr_t addr, FILE *stream, intn indent,
sn->entry[i].shadow ? "Yes":"No");
}
H5AC_unprotect (f, H5AC_SNODE, addr, sn);
H5AC_flush (f, H5AC_SNODE, addr, TRUE); /*see note above*/
FUNC_LEAVE (SUCCEED);
}

View File

@ -176,7 +176,7 @@ herr_t H5G_shadow_close (H5F_t *f, H5G_entry_t *ent);
hbool_t H5G_shadow_p (H5G_entry_t *ent);
herr_t H5G_shadow_dissociate (H5G_entry_t *ent);
herr_t H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym,
H5G_ac_ud1_t *ac_udata);
const H5G_ac_ud1_t *ac_udata);
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,

View File

@ -299,7 +299,7 @@ H5G_shadow_list (H5F_t *f, haddr_t grp_addr)
*-------------------------------------------------------------------------
*/
herr_t
H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, H5G_ac_ud1_t *ac_udata)
H5G_shadow_assoc_node (H5F_t *f, H5G_node_t *sym, const H5G_ac_ud1_t *ac_udata)
{
H5G_shadow_t *shadow = NULL;
const char *s = NULL;
@ -395,7 +395,21 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *grp, H5G_entry_t *ent)
}
/*
* Build the new shadow.
*/
shadow = H5MM_xcalloc (1, sizeof(H5G_shadow_t));
ent->shadow = shadow;
shadow->main = ent;
shadow->nrefs = 1;
shadow->entry = *ent;
shadow->entry.dirty = FALSE;
shadow->grp_addr = grp_addr;
/*
* Give the shadow a name. Obtaining the name might remove ENT from the
* cache, so we're careful not to reference it again.
*/
if (ent==f->shared->root_sym && 0==grp_addr) {
/*
* We're opening the root entry.
@ -419,16 +433,8 @@ H5G_shadow_open (H5F_t *f, H5G_entry_t *grp, H5G_entry_t *ent)
}
shadow->name = H5MM_xstrdup (s);
}
/*
* Build the new shadow.
*/
ent->shadow = shadow;
shadow->main = ent;
shadow->nrefs = 1;
shadow->entry = *ent;
shadow->entry.dirty = FALSE;
shadow->grp_addr = grp_addr;
ent = NULL; /*previous ops might have invalidated it*/
/*
* Link it into the shadow heap

View File

@ -267,7 +267,7 @@ H5G_stab_insert (H5F_t *f, H5G_entry_t *self, const char *name,
if (H5AC_unprotect (f, H5AC_SNODE, udata.node_addr, udata.node_ptr)<0) {
HRETURN_ERROR (H5E_SYM, H5E_PROTECT, NULL); /*can't unprotect*/
}
/* update the name offset in the entry */
ent->name_off = udata.entry.name_off;
FUNC_LEAVE (udata.entry_ptr);

View File

@ -45,14 +45,16 @@ typedef struct H5H_t {
} H5H_t;
/* PRIVATE PROTOTYPES */
static H5H_t *H5H_load (H5F_t *f, haddr_t addr, void *udata1, void *udata2);
static H5H_t *H5H_load (H5F_t *f, haddr_t addr, const 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*,void*))H5H_load,
H5AC_HEAP_ID,
(void*(*)(H5F_t*,haddr_t,const void*,void*))H5H_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5H_flush,
}};
@ -161,7 +163,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 *udata1, void *udata2)
H5H_load (H5F_t *f, haddr_t addr, const void *udata1, void *udata2)
{
uint8 hdr[20], *p;
H5H_t *heap=NULL;

View File

@ -26,7 +26,8 @@
/* 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 *_udata1, void *_udata2);
static H5O_t *H5O_load (H5F_t *f, haddr_t addr, const 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 +37,8 @@ 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*,void*))H5O_load,
H5AC_OHDR_ID,
(void*(*)(H5F_t*,haddr_t,const void*,void*))H5O_load,
(herr_t(*)(H5F_t*,hbool_t,haddr_t,void*))H5O_flush,
}};
@ -165,7 +167,7 @@ H5O_new (H5F_t *f, intn nlink, size_t size_hint)
*-------------------------------------------------------------------------
*/
static H5O_t *
H5O_load (H5F_t *f, haddr_t addr, void *_udata1, void *_udata2)
H5O_load (H5F_t *f, haddr_t addr, const void *_udata1, void *_udata2)
{
H5O_t *oh = NULL;
H5O_t *ret_value = (void*)1; /*kludge for HGOTO_ERROR*/

View File

@ -298,7 +298,9 @@ H5V_hyper_fill (size_t n, const size_t *_size,
size_t dst_start; /*byte offset to start of stride*/
size_t elmt_size=1; /*bytes per element */
herr_t status; /*function return status */
#ifndef NDEBUG
int i;
#endif
FUNC_ENTER (H5V_hyper_fill, NULL, FAIL);
@ -382,7 +384,9 @@ H5V_hyper_copy (size_t n, const size_t *_size,
size_t dst_start, src_start; /*offset to start at */
size_t elmt_size=1; /*element size in bytes */
herr_t status; /*return status */
#ifndef NDEBUG
intn i;
#endif
FUNC_ENTER (H5V_hyper_copy, NULL, FAIL);

View File

@ -527,7 +527,8 @@ main (int argc, char *argv[])
/* Create the test file */
if (NULL==(f=H5F_open (H5F_LOW_DFLT, FILENAME,
H5F_ACC_CREAT|H5F_ACC_WRITE|H5F_ACC_TRUNC,
(H5F_ACC_CREAT|H5F_ACC_WRITE|H5F_ACC_TRUNC|
H5F_ACC_DEBUG),
NULL))) {
printf ("Cannot create file %s; test aborted\n", FILENAME);
exit (1);

View File

@ -238,6 +238,7 @@ test_2 (void)
CHECK (fid, FAIL, "H5Fcreate");
f = H5Aatom_object (fid);
CHECK (f, NULL, "H5Aatom_object");
f->intent |= H5F_ACC_DEBUG;
/*
* Create a directory that has so many entries that the root