mirror of
https://github.com/HDFGroup/hdf5.git
synced 2024-11-21 01:04:10 +08:00
[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:
parent
833e82fec5
commit
7389762766
1
MANIFEST
1
MANIFEST
@ -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
|
||||
|
@ -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
|
||||
|
54
config/linux
54
config/linux
@ -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
|
||||
|
||||
|
125
src/H5AC.c
125
src/H5AC.c
@ -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);
|
||||
}
|
||||
|
@ -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
334
src/H5B.c
@ -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 */
|
||||
|
@ -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 */
|
||||
|
132
src/H5Distore.c
132
src/H5Distore.c
@ -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 */
|
||||
|
@ -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);
|
||||
|
||||
|
132
src/H5Fistore.c
132
src/H5Fistore.c
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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*/
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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*/
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user