summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5AC.c15
-rw-r--r--src/H5B.c78
-rw-r--r--src/H5Bprivate.h18
-rw-r--r--src/H5F.c98
-rw-r--r--src/H5Fprivate.h2
-rw-r--r--src/H5G.c4
-rw-r--r--src/H5Gnode.c106
-rw-r--r--src/H5Gprivate.h11
-rw-r--r--src/H5H.c170
-rw-r--r--src/H5Hprivate.h5
-rw-r--r--src/H5Tproto.h3
-rw-r--r--src/Makefile8
-rw-r--r--src/debug.c142
13 files changed, 609 insertions, 51 deletions
diff --git a/src/H5AC.c b/src/H5AC.c
index cca36bc..140a52d 100644
--- a/src/H5AC.c
+++ b/src/H5AC.c
@@ -96,6 +96,12 @@ H5AC_dest (hdf5_file_t *f)
*
* Modifications:
*
+ * Robb Matzke, 4 Aug 1997
+ * Fails immediately if the cached object is at the correct address
+ * but is of the wrong type. This happens if the caller doesn't know
+ * what type of object is at the address and calls this function with
+ * various type identifiers until one succeeds (cf., the debugger).
+ *
*-------------------------------------------------------------------------
*/
void *
@@ -119,6 +125,15 @@ H5AC_find (hdf5_file_t *f, const H5AC_class_t *type, haddr_t addr,
}
/*
+ * Fail if the item in the cache is at the correct address but is
+ * of the wrong type.
+ */
+ if (f->cache[idx].type && f->cache[idx].addr==addr &&
+ f->cache[idx].type!=type) {
+ return NULL;
+ }
+
+ /*
* Load a new thing. If it can't be loaded, then return an error
* without preempting anything.
*/
diff --git a/src/H5B.c b/src/H5B.c
index fadc6f5..89316b2 100644
--- a/src/H5B.c
+++ b/src/H5B.c
@@ -181,7 +181,7 @@ H5B_new (hdf5_file_t *f, const H5B_class_t *type, size_t sizeof_rkey)
* `page' buffer. Each native key pointer should be null until the key is
* translated to native format.
*/
- for (i=0,offset=H5B_HDR_SIZE(f);
+ for (i=0,offset=H5B_SIZEOF_HDR(f);
i<2*type->k;
i++,offset+=bt->sizeof_rkey+H5F_SIZEOF_OFFSET(f)) {
@@ -249,7 +249,7 @@ H5B_load (hdf5_file_t *f, haddr_t addr, const void *_data)
p = bt->page;
/* magic number */
- if (memcmp (p, H5B_MAGIC, 4)) goto error;
+ if (memcmp (p, H5B_MAGIC, H5B_SIZEOF_MAGIC)) goto error;
p += 4;
/* node type and level */
@@ -326,7 +326,7 @@ H5B_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5B_t *bt)
if (bt->dirty) {
/* magic number */
- memcpy (p, H5B_MAGIC, 4);
+ memcpy (p, H5B_MAGIC, H5B_SIZEOF_MAGIC);
p += 4;
/* node type and level */
@@ -513,14 +513,14 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
/*
* Copy data into the new node from the old node.
*/
- memcpy (bt->page + H5B_HDR_SIZE(f),
- old->page + H5B_HDR_SIZE(f) + delta*recsize,
+ memcpy (bt->page + H5B_SIZEOF_HDR(f),
+ old->page + H5B_SIZEOF_HDR(f) + delta*recsize,
type->k * recsize);
memcpy (bt->native,
old->native + delta * type->sizeof_nkey,
(type->k+1) * type->sizeof_nkey);
- for (i=0,offset=H5B_HDR_SIZE(f); i<=2*type->k; i++,offset+=recsize) {
+ for (i=0,offset=H5B_SIZEOF_HDR(f); i<=2*type->k; i++,offset+=recsize) {
/* key */
if (i<=type->k) {
@@ -555,8 +555,8 @@ H5B_split (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr, intn anchor)
old->nchildren = type->k;
if (H5B_ANCHOR_RT==anchor) {
- memcpy (old->page + H5B_HDR_SIZE(f),
- old->page + H5B_HDR_SIZE(f) + delta*recsize,
+ memcpy (old->page + H5B_SIZEOF_HDR(f),
+ old->page + H5B_SIZEOF_HDR(f) + delta*recsize,
type->k * recsize);
memmove (old->native,
old->native + delta * type->sizeof_nkey,
@@ -803,8 +803,8 @@ H5B_insert_child (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr,
/*
* The MD_KEY is the left key of the new node.
*/
- memmove (bt->page + H5B_HDR_SIZE(f) + (idx+1)*recsize,
- bt->page + H5B_HDR_SIZE(f) + idx*recsize,
+ memmove (bt->page + H5B_SIZEOF_HDR(f) + (idx+1)*recsize,
+ bt->page + H5B_SIZEOF_HDR(f) + idx*recsize,
(bt->nchildren-idx)*recsize + bt->sizeof_rkey);
memmove (bt->native + (idx+1) * type->sizeof_nkey,
@@ -822,9 +822,9 @@ H5B_insert_child (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr,
/*
* The MD_KEY is the right key of the new node.
*/
- memmove (bt->page + (H5B_HDR_SIZE(f) +
+ memmove (bt->page + (H5B_SIZEOF_HDR(f) +
(idx+1)*recsize + bt->sizeof_rkey),
- bt->page + (H5B_HDR_SIZE(f) +
+ bt->page + (H5B_SIZEOF_HDR(f) +
idx*recsize + bt->sizeof_rkey),
(bt->nchildren-idx) * recsize);
@@ -1170,8 +1170,60 @@ H5B_nodesize (hdf5_file_t *f, const H5B_class_t *type,
*total_nkey_size = (2 * type->k + 1) * type->sizeof_nkey;
}
- return (H5B_HDR_SIZE(f) + /*node header */
+ return (H5B_SIZEOF_HDR(f) + /*node header */
2 * type->k * H5F_SIZEOF_OFFSET(f) + /*child pointers*/
(2*type->k+1) * sizeof_rkey); /*keys */
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5B_debug
+ *
+ * Purpose: Prints debugging info about a B-tree.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 4 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5B_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth, const H5B_class_t *type)
+{
+ H5B_t *bt = H5AC_find (f, H5AC_BT, addr, type);
+
+ if (!bt) return -1;
+
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Tree type ID:",
+ (int)(bt->type->id));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Size of raw (disk) key:",
+ (unsigned long)(bt->sizeof_rkey));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Dirty flag:",
+ (int)(bt->dirty));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Number of initial dirty children:",
+ (int)(bt->ndirty));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Level:",
+ (int)(bt->level));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Address of left sibling:",
+ (unsigned long)(bt->left));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Address of right sibling:",
+ (unsigned long)(bt->right));
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Number of children:",
+ (int)(bt->nchildren));
+ return 0;
+}
diff --git a/src/H5Bprivate.h b/src/H5Bprivate.h
index 3a029e4..bb9d95c 100644
--- a/src/H5Bprivate.h
+++ b/src/H5Bprivate.h
@@ -21,11 +21,20 @@
#include "H5Fprivate.h"
-#define H5B_MAGIC "TREE" /* tree node magic number */
-#define H5B_HDR_SIZE(F) (8+2*H5F_SIZEOF_OFFSET(F))
+#define H5B_MAGIC "TREE" /*tree node magic number */
+#define H5B_SIZEOF_MAGIC 4 /*size of magic number */
+
+#define H5B_SIZEOF_HDR(F) \
+ (H5B_SIZEOF_MAGIC + /*magic number */ \
+ 4 + /*type, level, num entries */ \
+ 2*H5F_SIZEOF_OFFSET(F)) /*left and right sibling addresses */
#define H5B_ANCHOR_LT 0 /* left node is anchored, right is new */
#define H5B_ANCHOR_RT 1 /* right node is anchored, left is new */
+
+typedef enum H5B_subid_t {
+ H5B_SUBTYPE_SNODE =0 /*B-tree is for symbol table nodes */
+} H5B_subid_t;
/*
@@ -33,7 +42,7 @@
* variable of this type that contains class variables and methods.
*/
typedef struct H5B_class_t {
- intn id; /*id as found in file */
+ H5B_subid_t id; /*id as found in file */
intn k; /* max children is 2k */
size_t sizeof_nkey; /*size of native (memory) key */
size_t (*get_sizeof_rkey)(hdf5_file_t*);
@@ -75,7 +84,8 @@ typedef struct H5B_t {
/*
* Library prototypes.
*/
-herr_t H5B_debug (hdf5_file_t *f, haddr_t addr, const H5B_class_t *type);
+herr_t H5B_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth, const H5B_class_t *type);
haddr_t H5B_new (hdf5_file_t *f, const H5B_class_t *type, size_t sizeof_rkey);
herr_t H5B_find (hdf5_file_t *f, const H5B_class_t *type, haddr_t addr,
void *udata);
diff --git a/src/H5F.c b/src/H5F.c
index 7a43ca9..8e37967 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -584,6 +584,7 @@ hatom_t H5Fopen(const char *filename, uintn flags, hatom_t access_temp)
haddr_t curr_off=0; /* The current offset to check in the file */
size_t file_len=0; /* The length of the file we are checking */
hatom_t ret_value = FAIL;
+ size_t variable_size; /*size of the variable part of the bb */
FUNC_ENTER(H5F_mask, ID_H5Fopen, H5F_init_interface, FAIL);
@@ -670,9 +671,9 @@ hatom_t H5Fopen(const char *filename, uintn flags, hatom_t access_temp)
/* Read in the fixed-size part of the boot-block */
if(H5F_READ(new_file->file_handle,temp_buf,16)==FAIL)
- HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL);
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL);
- /* Decode the boot block */
+ /* Decode fixed-size part of the boot block */
p=temp_buf;
new_file->file_create_parms.bootblock_ver=*p++; /* Decode Boot-block version # */
new_file->file_create_parms.smallobject_ver=*p++; /* Decode Small-Object Heap version # */
@@ -684,6 +685,17 @@ hatom_t H5Fopen(const char *filename, uintn flags, hatom_t access_temp)
p++; /* Decode the reserved byte :-) */
UINT32DECODE(p,new_file->file_create_parms.btree_page_size); /* Decode the B-Tree page size */
UINT32DECODE(p,new_file->consist_flags); /* Decode File-Consistancy flags */
+
+ /* Read the variable-size part of the boot-block */
+ variable_size = H5F_SIZEOF_OFFSET(new_file) + /*offset of global small-object heap*/
+ H5F_SIZEOF_OFFSET(new_file) + /*offset of global free list*/
+ H5F_SIZEOF_SIZE(new_file) + /*logical size of HDF5 file*/
+ H5G_SIZEOF_ENTRY(new_file); /*root symbol table entry*/
+ if (H5F_READ(new_file->file_handle, temp_buf, variable_size)<0)
+ HGOTO_ERROR (H5E_IO, H5E_READERROR, FAIL);
+
+ /* Decode the variable-size part of the boot block */
+ p = temp_buf;
H5F_decode_offset(new_file,p,new_file->smallobj_off); /* Decode offset of global small-object heap */
H5F_decode_offset(new_file,p,new_file->freespace_off); /* Decode offset of global free-space heap */
H5F_decode_length(new_file,p,new_file->logical_len); /* Decode logical length of file */
@@ -846,3 +858,85 @@ H5F_block_write (hdf5_file_t *f, haddr_t addr, size_t size, void *buf)
PABLO_TRACE_OFF(H5F_mask, ID_H5F_block_write);
return SUCCEED;
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5F_debug
+ *
+ * Purpose: Prints a file header to the specified stream. Each line
+ * is indented and the field name occupies the specified width
+ * number of characters.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 1 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5F_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth)
+{
+ fprintf (stream, "%*sFile Boot Block...\n", indent, "");
+
+ fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Directory:",
+ f->dir);
+ fprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "File name:",
+ f->filename);
+ fprintf (stream, "%*s%-*s 0x%08x\n", indent, "", fwidth,
+ "Permissions",
+ (unsigned)(f->acc_perm));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Reference count:",
+ (unsigned)(f->ref_count));
+ fprintf (stream, "%*s%-*s 0x%08lx\n", indent, "", fwidth,
+ "Consistency flags:",
+ (unsigned long)(f->consist_flags));
+ fprintf (stream, "%*s%-*s %ld\n", indent, "", fwidth,
+ "Small object heap address:",
+ (long)(f->smallobj_off));
+ fprintf (stream, "%*s%-*s %ld\n", indent, "", fwidth,
+ "Free list address:",
+ (long)(f->freespace_off));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Logical file length:",
+ (unsigned long)(f->logical_len));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Size of user block:",
+ (unsigned long)(f->file_create_parms.userblock_size));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Size of file size_t type:",
+ (unsigned)(f->file_create_parms.offset_size));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Size of file off_t type:",
+ (unsigned)(f->file_create_parms.length_size));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Bytes per B-tree page:",
+ (unsigned)(f->file_create_parms.btree_page_size));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Boot block version number:",
+ (unsigned)(f->file_create_parms.bootblock_ver));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Small object heap version number:",
+ (unsigned)(f->file_create_parms.smallobject_ver));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Free list version number:",
+ (unsigned)(f->file_create_parms.freespace_ver));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Object directory version number:",
+ (unsigned)(f->file_create_parms.objectdir_ver));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Shared header version number:",
+ (unsigned)(f->file_create_parms.sharedheader_ver));
+
+
+ return 0;
+}
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 2856b6a..fde8fb3 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -92,6 +92,8 @@ void H5F_encode_offset_unusual(const hdf5_file_t *f, uint8 **p, uint8 *o);
intn H5F_compare_filename(const VOIDP obj, const VOIDP key);
herr_t H5F_block_read (hdf5_file_t *f, haddr_t addr, size_t size, void *buf);
herr_t H5F_block_write (hdf5_file_t *f, haddr_t addr, size_t size, void *buf);
+herr_t H5F_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth);
#endif /* HDF5FILE_H */
diff --git a/src/H5G.c b/src/H5G.c
index 3c1f21a..fa7da12 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -347,7 +347,7 @@ H5G_decode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
abort();
}
- *pp = p_ret + 2*H5F_SIZEOF_OFFSET(f) + 4 + 24;
+ *pp = p_ret + H5G_SIZEOF_ENTRY(f);
return 0;
}
@@ -433,7 +433,7 @@ H5G_encode (hdf5_file_t *f, uint8 **pp, H5G_entry_t *ent)
abort();
}
- *pp = p_ret + 2*H5F_SIZEOF_OFFSET(f) + 4 + 24;
+ *pp = p_ret + H5G_SIZEOF_ENTRY(f);
return 0;
}
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 52638eb..3ce046e 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -60,7 +60,7 @@ static const H5AC_class_t H5AC_SNODE[1] = {{
/* H5G inherits B-tree like properties from H5B */
const H5B_class_t H5B_SNODE[1] = {{
- 0, /*id */
+ H5B_SUBTYPE_SNODE, /*id */
64, /*k */
sizeof (H5G_node_key_t), /*sizeof_nkey */
H5G_node_sizeof_rkey, /*get_sizeof_rkey */
@@ -167,7 +167,8 @@ H5G_node_encode_key (hdf5_file_t *f, uint8 *raw, void *_key)
static size_t
H5G_node_size (hdf5_file_t *f)
{
- return H5G_HDR_SIZE(f) + (2*H5G_NODE_K) * (2*H5F_SIZEOF_OFFSET(f));
+ return H5G_NODE_SIZEOF_HDR(f) +
+ (2*H5G_NODE_K) * H5G_SIZEOF_ENTRY(f);
}
@@ -244,7 +245,7 @@ H5G_node_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5G_node_t *sym)
buf = p = H5MM_xmalloc (size);
/* magic number */
- HDmemcpy (p, H5G_NODE_MAGIC, 4);
+ HDmemcpy (p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC);
p += 4;
/* version number */
@@ -303,7 +304,7 @@ H5G_node_load (hdf5_file_t *f, haddr_t addr, const void *_udata)
H5F_block_read (f, addr, size, buf);
/* magic */
- if (HDmemcmp (p, H5G_NODE_MAGIC, 4)) goto error;
+ if (HDmemcmp (p, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC)) goto error;
p += 4;
/* version */
@@ -693,3 +694,100 @@ H5G_node_list (hdf5_file_t *f, haddr_t addr, void *_udata)
return 0;
}
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_node_debug
+ *
+ * Purpose: Prints debugging information about a symbol table node
+ * or a B-tree node for a symbol table B-tree.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 4 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth)
+{
+ int i, j;
+ char buf[64];
+ H5G_node_t *sn = H5AC_find (f, H5AC_SNODE, addr, NULL);
+
+ /*
+ * If we couldn't load the symbol table node, then try loading the
+ * B-tree node.
+ */
+ if (!sn) {
+ return H5B_debug (f, addr, stream, indent, fwidth, H5B_SNODE);
+ }
+
+
+ if (!sn) return -1;
+ fprintf (stream, "%*sSymbol Table Node...\n", indent, "");
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Dirty:",
+ sn->dirty);
+ fprintf (stream, "%*s%-*s %d of %d\n", indent, "", fwidth,
+ "Number of Symbols:",
+ sn->nsyms, 2*H5G_NODE_K);
+
+ indent += 3;
+ fwidth = MAX (0, fwidth-3);
+ for (i=0; i<sn->nsyms; i++) {
+ fprintf (stream, "%*sSymbol %d:\n", indent-3, "", i);
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Name offset into private heap:",
+ (unsigned long)(sn->entry[i].name_off));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Object header address:",
+ (unsigned long)(sn->entry[i].header));
+
+ fprintf (stream, "%*s%-*s ", indent, "", fwidth,
+ "Symbol type:");
+ switch (sn->entry[i].type) {
+ case H5G_NOTHING_CACHED:
+ fprintf (stream, "Nothing Cached\n");
+ break;
+
+ case H5G_CACHED_SDATA:
+ fprintf (stream, "S-data\n");
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Number type:",
+ (unsigned)(sn->entry[i].cache.sdata.nt));
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Dimensionality:",
+ (unsigned)(sn->entry[i].cache.sdata.ndim));
+ for (j=0; j<sn->entry[i].cache.sdata.ndim && j<4; j++) {
+ sprintf (buf, "Dimension %d", j);
+ fprintf (stream, "%*s%-*s %u\n", indent, "", fwidth,
+ buf,
+ (unsigned)(sn->entry[i].cache.sdata.dim[j]));
+ }
+ break;
+
+ case H5G_CACHED_SYMTAB:
+ fprintf (stream, "Symbol Table\n");
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "B-tree address:",
+ (unsigned long)(sn->entry[i].cache.symtab.btree));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Heap address:",
+ (unsigned long)(sn->entry[i].cache.symtab.heap));
+ break;
+
+ default:
+ fprintf (stream, "*** Unknown symbol type %d\n", sn->entry[i].type);
+ break;
+ }
+ }
+ return 0;
+}
+
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 73a06ee..5e08c4d 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -25,9 +25,16 @@
#include "H5Fprivate.h"
#define H5G_NODE_MAGIC "SNOD" /*symbol table node magic number */
+#define H5G_NODE_SIZEOF_MAGIC 4 /*sizeof symbol node magic number */
#define H5G_NODE_VERS 1 /*symbol table node version number */
#define H5G_NODE_K 64 /*min degree. max degree is twice this */
-#define H5G_HDR_SIZE(F) 8
+#define H5G_NODE_SIZEOF_HDR(F) (H5G_NODE_SIZEOF_MAGIC + 4)
+#define H5G_SIZEOF_ENTRY(F) \
+ (H5F_SIZEOF_OFFSET(F) + /*offset of name into heap */ \
+ H5F_SIZEOF_OFFSET(F) + /*address of object header */ \
+ 4 + /*entry type */ \
+ 24) /*scratch pad space */
+
/*
* Various types of object header information can be cached in a symbol
@@ -126,6 +133,8 @@ extern const H5B_class_t H5B_SNODE[1];
/*
* Library prototypes...
*/
+herr_t H5G_node_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth);
haddr_t H5G_new (hdf5_file_t *f, size_t init);
haddr_t H5G_find (hdf5_file_t *f, haddr_t addr, const char *name,
H5G_entry_t *entry);
diff --git a/src/H5H.c b/src/H5H.c
index 9805bbd..11ed3b2 100644
--- a/src/H5H.c
+++ b/src/H5H.c
@@ -22,10 +22,17 @@
#include "H5MFprivate.h" /*file memory management */
#include "H5MMprivate.h" /*core memory management */
-#define H5H_MAGIC "HEAP" /*heap magic number */
#define H5H_FREE_NULL 1 /*end of free list on disk */
-#define H5H_HDR_SIZE(F) (4+H5F_SIZEOF_SIZE(F)+2*H5F_SIZEOF_OFFSET(F))
-#define H5H_SIZEOF_FREE(F) (H5F_SIZEOF_SIZE(F)+H5F_SIZEOF_OFFSET(F))
+
+#define H5H_SIZEOF_HDR(F) \
+ (H5H_SIZEOF_MAGIC + /*heap signature */ \
+ H5F_SIZEOF_SIZE (F) + /*data size */ \
+ H5F_SIZEOF_OFFSET (F) + /*free list head */ \
+ H5F_SIZEOF_OFFSET (F)) /*data address */
+
+#define H5H_SIZEOF_FREE(F) \
+ (H5F_SIZEOF_OFFSET (F) + /*ptr to next free block */ \
+ H5F_SIZEOF_SIZE (F)) /*size of this free block */
typedef struct H5H_free_t {
off_t offset; /*offset of free block */
@@ -92,15 +99,15 @@ H5H_new (hdf5_file_t *f, size_t size_hint)
}
/* allocate file version */
- total_size = H5H_HDR_SIZE(f) + size_hint;
+ total_size = H5H_SIZEOF_HDR(f) + size_hint;
if ((addr = H5MF_alloc (f, total_size))<0) return -1;
/* allocate memory version */
heap = H5MM_xcalloc (1, sizeof(H5H_t));
- heap->addr = addr + H5H_HDR_SIZE(f);
+ heap->addr = addr + H5H_SIZEOF_HDR(f);
heap->disk_alloc = size_hint;
heap->mem_alloc = size_hint;
- heap->chunk = H5MM_xmalloc (H5H_HDR_SIZE(f) + size_hint);
+ heap->chunk = H5MM_xmalloc (H5H_SIZEOF_HDR(f) + size_hint);
/* free list */
if (size_hint) {
@@ -146,15 +153,15 @@ H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata)
haddr_t free_block;
assert (addr>0);
- assert (H5H_HDR_SIZE(f) <= sizeof hdr);
+ assert (H5H_SIZEOF_HDR(f) <= sizeof hdr);
assert (!udata);
- if (H5F_block_read (f, addr, H5H_HDR_SIZE(f), hdr)<0) goto error;
+ if (H5F_block_read (f, addr, H5H_SIZEOF_HDR(f), hdr)<0) goto error;
p = hdr;
/* magic number */
- if (HDmemcmp (hdr, H5H_MAGIC, 4)) goto error;
- p += 4;
+ if (HDmemcmp (hdr, H5H_MAGIC, H5H_SIZEOF_MAGIC)) goto error;
+ p += H5H_SIZEOF_MAGIC;
/* heap data size */
H5F_decode_length (f, p, heap->disk_alloc);
@@ -166,10 +173,10 @@ H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata)
/* data */
H5F_decode_offset (f, p, heap->addr);
- heap->chunk = H5MM_xmalloc (H5H_HDR_SIZE(f) + heap->mem_alloc);
+ heap->chunk = H5MM_xmalloc (H5H_SIZEOF_HDR(f) + heap->mem_alloc);
if (heap->disk_alloc &&
H5F_block_read (f, heap->addr, heap->disk_alloc,
- heap->chunk + H5H_HDR_SIZE(f))<0) {
+ heap->chunk + H5H_SIZEOF_HDR(f))<0) {
goto error;
}
@@ -184,7 +191,7 @@ H5H_load (hdf5_file_t *f, haddr_t addr, const void *udata)
tail = fl;
if (!heap->freelist) heap->freelist = fl;
- p = heap->chunk + H5H_HDR_SIZE(f) + free_block;
+ p = heap->chunk + H5H_SIZEOF_HDR(f) + free_block;
H5F_decode_offset (f, p, free_block);
H5F_decode_length (f, p, fl->size);
@@ -241,7 +248,7 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
/*
* Write the header.
*/
- HDmemcpy (p, H5H_MAGIC, 4); p += 4;
+ HDmemcpy (p, H5H_MAGIC, H5H_SIZEOF_MAGIC); p += H5H_SIZEOF_MAGIC;
H5F_encode_length (f, p, heap->mem_alloc);
H5F_encode_offset (f, p, fl?fl->offset:-1);
H5F_encode_offset (f, p, heap->addr);
@@ -250,7 +257,7 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
* Write the free list.
*/
while (fl) {
- p = heap->chunk + H5H_HDR_SIZE(f) + fl->offset;
+ p = heap->chunk + H5H_SIZEOF_HDR(f) + fl->offset;
if (fl->next) {
H5F_encode_offset (f, p, fl->next->offset);
} else {
@@ -263,17 +270,17 @@ H5H_flush (hdf5_file_t *f, hbool_t destroy, haddr_t addr, H5H_t *heap)
/*
* Copy buffer to disk.
*/
- if (heap->addr == addr + H5H_HDR_SIZE(f)) {
- if (H5F_block_write (f, addr, H5H_HDR_SIZE(f)+heap->disk_alloc,
+ if (heap->addr == addr + H5H_SIZEOF_HDR(f)) {
+ if (H5F_block_write (f, addr, H5H_SIZEOF_HDR(f)+heap->disk_alloc,
heap->chunk)<0) {
return -1;
}
} else {
- if (H5F_block_write (f, addr, H5H_HDR_SIZE(f), heap->chunk)<0) {
+ if (H5F_block_write (f, addr, H5H_SIZEOF_HDR(f), heap->chunk)<0) {
return -1;
}
if (H5F_block_write (f, heap->addr, heap->disk_alloc,
- heap->chunk + H5H_HDR_SIZE(f))<0) {
+ heap->chunk + H5H_SIZEOF_HDR(f))<0) {
return -1;
}
}
@@ -333,7 +340,7 @@ H5H_read (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size, void *buf)
assert (offset+size<=heap->mem_alloc);
if (!buf) buf = H5MM_xmalloc (size);
- HDmemcpy (buf, heap->chunk+H5H_HDR_SIZE(f)+offset, size);
+ HDmemcpy (buf, heap->chunk+H5H_SIZEOF_HDR(f)+offset, size);
return buf;
}
@@ -374,7 +381,7 @@ H5H_peek (hdf5_file_t *f, haddr_t addr, off_t offset)
H5H_t *heap = H5AC_find (f, H5AC_HEAP, addr, NULL);
assert (offset>=0 && offset<heap->mem_alloc);
- return heap->chunk+H5H_HDR_SIZE(f)+offset;
+ return heap->chunk+H5H_SIZEOF_HDR(f)+offset;
}
@@ -502,13 +509,13 @@ H5H_insert (hdf5_file_t *f, haddr_t addr, size_t size, const void *buf)
(unsigned long)(heap->mem_alloc + need_more));
heap->mem_alloc += need_more;
heap->chunk = H5MM_xrealloc (heap->chunk,
- H5H_HDR_SIZE(f)+heap->mem_alloc);
+ H5H_SIZEOF_HDR(f)+heap->mem_alloc);
}
/*
* Copy the data into the heap
*/
- HDmemcpy (heap->chunk + H5H_HDR_SIZE(f) + offset, buf, size);
+ HDmemcpy (heap->chunk + H5H_SIZEOF_HDR(f) + offset, buf, size);
return offset;
}
@@ -547,7 +554,7 @@ H5H_write (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size,
assert (buf);
heap->dirty += 1;
- HDmemcpy (heap->chunk+H5H_HDR_SIZE(f)+offset, buf, size);
+ HDmemcpy (heap->chunk+H5H_SIZEOF_HDR(f)+offset, buf, size);
return 0;
}
@@ -651,3 +658,118 @@ H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size)
return 0;
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5H_debug
+ *
+ * Purpose: Prints debugging information about a heap.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Aug 1 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5H_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth)
+{
+ H5H_t *h = H5AC_find (f, H5AC_HEAP, addr, NULL);
+ int i, j, overlap;
+ uint8 c;
+ H5H_free_t *freelist=NULL;
+ uint8 *marker = NULL;
+ size_t amount_free = 0;
+
+ if (!h) return -1;
+
+ fprintf (stream, "%*sHeap...\n", indent, "");
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Dirty:",
+ (int)(h->dirty));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Data bytes allocated on disk:",
+ (unsigned long)(h->disk_alloc));
+ fprintf (stream, "%*s%-*s %lu\n", indent, "", fwidth,
+ "Data bytes allocated in core:",
+ (unsigned long)(h->mem_alloc));
+
+
+ /*
+ * Traverse the free list and check that all free blocks fall within
+ * the heap and that no two free blocks point to the same region of
+ * the heap.
+ */
+ marker = H5MM_xcalloc (h->mem_alloc, 1);
+ for (freelist=h->freelist; freelist; freelist=freelist->next) {
+ fprintf (stream, "%*s%-*s %8lu, %8lu\n", indent, "", fwidth,
+ "Free Block (offset,size):",
+ (unsigned long)(freelist->offset),
+ (unsigned long)(freelist->size));
+ if (freelist->offset + freelist->size > h->mem_alloc) {
+ fprintf (stream, "***THAT FREE BLOCK IS OUT OF BOUNDS!\n");
+ } else {
+ for (i=overlap=0; i<freelist->size; i++) {
+ if (marker[freelist->offset+i]) overlap++;
+ marker[freelist->offset+i] = 1;
+ }
+ if (overlap) {
+ fprintf (stream,"***THAT FREE BLOCK OVERLAPPED A PREVIOUS ONE!\n");
+ } else {
+ amount_free += freelist->size;
+ }
+ }
+ }
+
+ if (h->mem_alloc) {
+ fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Percent of heap used:",
+ 100 * (h->mem_alloc - amount_free) / h->mem_alloc);
+ }
+
+ /*
+ * Print the data in a VMS-style octal dump.
+ */
+ fprintf (stream, "%*sData follows (`__' indicates free region)...\n",
+ indent, "");
+ for (i=0; i<h->disk_alloc; i+=16) {
+ fprintf (stream, "%*s %8d: ", indent, "", i);
+ for (j=0; j<16; j++) {
+ if (i+j<h->disk_alloc) {
+ if (marker[i+j]) {
+ fprintf (stream, "__ ");
+ } else {
+ c = h->chunk[H5H_SIZEOF_HDR(f)+i+j];
+ fprintf (stream, "%02x ", c);
+ }
+ } else {
+ fprintf (stream, " ");
+ }
+ if (7==j) fputc (' ', stream);
+ }
+
+ for (j=0; j<16; j++) {
+ if (i+j<h->disk_alloc) {
+ if (marker[i+j]) {
+ fputc (' ', stream);
+ } else {
+ c = h->chunk[H5H_SIZEOF_HDR(f)+i+j];
+ if (c>' ' && c<'~') fputc (c, stream);
+ else fputc ('.', stream);
+ }
+ }
+ }
+
+ fputc ('\n', stream);
+ }
+
+ H5MM_xfree (marker);
+ return 0;
+}
diff --git a/src/H5Hprivate.h b/src/H5Hprivate.h
index f896b4a..0c31df3 100644
--- a/src/H5Hprivate.h
+++ b/src/H5Hprivate.h
@@ -20,6 +20,9 @@
#include "H5Hproto.h"
#include "H5Fprivate.h"
+#define H5H_MAGIC "HEAP" /*heap magic number */
+#define H5H_SIZEOF_MAGIC 4
+
/*
* Library prototypes...
*/
@@ -31,6 +34,8 @@ off_t H5H_insert (hdf5_file_t *f, haddr_t addr, size_t size, const void *buf);
herr_t H5H_write (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size,
const void *buf);
herr_t H5H_remove (hdf5_file_t *f, haddr_t addr, off_t offset, size_t size);
+herr_t H5H_debug (hdf5_file_t *f, haddr_t addr, FILE *stream, intn indent,
+ intn fwidth);
#endif
diff --git a/src/H5Tproto.h b/src/H5Tproto.h
index 5e32b0f..908445e 100644
--- a/src/H5Tproto.h
+++ b/src/H5Tproto.h
@@ -48,6 +48,9 @@ hbool_t H5Tis_atomic(hatom_t tid);
herr_t H5Tset_type(hatom_t tid,hatom_t base,uint8 len,uint8 arch);
uintn H5Tsize(hatom_t tid, uint8 len, uint8 arch, hbool_t mem_flag);
herr_t H5T_release(hatom_t oid);
+herr_t H5Tadd_field (hatom_t tid, const char *name, hatom_t base, uint8 len,
+ uint8 arch, hatom_t space);
+herr_t H5Tget_fields(hatom_t tid, hatom_t *field_list);
#if defined c_plusplus || defined __cplusplus
}
diff --git a/src/Makefile b/src/Makefile
index 13eeea4..022f392 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -34,7 +34,7 @@ $(TARGET): $(OBJ)
$(AR) $(ARFLAGS) $(TARGET) $(OBJ)
$(RANLIB) $(TARGET)
-all test: $(TARGET)
+all test: $(TARGET) debug_hdf5
debug: $(OBJ)
$(AR) $(ARFLAGS) $(TARGET) $(OBJ)
@@ -46,6 +46,12 @@ clean:
###########################################################################
+debug_hdf5: $(TARGET) debug.o
+ $(CC) -o debug debug.o -L. -lhdf5
+
+debug.o: debug.c $(INCL)
+ $(CC) $(CFLAGS) debug.c
+
H5.o: H5.c $(INCL) H5private.h H5proto.h
$(CC) $(CFLAGS) H5.c
diff --git a/src/debug.c b/src/debug.c
new file mode 100644
index 0000000..f061d4c
--- /dev/null
+++ b/src/debug.c
@@ -0,0 +1,142 @@
+/*-------------------------------------------------------------------------
+ * Copyright (C) 1997 National Center for Supercomputing Applications.
+ * All rights reserved.
+ *
+ *-------------------------------------------------------------------------
+ *
+ * Created: debug.c
+ * Jul 18 1997
+ * Robb Matzke <robb@maya.nuance.com>
+ *
+ * Purpose: Debugs an existing HDF5 file at a low level.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#include "hdf5.h"
+
+#include "H5private.h"
+#include "H5Bprivate.h"
+#include "H5Fprivate.h"
+#include "H5Gprivate.h"
+#include "H5Hprivate.h"
+
+#define INDENT 3
+#define VCOL 50
+
+
+/*-------------------------------------------------------------------------
+ * Function: main
+ *
+ * Usage: debug FILENAME [OFFSET]
+ *
+ * Return: Success: exit (0)
+ *
+ * Failure: exit (non-zero)
+ *
+ * Programmer: Robb Matzke
+ * robb@maya.nuance.com
+ * Jul 18 1997
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+main (int argc, char *argv[])
+{
+ hatom_t fid;
+ hdf5_file_t *f;
+ haddr_t addr = 0;
+ uint8 sig[16];
+ intn i;
+
+ /*
+ * Parse command arguments.
+ */
+ if (argc>2) {
+ printf ("New address: %s\n", argv[2]);
+ addr = strtol (argv[2], NULL, 0);
+ }
+
+ /*
+ * Open the file and get the file descriptor.
+ */
+ if ((fid = H5Fopen (argv[1], 0, 0))<0) {
+ fprintf (stderr, "cannot open file\n");
+ exit (1);
+ }
+ if (NULL==(f=H5Aatom_object (fid))) {
+ fprintf (stderr, "cannot obtain hdf5_file_t pointer\n");
+ exit (2);
+ }
+
+ /*
+ * Read the signature at the specified file position.
+ */
+ printf ("Reading signature at byte %lu\n", (unsigned long)addr);
+ if (H5F_block_read (f, addr, sizeof(sig), sig)<0) {
+ fprintf (stderr, "cannot read signature\n");
+ exit (3);
+ }
+
+ if (!memcmp (sig, HDF5_FILE_SIGNATURE, HDF5_FILE_SIGNATURE_LEN)) {
+ /*
+ * Debug the boot block.
+ */
+ H5F_debug (f, 0, stdout, 0, VCOL);
+
+ } else if (!memcmp (sig, H5H_MAGIC, H5H_SIZEOF_MAGIC)) {
+ /*
+ * Debug a heap.
+ */
+ H5H_debug (f, addr, stdout, 0, VCOL);
+
+ } else if (!memcmp (sig, H5G_NODE_MAGIC, H5G_NODE_SIZEOF_MAGIC)) {
+ /*
+ * Debug a symbol table node.
+ */
+ H5G_node_debug (f, addr, stdout, 0, VCOL);
+
+ } else if (!memcmp (sig, H5B_MAGIC, H5B_SIZEOF_MAGIC)) {
+ /*
+ * Debug a B-tree. B-trees are debugged through the B-tree
+ * subclass. The subclass identifier is the byte immediately
+ * after the B-tree signature.
+ */
+ H5B_subid_t subtype = sig[H5B_SIZEOF_MAGIC];
+ switch (subtype) {
+ case H5B_SUBTYPE_SNODE:
+ H5G_node_debug (f, addr, stdout, 0, VCOL);
+ break;
+
+ default:
+ fprintf (stderr, "Unknown B-tree subtype %u\n", (unsigned)(subtype));
+ exit (4);
+ }
+
+ } else {
+ /*
+ * Got some other unrecognized signature.
+ */
+ printf ("%-*s ", VCOL, "Signature:");
+ for (i=0; i<8; i++) {
+ if (sig[i]>' ' && sig[i]<='~' && '\\'!=sig[i]) {
+ putchar (sig[i]);
+ } else if ('\\'==sig[i]) {
+ putchar ('\\');
+ putchar ('\\');
+ } else {
+ printf ("\\%03o", sig[i]);
+ }
+ }
+ putchar ('\n');
+
+ fprintf (stderr, "unknown signature\n");
+ exit (4);
+ }
+
+ H5Fclose (fid);
+ exit (0);
+}