mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-02-17 16:10:24 +08:00
[svn-r11297] Purpose:
Code cleanup & speedup Description: Refactor h5dump & related code to be considerably cleaner & faster for files with large #'s of objects. Platforms tested: FreeBS 4.11 (sleipnir) Linux 2.4
This commit is contained in:
parent
ab6656c52c
commit
a4329aaa47
@ -296,6 +296,8 @@ New Features
|
||||
|
||||
Tools:
|
||||
------
|
||||
- Sped up h5dump on files with large numbers of objects.
|
||||
QAK - 2005/08/25
|
||||
- Added a standalone mode for building h5perf. AKC - 2005/08/12
|
||||
- new tool, h5jam. See reference manual. 2004/10/08
|
||||
- h5repack.sh did not report errors encountered during tests. It does
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -78,7 +78,6 @@ static herr_t list (hid_t group, const char *name, void *cd);
|
||||
static void display_type(hid_t type, int ind);
|
||||
static char *fix_name(const char *path, const char *base);
|
||||
|
||||
hid_t thefile;
|
||||
const char *progname="h5ls";
|
||||
int d_status;
|
||||
|
||||
@ -1823,10 +1822,10 @@ list (hid_t group, const char *name, void *_iter)
|
||||
/* Show detailed information about the object, beginning with information
|
||||
* which is common to all objects. */
|
||||
if (verbose_g>0 && H5G_LINK!=sb.type) {
|
||||
if (sb.type>=0) H5Aiterate(obj, NULL, list_attr, NULL);
|
||||
printf(" %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:",
|
||||
sb.fileno, sb.objno);
|
||||
printf(" %-10s %u\n", "Links:", sb.nlink);
|
||||
if (sb.type>=0)
|
||||
H5Aiterate(obj, NULL, list_attr, NULL);
|
||||
printf(" %-10s %lu:"H5_PRINTF_HADDR_FMT"\n", "Location:", sb.fileno, sb.objno);
|
||||
printf(" %-10s %u\n", "Links:", sb.nlink);
|
||||
if (sb.mtime>0) {
|
||||
if (simple_output_g) tm=gmtime(&(sb.mtime));
|
||||
else tm=localtime(&(sb.mtime));
|
||||
|
@ -24,9 +24,9 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "h5tools.h"
|
||||
#include "h5tools_ref.h"
|
||||
#include "h5tools_str.h"
|
||||
#include "h5tools_utils.h"
|
||||
#include "hdf5.h"
|
||||
#include "H5private.h"
|
||||
|
||||
/*
|
||||
@ -139,6 +139,9 @@ h5tools_close(void)
|
||||
rawdatastream = NULL;
|
||||
}
|
||||
|
||||
/* Clean up the reference path table, if it's been used */
|
||||
term_ref_path_table();
|
||||
|
||||
/* Shut down the library */
|
||||
H5close();
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <stdlib.h>
|
||||
#include "h5tools_ref.h"
|
||||
#include "H5private.h"
|
||||
#include "H5SLprivate.h"
|
||||
#include "h5tools.h"
|
||||
#include "h5tools_utils.h"
|
||||
|
||||
@ -34,15 +35,107 @@
|
||||
* method of selecting which one.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
haddr_t objno; /* Object ID (i.e. address) */
|
||||
const char *path; /* Object path */
|
||||
} ref_path_node_t;
|
||||
|
||||
static H5SL_t *ref_path_table = NULL; /* the "table" (implemented with a skip list) */
|
||||
static hid_t thefile;
|
||||
|
||||
extern hid_t thefile;
|
||||
size_t prefix_len = 1024;
|
||||
char *prefix;
|
||||
extern char *progname;
|
||||
extern int d_status;
|
||||
|
||||
static int ref_path_table_put(const char *, haddr_t objno);
|
||||
static hbool_t ref_path_table_find(haddr_t objno);
|
||||
|
||||
ref_path_table_entry_t *ref_path_table = NULL; /* the table */
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: init_ref_path_table
|
||||
*
|
||||
* Purpose: Enter the root group ("/") into the path table
|
||||
*
|
||||
* Return: Non-negative on success, negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
init_ref_path_table(hid_t fid)
|
||||
{
|
||||
H5G_stat_t sb;
|
||||
char *root_path;
|
||||
|
||||
/* Set file ID for later queries (XXX: this should be fixed) */
|
||||
thefile = fid;
|
||||
|
||||
/* Create skip list to store reference path information */
|
||||
if((ref_path_table = H5SL_create(H5SL_TYPE_HADDR, 0.5, (size_t)16))==NULL)
|
||||
return (-1);
|
||||
|
||||
if((root_path = HDstrdup("/")) == NULL)
|
||||
return (-1);
|
||||
|
||||
if(H5Gget_objinfo(fid, "/", TRUE, &sb)<0) {
|
||||
/* fatal error? */
|
||||
HDfree(root_path);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Insert into table (takes ownership of path) */
|
||||
ref_path_table_put(root_path, sb.objno);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: free_ref_path_info
|
||||
*
|
||||
* Purpose: Free the key for a reference path table node
|
||||
*
|
||||
* Return: Non-negative on success, negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
free_ref_path_info(void *item, void UNUSED *key, void UNUSED *operator_data/*in,out*/)
|
||||
{
|
||||
ref_path_node_t *node = (ref_path_node_t *)item;
|
||||
|
||||
HDfree(node->path);
|
||||
HDfree(node);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: term_ref_path_table
|
||||
*
|
||||
* Purpose: Terminate the reference path table
|
||||
*
|
||||
* Return: Non-negative on success, negative on failure
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
term_ref_path_table(void)
|
||||
{
|
||||
/* Destroy reference path table, freeing all memory */
|
||||
if(ref_path_table)
|
||||
H5SL_destroy(ref_path_table, free_ref_path_info, NULL);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: ref_path_table_lookup
|
||||
@ -59,34 +152,60 @@ ref_path_table_entry_t *ref_path_table = NULL; /* the table */
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
ref_path_table_entry_t *
|
||||
haddr_t
|
||||
ref_path_table_lookup(const char *thepath)
|
||||
{
|
||||
H5G_stat_t sb;
|
||||
ref_path_table_entry_t *pte = ref_path_table;
|
||||
H5G_stat_t sb;
|
||||
haddr_t ret_value;
|
||||
|
||||
/* Get object ID for object at path */
|
||||
if(H5Gget_objinfo(thefile, thepath, TRUE, &sb)<0)
|
||||
/* fatal error ? */
|
||||
return NULL;
|
||||
return HADDR_UNDEF;
|
||||
|
||||
while(pte!=NULL) {
|
||||
if (sb.objno==pte->statbuf.objno)
|
||||
return pte;
|
||||
pte = pte->next;
|
||||
}
|
||||
/* Return OID or HADDR_UNDEF */
|
||||
ret_value = ref_path_table_find(sb.objno) ? sb.objno : HADDR_UNDEF;
|
||||
|
||||
return NULL;
|
||||
return(ret_value);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: ref_path_table_find
|
||||
*
|
||||
* Purpose: Looks up a table entry given a object number.
|
||||
* Used during construction of the table.
|
||||
*
|
||||
* Return: TRUE/FALSE on success, can't fail
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static hbool_t
|
||||
ref_path_table_find(haddr_t objno)
|
||||
{
|
||||
HDassert(ref_path_table);
|
||||
|
||||
if(H5SL_search(ref_path_table, &objno) == NULL)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: ref_path_table_put
|
||||
*
|
||||
* Purpose: Enter the 'obj' with 'path' in the table if
|
||||
* not already there.
|
||||
* Purpose: Enter the 'obj' with 'path' in the table (assumes its not
|
||||
* already there)
|
||||
*
|
||||
* Create an object reference, pte, and store them
|
||||
* in the table.
|
||||
*
|
||||
* Return: The object reference for the object.
|
||||
* NOTE: Takes ownership of the path name string passed in!
|
||||
*
|
||||
* Return: Non-negative on success, negative on failure
|
||||
*
|
||||
* Programmer: REMcG
|
||||
*
|
||||
@ -94,37 +213,21 @@ ref_path_table_lookup(const char *thepath)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
ref_path_table_entry_t *
|
||||
ref_path_table_put(hid_t obj, const char *path)
|
||||
static int
|
||||
ref_path_table_put(const char *path, haddr_t objno)
|
||||
{
|
||||
ref_path_table_entry_t *pte;
|
||||
ref_path_node_t *new_node;
|
||||
|
||||
/* look up 'obj'. If already in table, return */
|
||||
pte = ref_path_table_lookup(path);
|
||||
if (pte != NULL)
|
||||
return pte;
|
||||
HDassert(ref_path_table);
|
||||
HDassert(path);
|
||||
|
||||
/* if not found, then make new entry */
|
||||
if((new_node = HDmalloc(sizeof(ref_path_node_t))) == NULL)
|
||||
return(-1);
|
||||
|
||||
pte = (ref_path_table_entry_t *) malloc(sizeof(ref_path_table_entry_t));
|
||||
if (pte == NULL)
|
||||
/* fatal error? */
|
||||
return NULL;
|
||||
new_node->objno = objno;
|
||||
new_node->path = path;
|
||||
|
||||
pte->obj = obj;
|
||||
|
||||
pte->apath = HDstrdup(path);
|
||||
|
||||
if(H5Gget_objinfo(thefile, path, TRUE, &pte->statbuf)<0) {
|
||||
/* fatal error? */
|
||||
free(pte);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pte->next = ref_path_table;
|
||||
ref_path_table = pte;
|
||||
|
||||
return pte;
|
||||
return(H5SL_insert(ref_path_table, new_node, &(new_node->objno)));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -133,7 +236,7 @@ ref_path_table_put(hid_t obj, const char *path)
|
||||
int xid = 1;
|
||||
|
||||
int get_next_xid() {
|
||||
return xid++;
|
||||
return xid++;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -145,42 +248,33 @@ int get_next_xid() {
|
||||
haddr_t fake_xid = HADDR_MAX;
|
||||
haddr_t
|
||||
get_fake_xid () {
|
||||
return (fake_xid--);
|
||||
return (fake_xid--);
|
||||
}
|
||||
|
||||
/*
|
||||
* for an object that does not have an object id (e.g., soft link),
|
||||
* create a table entry with a fake object id as the key.
|
||||
*
|
||||
* Assumes 'path' is for an object that is not in the table.
|
||||
*
|
||||
*/
|
||||
|
||||
ref_path_table_entry_t *
|
||||
haddr_t
|
||||
ref_path_table_gen_fake(const char *path)
|
||||
{
|
||||
ref_path_table_entry_t *pte;
|
||||
const char *dup_path;
|
||||
haddr_t fake_objno;
|
||||
|
||||
/* look up 'obj'. If already in table, return */
|
||||
pte = ref_path_table_lookup(path);
|
||||
if (pte != NULL)
|
||||
return pte;
|
||||
if((dup_path = HDstrdup(path)) == NULL)
|
||||
return HADDR_UNDEF;
|
||||
|
||||
/* if not found, then make new entry */
|
||||
/* Generate fake ID for string */
|
||||
fake_objno = get_fake_xid();
|
||||
|
||||
pte = (ref_path_table_entry_t *) malloc(sizeof(ref_path_table_entry_t));
|
||||
if (pte == NULL)
|
||||
/* fatal error? */
|
||||
return NULL;
|
||||
/* Insert "fake" object into table (takes ownership of path) */
|
||||
ref_path_table_put(dup_path, fake_objno);
|
||||
|
||||
pte->obj = (hid_t)-1;
|
||||
|
||||
memset(&pte->statbuf,0,sizeof(H5G_stat_t));
|
||||
pte->statbuf.objno = get_fake_xid();
|
||||
|
||||
pte->apath = HDstrdup(path);
|
||||
|
||||
pte->next = ref_path_table;
|
||||
ref_path_table = pte;
|
||||
|
||||
return pte;
|
||||
return(fake_objno);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -196,17 +290,18 @@ ref_path_table_gen_fake(const char *path)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
char *
|
||||
lookup_ref_path(hobj_ref_t ref)
|
||||
const char *
|
||||
lookup_ref_path(haddr_t ref)
|
||||
{
|
||||
ref_path_table_entry_t *pte = ref_path_table;
|
||||
ref_path_node_t *node;
|
||||
|
||||
while(pte!=NULL) {
|
||||
if (ref==pte->statbuf.objno)
|
||||
return pte->apath;
|
||||
pte = pte->next;
|
||||
}
|
||||
return NULL;
|
||||
/* Be safer for h5ls */
|
||||
if(!ref_path_table)
|
||||
return(NULL);
|
||||
|
||||
node = H5SL_search(ref_path_table, &ref);
|
||||
|
||||
return(node ? node->path : NULL);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -224,84 +319,44 @@ lookup_ref_path(hobj_ref_t ref)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
fill_ref_path_table(hid_t group, const char *name, void UNUSED * op_data)
|
||||
fill_ref_path_table(hid_t group, const char *obj_name, void *op_data)
|
||||
{
|
||||
hid_t obj;
|
||||
char *tmp;
|
||||
size_t tmp_len;
|
||||
const char *obj_prefix = (const char *)op_data;
|
||||
H5G_stat_t statbuf;
|
||||
ref_path_table_entry_t *pte;
|
||||
char *thepath;
|
||||
|
||||
H5Gget_objinfo(group, name, FALSE, &statbuf);
|
||||
tmp_len = strlen(prefix) + strlen(name) + 2;
|
||||
tmp = (char *) malloc(tmp_len);
|
||||
H5Gget_objinfo(group, obj_name, FALSE, &statbuf);
|
||||
|
||||
if (tmp == NULL)
|
||||
return FAIL;
|
||||
/* Check if the object is in the path table */
|
||||
if (!ref_path_table_find(statbuf.objno)) {
|
||||
size_t tmp_len;
|
||||
char *thepath;
|
||||
|
||||
thepath = (char *) malloc(tmp_len);
|
||||
/* Compute length for this object's path */
|
||||
tmp_len = HDstrlen(obj_prefix) + HDstrlen(obj_name) + 2;
|
||||
|
||||
if (thepath == NULL) {
|
||||
free(tmp);
|
||||
return FAIL;
|
||||
}
|
||||
/* Allocate room for the path for this object */
|
||||
if ((thepath = (char *) HDmalloc(tmp_len)) == NULL)
|
||||
return FAIL;
|
||||
|
||||
strcpy(tmp, prefix);
|
||||
/* Build the name for this object */
|
||||
HDstrcpy(thepath, obj_prefix);
|
||||
HDstrcat(thepath, "/");
|
||||
HDstrcat(thepath, obj_name);
|
||||
|
||||
strcpy(thepath, prefix);
|
||||
strcat(thepath, "/");
|
||||
strcat(thepath, name);
|
||||
/* Insert the object into the path table */
|
||||
ref_path_table_put(thepath, statbuf.objno);
|
||||
|
||||
switch (statbuf.type) {
|
||||
case H5G_DATASET:
|
||||
if ((obj = H5Dopen(group, name)) >= 0) {
|
||||
pte = ref_path_table_lookup(thepath);
|
||||
if (pte == NULL)
|
||||
ref_path_table_put(obj, thepath);
|
||||
H5Dclose(obj);
|
||||
} else {
|
||||
error_msg(progname, "unable to get dataset \"%s\"\n", name);
|
||||
d_status = EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case H5G_GROUP:
|
||||
if ((obj = H5Gopen(group, name)) >= 0) {
|
||||
if (prefix_len <= tmp_len) {
|
||||
prefix_len = tmp_len + 1;
|
||||
prefix = realloc(prefix, prefix_len);
|
||||
if(statbuf.type == H5G_GROUP) {
|
||||
/* Iterate over objects in this group, using this group's
|
||||
* name as their prefix
|
||||
*/
|
||||
if(H5Giterate(group, obj_name, NULL, fill_ref_path_table, thepath) < 0) {
|
||||
error_msg(progname, "unable to dump group \"%s\"\n", obj_name);
|
||||
d_status = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
strcat(strcat(prefix, "/"), name);
|
||||
pte = ref_path_table_lookup(thepath);
|
||||
if (pte == NULL) {
|
||||
ref_path_table_put(obj, thepath);
|
||||
H5Giterate(obj, ".", NULL, fill_ref_path_table, NULL);
|
||||
strcpy(prefix, tmp);
|
||||
}
|
||||
H5Gclose(obj);
|
||||
} else {
|
||||
error_msg(progname, "unable to dump group \"%s\"\n", name);
|
||||
d_status = EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
case H5G_TYPE:
|
||||
if ((obj = H5Topen(group, name)) >= 0) {
|
||||
pte = ref_path_table_lookup(thepath);
|
||||
if (pte == NULL)
|
||||
ref_path_table_put(obj, thepath);
|
||||
H5Tclose(obj);
|
||||
} else {
|
||||
error_msg(progname, "unable to get dataset \"%s\"\n", name);
|
||||
d_status = EXIT_FAILURE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(tmp);
|
||||
free(thepath);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -17,31 +17,22 @@
|
||||
|
||||
#include "hdf5.h"
|
||||
|
||||
typedef struct ref_path_table_entry_t {
|
||||
hid_t obj;
|
||||
char *apath;
|
||||
H5G_stat_t statbuf;
|
||||
struct ref_path_table_entry_t *next;
|
||||
}ref_path_table_entry_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char* lookup_ref_path(hobj_ref_t ref);
|
||||
int init_ref_path_table(hid_t fid);
|
||||
const char *lookup_ref_path(haddr_t ref);
|
||||
herr_t fill_ref_path_table(hid_t, const char *, void *);
|
||||
int get_next_xid(void);
|
||||
haddr_t get_fake_xid (void);
|
||||
struct ref_path_table_entry_t *ref_path_table_lookup(const char *);
|
||||
ref_path_table_entry_t *ref_path_table_put(hid_t obj, const char *path);
|
||||
struct ref_path_table_entry_t *ref_path_table_gen_fake(const char *);
|
||||
haddr_t ref_path_table_lookup(const char *);
|
||||
haddr_t ref_path_table_gen_fake(const char *);
|
||||
int term_ref_path_table(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -25,8 +25,8 @@
|
||||
|
||||
#include "H5private.h"
|
||||
#include "h5tools.h" /*for h5dump_t structure */
|
||||
#include "h5tools_str.h" /*function prototypes */
|
||||
#include "h5tools_ref.h"
|
||||
#include "h5tools_str.h" /*function prototypes */
|
||||
|
||||
/*
|
||||
* If REPEAT_VERBOSE is defined then character strings will be printed so
|
||||
@ -855,7 +855,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5dump_t *info, hid_t container,
|
||||
if (h5tools_is_zero(vp, H5Tget_size(type))) {
|
||||
h5tools_str_append(str, "NULL");
|
||||
} else {
|
||||
char *path=NULL;
|
||||
const char *path;
|
||||
otype = H5Rget_obj_type(container, H5R_OBJECT, vp);
|
||||
obj = H5Rdereference(container, H5R_OBJECT, vp);
|
||||
H5Gget_objinfo(obj, ".", FALSE, &sb);
|
||||
@ -886,7 +886,7 @@ h5tools_str_sprint(h5tools_str_t *str, const h5dump_t *info, hid_t container,
|
||||
h5tools_str_append(str, info->obj_format, sb.fileno,sb.objno);
|
||||
|
||||
/* Print name */
|
||||
path = lookup_ref_path(*(hobj_ref_t *)vp);
|
||||
path = lookup_ref_path(*(haddr_t *)vp);
|
||||
if (path) {
|
||||
h5tools_str_append(str, " ");
|
||||
h5tools_str_append(str, path);
|
||||
|
@ -39,7 +39,13 @@ int opt_ind = 1; /*token pointer */
|
||||
const char *opt_arg; /*flag argument (or value) */
|
||||
|
||||
/* local functions */
|
||||
static void add_obj(table_t *table, haddr_t objno, char *objname);
|
||||
static void init_table(table_t **tbl);
|
||||
#ifdef H5DUMP_DEBUG
|
||||
static void dump_table(char* tablename, table_t *table);
|
||||
#endif /* H5DUMP_DEBUG */
|
||||
static void add_obj(table_t *table, haddr_t objno, char *objname, hbool_t recorded);
|
||||
static char * build_obj_path_name(const char *prefix, const char *name);
|
||||
static herr_t find_objs_cb(hid_t group, const char *name, void *op_data);
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -309,46 +315,18 @@ print_version(const char *progname)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
static void
|
||||
init_table(table_t **tbl)
|
||||
{
|
||||
int i;
|
||||
table_t *table = HDmalloc(sizeof(table_t));
|
||||
|
||||
table->size = 20;
|
||||
table->nobjs = 0;
|
||||
table->objs = HDmalloc(table->size * sizeof(obj_t));
|
||||
|
||||
for (i = 0; i < table->size; i++) {
|
||||
table->objs[i].objno = 0;
|
||||
table->objs[i].displayed = 0;
|
||||
table->objs[i].recorded = 0;
|
||||
table->objs[i].objflag = 0;
|
||||
table->objs[i].objname = NULL;
|
||||
}
|
||||
|
||||
*tbl = table;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: init_prefix
|
||||
*
|
||||
* Purpose: allocate and initialize prefix
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
init_prefix(char **prefix, size_t prefix_len)
|
||||
{
|
||||
assert(prefix_len > 0);
|
||||
*prefix = HDcalloc(prefix_len, 1);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: free_table
|
||||
@ -365,11 +343,68 @@ init_prefix(char **prefix, size_t prefix_len)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
free_table(table_t **table)
|
||||
free_table(table_t *table)
|
||||
{
|
||||
HDfree((*table)->objs);
|
||||
unsigned u; /* Local index value */
|
||||
|
||||
/* Free the names for the objects in the table */
|
||||
for(u = 0; u < table->nobjs; u++)
|
||||
if(table->objs[u].objname)
|
||||
HDfree(table->objs[u].objname);
|
||||
|
||||
HDfree(table->objs);
|
||||
}
|
||||
|
||||
#ifdef H5DUMP_DEBUG
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: dump_table
|
||||
*
|
||||
* Purpose: display the contents of tables for debugging purposes
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Programmer: Ruey-Hsia Li
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
dump_table(char* tablename, table_t *table)
|
||||
{
|
||||
unsigned u;
|
||||
|
||||
printf("%s: # of entries = %d\n", tablename,table->nobjs);
|
||||
for (u = 0; u < table->nobjs; u++)
|
||||
HDfprintf(stdout,"%a %s %d %d\n", table->objs[u].objno,
|
||||
table->objs[u].objname,
|
||||
table->objs[u].displayed, table->objs[u].recorded);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: dump_tables
|
||||
*
|
||||
* Purpose: display the contents of tables for debugging purposes
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Programmer: Ruey-Hsia Li
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
dump_tables(find_objs_t *info)
|
||||
{
|
||||
dump_table("group_table", info->group_table);
|
||||
dump_table("dset_table", info->dset_table);
|
||||
dump_table("type_table", info->type_table);
|
||||
}
|
||||
#endif /* H5DUMP_DEBUG */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: search_obj
|
||||
@ -386,23 +421,153 @@ free_table(table_t **table)
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
obj_t *
|
||||
search_obj(table_t *table, haddr_t objno)
|
||||
{
|
||||
int i;
|
||||
unsigned u;
|
||||
|
||||
for (i = 0; i < table->nobjs; i++)
|
||||
if (table->objs[i].objno == objno)
|
||||
return i;
|
||||
for (u = 0; u < table->nobjs; u++)
|
||||
if (table->objs[u].objno == objno)
|
||||
return &(table->objs[u]);
|
||||
|
||||
return FAIL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: find_objs
|
||||
* Function: build_obj_path_name
|
||||
*
|
||||
* Purpose: Find objects, committed types and store them in tables
|
||||
* Purpose: Allocate space & build path name from prefix & name
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Quincey Koziol
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static char *
|
||||
build_obj_path_name(const char *prefix, const char *name)
|
||||
{
|
||||
char *path;
|
||||
|
||||
path = HDmalloc(HDstrlen(prefix) + HDstrlen(name) + 2);
|
||||
HDstrcpy(path, prefix);
|
||||
HDstrcat(path,"/");
|
||||
HDstrcat(path,name); /* absolute name of the data set */
|
||||
|
||||
return(path);
|
||||
} /* end build_obj_path_name() */
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: find_objs_cb
|
||||
*
|
||||
* Purpose: Callback to find objects, committed types and store them in tables
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Ruey-Hsia Li
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static herr_t
|
||||
find_objs_cb(hid_t group, const char *name, void *op_data)
|
||||
{
|
||||
H5G_stat_t statbuf;
|
||||
find_objs_t *info = (find_objs_t*)op_data;
|
||||
herr_t ret_value = 0;
|
||||
|
||||
H5Gget_objinfo(group, name, TRUE, &statbuf);
|
||||
|
||||
switch (statbuf.type) {
|
||||
char *tmp;
|
||||
|
||||
case H5G_GROUP:
|
||||
if (search_obj(info->group_table, statbuf.objno) == NULL) {
|
||||
char *old_prefix;
|
||||
|
||||
tmp = build_obj_path_name(info->prefix, name);
|
||||
add_obj(info->group_table, statbuf.objno, tmp, TRUE);
|
||||
|
||||
old_prefix = info->prefix;
|
||||
info->prefix = tmp;
|
||||
|
||||
if(H5Giterate(group, name, NULL, find_objs_cb, (void *)info) < 0)
|
||||
ret_value = FAIL;
|
||||
|
||||
info->prefix = old_prefix;
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
case H5G_DATASET:
|
||||
if (search_obj(info->dset_table, statbuf.objno) == NULL) {
|
||||
hid_t dset;
|
||||
|
||||
tmp = build_obj_path_name(info->prefix, name);
|
||||
add_obj(info->dset_table, statbuf.objno, tmp, TRUE);
|
||||
|
||||
if ((dset = H5Dopen (group, name)) >= 0) {
|
||||
hid_t type;
|
||||
|
||||
type = H5Dget_type(dset);
|
||||
|
||||
if (H5Tcommitted(type) > 0) {
|
||||
H5Gget_objinfo(type, ".", TRUE, &statbuf);
|
||||
|
||||
if (search_obj(info->type_table, statbuf.objno) == NULL) {
|
||||
char *type_name = HDstrdup(tmp);
|
||||
|
||||
add_obj(info->type_table, statbuf.objno, type_name, FALSE);
|
||||
} /* end if */
|
||||
}
|
||||
|
||||
H5Tclose(type);
|
||||
H5Dclose(dset);
|
||||
} else {
|
||||
ret_value = FAIL;
|
||||
}
|
||||
} /* end if */
|
||||
break;
|
||||
|
||||
case H5G_TYPE:
|
||||
{
|
||||
obj_t *found_obj;
|
||||
|
||||
tmp = build_obj_path_name(info->prefix, name);
|
||||
if ((found_obj = search_obj(info->type_table, statbuf.objno)) == NULL)
|
||||
add_obj(info->type_table, statbuf.objno, tmp, TRUE);
|
||||
else {
|
||||
/* Use latest version of name */
|
||||
HDfree(found_obj->objname);
|
||||
found_obj->objname = HDstrdup(tmp);
|
||||
|
||||
/* Mark named datatype as having valid name */
|
||||
found_obj->recorded = TRUE;
|
||||
} /* end else */
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
/* Ignore links, etc. */
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: init_objs
|
||||
*
|
||||
* Purpose: Initialize tables for groups, datasets & named datatypes
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
@ -415,216 +580,22 @@ search_obj(table_t *table, haddr_t objno)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
herr_t
|
||||
find_objs(hid_t group, const char *name, void *op_data)
|
||||
init_objs(hid_t fid, find_objs_t *info, table_t **group_table,
|
||||
table_t **dset_table, table_t **type_table)
|
||||
{
|
||||
hid_t obj, type;
|
||||
H5G_stat_t statbuf;
|
||||
char *tmp;
|
||||
find_objs_t *info = (find_objs_t*)op_data;
|
||||
int i;
|
||||
/* Initialize the tables */
|
||||
init_table(group_table);
|
||||
init_table(dset_table);
|
||||
init_table(type_table);
|
||||
|
||||
if (info->threshold > 1)
|
||||
/*will get an infinite loop if greater than 1*/
|
||||
return FAIL;
|
||||
/* Init the find_objs_t */
|
||||
info->prefix = "";
|
||||
info->group_table = *group_table;
|
||||
info->type_table = *type_table;
|
||||
info->dset_table = *dset_table;
|
||||
|
||||
H5Gget_objinfo(group, name, TRUE, &statbuf);
|
||||
|
||||
tmp = HDmalloc(HDstrlen(info->prefix) + HDstrlen(name) + 2);
|
||||
HDstrcpy(tmp, info->prefix);
|
||||
|
||||
switch (statbuf.type) {
|
||||
case H5G_GROUP:
|
||||
if ((obj = H5Gopen(group, name)) >= 0) {
|
||||
while (info->prefix_len < (HDstrlen(info->prefix) + HDstrlen(name) + 2)) {
|
||||
info->prefix_len *= 2;
|
||||
info->prefix = HDrealloc(info->prefix,
|
||||
info->prefix_len * sizeof(char));
|
||||
}
|
||||
|
||||
HDstrcat(HDstrcat(info->prefix,"/"), name);
|
||||
|
||||
if (statbuf.nlink > info->threshold) {
|
||||
if (search_obj(info->group_table, statbuf.objno) == FAIL) {
|
||||
add_obj(info->group_table, statbuf.objno, info->prefix);
|
||||
H5Giterate(obj, ".", NULL, find_objs, (void *)info);
|
||||
}
|
||||
} else {
|
||||
H5Giterate (obj, ".", NULL, find_objs, (void *)info);
|
||||
}
|
||||
|
||||
HDstrcpy(info->prefix, tmp);
|
||||
H5Gclose (obj);
|
||||
} else {
|
||||
info->status = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case H5G_DATASET:
|
||||
HDstrcat(tmp,"/");
|
||||
HDstrcat(tmp,name); /* absolute name of the data set */
|
||||
|
||||
if (statbuf.nlink > info->threshold &&
|
||||
search_obj(info->dset_table, statbuf.objno) == FAIL)
|
||||
add_obj(info->dset_table, statbuf.objno, tmp);
|
||||
|
||||
if ((obj = H5Dopen (group, name)) >= 0) {
|
||||
type = H5Dget_type(obj);
|
||||
|
||||
if (H5Tcommitted(type) > 0) {
|
||||
H5Gget_objinfo(type, ".", TRUE, &statbuf);
|
||||
|
||||
if (search_obj(info->type_table, statbuf.objno) == FAIL) {
|
||||
add_obj(info->type_table, statbuf.objno, tmp);
|
||||
info->type_table->objs[info->type_table->nobjs - 1].objflag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
H5Tclose(type);
|
||||
H5Dclose (obj);
|
||||
} else {
|
||||
info->status = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case H5G_TYPE:
|
||||
HDstrcat(tmp,"/");
|
||||
HDstrcat(tmp,name); /* absolute name of the type */
|
||||
i = search_obj(info->type_table, statbuf.objno);
|
||||
|
||||
if (i == FAIL) {
|
||||
add_obj(info->type_table, statbuf.objno, tmp) ;
|
||||
|
||||
/* named data type */
|
||||
info->type_table->objs[info->type_table->nobjs-1].recorded = 1;
|
||||
|
||||
/* named data type */
|
||||
info->type_table->objs[info->type_table->nobjs-1].objflag = 1;
|
||||
} else {
|
||||
free(info->type_table->objs[i].objname);
|
||||
info->type_table->objs[i].objname = HDstrdup(tmp);
|
||||
info->type_table->objs[i].recorded = 1;
|
||||
|
||||
/* named data type */
|
||||
info->type_table->objs[info->type_table->nobjs-1].objflag = 1;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
HDfree(tmp);
|
||||
return SUCCEED;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: dump_table
|
||||
*
|
||||
* Purpose: display the contents of tables for debugging purposes
|
||||
*
|
||||
* Return: void
|
||||
*
|
||||
* Programmer: Ruey-Hsia Li
|
||||
*
|
||||
* Modifications:
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
dump_table(char* tablename, table_t *table)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("%s: # of entries = %d\n", tablename,table->nobjs);
|
||||
|
||||
for (i = 0; i < table->nobjs; i++)
|
||||
HDfprintf(stdout,"\t%a %s %d\n",
|
||||
table->objs[i].objno,
|
||||
table->objs[i].objname,
|
||||
table->objs[i].objflag);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: get_table_idx
|
||||
*
|
||||
* Purpose: Determine if objects are in a link loop
|
||||
*
|
||||
* Return: Success: table index of object detected to be in loop
|
||||
*
|
||||
* Failure: FAIL
|
||||
*
|
||||
* Programmer: Paul Harten
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
get_table_idx(table_t *table, haddr_t objno)
|
||||
{
|
||||
return search_obj(table, objno);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: get_tableflag
|
||||
*
|
||||
* Purpose: Return the i'th element's flag setting
|
||||
*
|
||||
* Return: Boolean setting of the i'th element of the object table flag
|
||||
*
|
||||
* Programmer: Paul Harten
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
get_tableflag(table_t *table, int idx)
|
||||
{
|
||||
return table->objs[idx].objflag;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: set_tableflag
|
||||
*
|
||||
* Purpose: Set the i'th element of the object table's flag to TRUE
|
||||
*
|
||||
* Return: Success: SUCCEED
|
||||
*
|
||||
* Failure: N/A
|
||||
*
|
||||
* Programmer: Paul Harten
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
set_tableflag(table_t *table, int idx)
|
||||
{
|
||||
table->objs[idx].objflag = TRUE;
|
||||
return SUCCEED;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
* Function: get_objectname
|
||||
*
|
||||
* Purpose: Get name of i'th object in table
|
||||
*
|
||||
* Return: Success: strdup() of object name character string
|
||||
*
|
||||
* Failure: NULL and sets errno to ENOMEM
|
||||
*
|
||||
* Programmer: Paul Harten
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
char *
|
||||
get_objectname(table_t *table, int idx)
|
||||
{
|
||||
return HDstrdup(table->objs[idx].objname);
|
||||
/* Find all shared objects */
|
||||
return(H5Giterate(fid, "/", NULL, find_objs_cb, (void *)info));
|
||||
}
|
||||
|
||||
|
||||
@ -643,27 +614,24 @@ get_objectname(table_t *table, int idx)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
static void
|
||||
add_obj(table_t *table, haddr_t objno, char *objname)
|
||||
add_obj(table_t *table, haddr_t objno, char *objname, hbool_t record)
|
||||
{
|
||||
int i;
|
||||
unsigned u;
|
||||
|
||||
/* See if we need to make table larger */
|
||||
if (table->nobjs == table->size) {
|
||||
table->size *= 2;
|
||||
table->objs = HDrealloc(table->objs, table->size * sizeof(obj_t));
|
||||
|
||||
for (i = table->nobjs; i < table->size; i++) {
|
||||
table->objs[i].objno = 0;
|
||||
table->objs[i].displayed = 0;
|
||||
table->objs[i].recorded = 0;
|
||||
table->objs[i].objflag = 0;
|
||||
table->objs[i].objname = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
i = table->nobjs++;
|
||||
table->objs[i].objno = objno;
|
||||
free(table->objs[i].objname);
|
||||
table->objs[i].objname = HDstrdup(objname);
|
||||
/* Increment number of objects in table */
|
||||
u = table->nobjs++;
|
||||
|
||||
/* Set information about object */
|
||||
table->objs[u].objno = objno;
|
||||
table->objs[u].objname = objname;
|
||||
table->objs[u].recorded = record;
|
||||
table->objs[u].displayed = 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -81,27 +81,23 @@ extern int get_option(int argc, const char **argv, const char *opt,
|
||||
typedef struct obj_t {
|
||||
haddr_t objno;
|
||||
char *objname;
|
||||
int displayed;
|
||||
int recorded;
|
||||
int objflag;
|
||||
hbool_t displayed; /* Flag to indicate that the object has been displayed */
|
||||
hbool_t recorded; /* Flag for named datatypes to indicate they were found in the group hierarchy */
|
||||
} obj_t;
|
||||
|
||||
/*struct for the tables that the find_objs function uses*/
|
||||
typedef struct table_t {
|
||||
int size;
|
||||
int nobjs;
|
||||
size_t size;
|
||||
size_t nobjs;
|
||||
obj_t *objs;
|
||||
} table_t;
|
||||
|
||||
/*this struct stores the information that is passed to the find_objs function*/
|
||||
typedef struct find_objs_t {
|
||||
size_t prefix_len;
|
||||
char *prefix;
|
||||
unsigned int threshold; /* should be 0 or 1 */
|
||||
table_t *group_table;
|
||||
table_t *type_table;
|
||||
table_t *dset_table;
|
||||
int status;
|
||||
} find_objs_t;
|
||||
|
||||
extern int nCols; /*max number of columns for outputting */
|
||||
@ -111,16 +107,13 @@ extern void indentation(int);
|
||||
extern void print_version(const char *progname);
|
||||
extern void error_msg(const char *progname, const char *fmt, ...);
|
||||
extern void warn_msg(const char *progname, const char *fmt, ...);
|
||||
extern void free_table(table_t **table);
|
||||
extern void dump_table(char *name, table_t *table);
|
||||
extern int get_table_idx(table_t *table, haddr_t objno);
|
||||
extern int get_tableflag(table_t*, int);
|
||||
extern int set_tableflag(table_t*, int);
|
||||
extern char *get_objectname(table_t*, int);
|
||||
extern herr_t find_objs(hid_t group, const char *name, void *op_data);
|
||||
extern int search_obj(table_t *temp, haddr_t objno);
|
||||
extern void init_table(table_t **tbl);
|
||||
extern void init_prefix(char **temp, size_t);
|
||||
extern void free_table(table_t *table);
|
||||
#ifdef H5DUMP_DEBUG
|
||||
extern void dump_tables(find_objs_t *info)
|
||||
#endif /* H5DUMP_DEBUG */
|
||||
extern herr_t init_objs(hid_t fid, find_objs_t *info, table_t **group_table,
|
||||
table_t **dset_table, table_t **type_table);
|
||||
extern obj_t *search_obj(table_t *temp, haddr_t objno);
|
||||
#ifndef H5_HAVE_TMPFILE
|
||||
extern FILE * tmpfile(void);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user