1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 #include "H5private.h"    /* Generic Functions      */
15 #include "h5tools.h"
16 #include "h5tools_utils.h"
17 #include "h5tools_ref.h"
18 #include "h5trav.h"
19 #include "hdf5.h"
20 
21 /* Name of tool */
22 #define PROGRAMNAME "h5stat"
23 
24 /* Parameters to control statistics gathered */
25 
26 /* Default threshold for small groups/datasets/attributes */
27 #define DEF_SIZE_SMALL_GROUPS           10
28 #define DEF_SIZE_SMALL_DSETS            10
29 #define DEF_SIZE_SMALL_ATTRS            10
30 
31 #define SIZE_SMALL_SECTS            10
32 
33 #define  H5_NFILTERS_IMPL        8     /* Number of currently implemented filters + one to
34                                           accommodate for user-define filters + one
35                                           to accomodate datasets whithout any filters */
36 
37 /* File space management strategies: see H5Fpublic.h for declarations */
38 const char *FS_STRATEGY_NAME[] = {
39     "H5F_FSPACE_STRATEGY_FSM_AGGR",
40     "H5F_FSPACE_STRATEGY_PAGE",
41     "H5F_FSPACE_STRATEGY_AGGR",
42     "H5F_FSPACE_STRATEGY_NONE",
43     "unknown",
44     NULL
45 };
46 
47 /* Datatype statistics for datasets */
48 typedef struct dtype_info_t {
49     hid_t tid;                          /* ID of datatype */
50     unsigned long count;                /* Number of types found */
51     unsigned long named;                /* Number of types that are named */
52 } dtype_info_t;
53 
54 typedef struct ohdr_info_t {
55     hsize_t total_size;                 /* Total size of object headers */
56     hsize_t free_size;                  /* Total free space in object headers */
57 } ohdr_info_t;
58 
59 /* Info to pass to the iteration functions */
60 typedef struct iter_t {
61     hid_t fid;                          /* File ID */
62     hsize_t filesize;      /* Size of the file */
63     unsigned long uniq_groups;          /* Number of unique groups */
64     unsigned long uniq_dsets;           /* Number of unique datasets */
65     unsigned long uniq_dtypes;          /* Number of unique named datatypes */
66     unsigned long uniq_links;           /* Number of unique links */
67     unsigned long uniq_others;          /* Number of other unique objects */
68 
69     unsigned long max_links;            /* Maximum # of links to an object */
70     hsize_t max_fanout;                 /* Maximum fanout from a group */
71     unsigned long *num_small_groups;    /* Size of small groups tracked */
72     unsigned group_nbins;               /* Number of bins for group counts */
73     unsigned long *group_bins;          /* Pointer to array of bins for group counts */
74     ohdr_info_t group_ohdr_info;        /* Object header information for groups */
75 
76     hsize_t  max_attrs;                 /* Maximum attributes from a group */
77     unsigned long *num_small_attrs;     /* Size of small attributes tracked */
78     unsigned attr_nbins;                /* Number of bins for attribute counts */
79     unsigned long *attr_bins;           /* Pointer to array of bins for attribute counts */
80 
81     unsigned max_dset_rank;             /* Maximum rank of dataset */
82     unsigned long dset_rank_count[H5S_MAX_RANK];   /* Number of datasets of each rank */
83     hsize_t max_dset_dims;              /* Maximum dimension size of dataset */
84     unsigned long *small_dset_dims;     /* Size of dimensions of small datasets tracked */
85     unsigned long dset_layouts[H5D_NLAYOUTS];           /* Type of storage for each dataset */
86     unsigned long dset_comptype[H5_NFILTERS_IMPL];     /* Number of currently implemented filters */
87     unsigned long dset_ntypes;          /* Number of diff. dataset datatypes found */
88     dtype_info_t *dset_type_info;       /* Pointer to dataset datatype information found */
89     unsigned dset_dim_nbins;            /* Number of bins for dataset dimensions */
90     unsigned long *dset_dim_bins;       /* Pointer to array of bins for dataset dimensions */
91     ohdr_info_t dset_ohdr_info;         /* Object header information for datasets */
92     hsize_t dset_storage_size;          /* Size of raw data for datasets */
93     hsize_t dset_external_storage_size; /* Size of raw data for datasets with external storage */
94     ohdr_info_t dtype_ohdr_info;        /* Object header information for datatypes */
95     hsize_t groups_btree_storage_size;  /* btree size for group */
96     hsize_t groups_heap_storage_size;   /* heap size for group */
97     hsize_t attrs_btree_storage_size;   /* btree size for attributes (1.8) */
98     hsize_t attrs_heap_storage_size;    /* fractal heap size for attributes (1.8) */
99     hsize_t SM_hdr_storage_size;        /* header size for SOHM table (1.8) */
100     hsize_t SM_index_storage_size;      /* index (btree & list) size for SOHM table (1.8) */
101     hsize_t SM_heap_storage_size;       /* fractal heap size for SOHM table (1.8) */
102     hsize_t super_size;                 /* superblock size */
103     hsize_t super_ext_size;             /* superblock extension size */
104     hsize_t ublk_size;                  /* user block size (if exists) */
105     H5F_fspace_strategy_t fs_strategy;  /* File space management strategy */
106     hbool_t fs_persist;                 /* Free-space persist or not */
107     hsize_t fs_threshold;               /* Free-space section threshold */
108     hsize_t fsp_size;                   /* File space page size */
109     hsize_t free_space;                 /* Amount of freespace in the file */
110     hsize_t free_hdr;                   /* Size of free space manager metadata in the file */
111     unsigned long num_small_sects[SIZE_SMALL_SECTS];   /* Size of small free-space sections */
112     unsigned sect_nbins;                /* Number of bins for free-space section sizes */
113     unsigned long *sect_bins;           /* Pointer to array of bins for free-space section sizes */
114     hsize_t datasets_index_storage_size;/* meta size for chunked dataset's indexing type */
115     hsize_t datasets_heap_storage_size; /* heap size for dataset with external storage */
116     unsigned long nexternal;            /* Number of external files for a dataset */
117     int           local;                /* Flag to indicate iteration over the object*/
118 } iter_t;
119 
120 
121 static const char *drivername = "";
122 
123 #ifdef H5_HAVE_ROS3_VFD
124 /* default "anonymous" s3 configuration
125  */
126 static H5FD_ros3_fapl_t ros3_fa = {
127     1,     /* fapl version      */
128     false, /* authenticate      */
129     "",    /* aws region        */
130     "",    /* access key id     */
131     "",    /* secret access key */
132 };
133 #endif /* H5_HAVE_ROS3_VFD */
134 
135 #ifdef H5_HAVE_LIBHDFS
136 /* default HDFS access configuration
137  */
138 static H5FD_hdfs_fapl_t hdfs_fa = {
139     1,           /* fapl version          */
140     "localhost", /* namenode name         */
141     0,           /* namenode port         */
142     "",          /* kerberos ticket cache */
143     "",          /* user name             */
144     2048,        /* stream buffer size    */
145 };
146 #endif /* H5_HAVE_LIBHDFS */
147 
148 static int        display_all = TRUE;
149 
150 /* Enable the printing of selected statistics */
151 static int        display_file = FALSE;     /* display file information */
152 static int        display_group = FALSE;    /* display groups information */
153 static int        display_dset = FALSE;     /* display datasets information */
154 static int        display_dset_dtype_meta = FALSE;  /* display datasets' datatype information */
155 static int        display_attr = FALSE;     /* display attributes information */
156 static int        display_free_sections = FALSE;    /* display free space information */
157 static int        display_summary = FALSE;  /* display summary of file space information */
158 
159 static int        display_file_metadata = FALSE;    /* display file space info for file's metadata */
160 static int        display_group_metadata = FALSE;   /* display file space info for groups' metadata */
161 static int        display_dset_metadata = FALSE;    /* display file space info for datasets' metadata */
162 
163 static int        display_object = FALSE;  /* not implemented yet */
164 
165 /* Initialize threshold for small groups/datasets/attributes */
166 static int      sgroups_threshold = DEF_SIZE_SMALL_GROUPS;
167 static int      sdsets_threshold = DEF_SIZE_SMALL_DSETS;
168 static int      sattrs_threshold = DEF_SIZE_SMALL_ATTRS;
169 
170 /* a structure for handling the order command-line parameters come in */
171 struct handler_t {
172     size_t obj_count;
173     char **obj;
174 };
175 
176 static const char *s_opts ="Aa:Ddm:EFfhGgl:sSTO:Vw:H:";
177 /* e.g. "filemetadata" has to precede "file"; "groupmetadata" has to precede "group" etc. */
178 static struct long_options l_opts[] = {
179     {"help", no_arg, 'h'},
180     {"hel", no_arg, 'h'},
181     {"he", no_arg, 'h'},
182     {"filemetadata", no_arg, 'F'},
183     {"filemetadat", no_arg, 'F'},
184     {"filemetada", no_arg, 'F'},
185     {"filemetad", no_arg, 'F'},
186     {"filemeta", no_arg, 'F'},
187     {"filemet", no_arg, 'F'},
188     {"fileme", no_arg, 'F'},
189     {"filem", no_arg, 'F'},
190     {"file", no_arg, 'f'},
191     {"fil", no_arg, 'f'},
192     {"fi", no_arg, 'f'},
193     {"groupmetadata", no_arg, 'G'},
194     {"groupmetadat", no_arg, 'G'},
195     {"groupmetada", no_arg, 'G'},
196     {"groupmetad", no_arg, 'G'},
197     {"groupmeta", no_arg, 'G'},
198     {"groupmet", no_arg, 'G'},
199     {"groupme", no_arg, 'G'},
200     {"groupm", no_arg, 'G'},
201     {"group", no_arg, 'g'},
202     {"grou", no_arg, 'g'},
203     {"gro", no_arg, 'g'},
204     {"gr", no_arg, 'g'},
205     { "links", require_arg, 'l' },
206     { "link", require_arg, 'l' },
207     { "lin", require_arg, 'l' },
208     { "li", require_arg, 'l' },
209     {"dsetmetadata", no_arg, 'D'},
210     {"dsetmetadat", no_arg, 'D'},
211     {"dsetmetada", no_arg, 'D'},
212     {"dsetmetad", no_arg, 'D'},
213     {"dsetmeta", no_arg, 'D'},
214     {"dsetmet", no_arg, 'D'},
215     {"dsetme", no_arg, 'D'},
216     {"dsetm", no_arg, 'D'},
217     {"dset", no_arg, 'd'},
218     {"dse", no_arg, 'd'},
219     {"ds", no_arg, 'd'},
220     {"dims", require_arg, 'm'},
221     {"dim", require_arg, 'm'},
222     {"di", require_arg, 'm'},
223     {"dtypemetadata", no_arg, 'T'},
224     {"dtypemetadat", no_arg, 'T'},
225     {"dtypemetada", no_arg, 'T'},
226     {"dtypemetad", no_arg, 'T'},
227     {"dtypemeta", no_arg, 'T'},
228     {"dtypemet", no_arg, 'T'},
229     {"dtypeme", no_arg, 'T'},
230     {"dtypem", no_arg, 'T'},
231     {"dtype", no_arg, 'T'},
232     {"dtyp", no_arg, 'T'},
233     {"dty", no_arg, 'T'},
234     {"dt", no_arg, 'T'},
235     { "object", require_arg, 'O' },
236     { "objec", require_arg, 'O' },
237     { "obje", require_arg, 'O' },
238     { "obj", require_arg, 'O' },
239     { "ob", require_arg, 'O' },
240     { "version", no_arg, 'V' },
241     { "versio", no_arg, 'V' },
242     { "versi", no_arg, 'V' },
243     { "vers", no_arg, 'V' },
244     { "ver", no_arg, 'V' },
245     { "ve", no_arg, 'V' },
246     { "attribute", no_arg, 'A' },
247     { "attribut", no_arg, 'A' },
248     { "attribu", no_arg, 'A' },
249     { "attrib", no_arg, 'A' },
250     { "attri", no_arg, 'A' },
251     { "attr", no_arg, 'A' },
252     { "att", no_arg, 'A' },
253     { "at", no_arg, 'A' },
254     { "enable-error-stack", no_arg, 'E' },
255     { "numattrs", require_arg, 'a' },
256     { "numattr", require_arg, 'a' },
257     { "numatt", require_arg, 'a' },
258     { "numat", require_arg, 'a' },
259     { "numa", require_arg, 'a' },
260     { "num", require_arg, 'a' },
261     { "nu", require_arg, 'a' },
262     { "freespace", no_arg, 's' },
263     { "freespac", no_arg, 's' },
264     { "freespa", no_arg, 's' },
265     { "freesp", no_arg, 's' },
266     { "frees", no_arg, 's' },
267     { "free", no_arg, 's' },
268     { "fre", no_arg, 's' },
269     { "fr", no_arg, 's' },
270     { "summary", no_arg, 'S' },
271     { "summar", no_arg, 'S' },
272     { "summa", no_arg, 'S' },
273     { "summ", no_arg, 'S' },
274     { "sum", no_arg, 'S' },
275     { "su", no_arg, 'S' },
276     { "s3-cred", require_arg, 'w' },
277     { "hdfs-attrs", require_arg, 'H' },
278     { NULL, 0, '\0' }
279 };
280 
281 static void
leave(int ret)282 leave(int ret)
283 {
284    h5tools_close();
285    HDexit(ret);
286 }
287 
288 
289 
290 /*-------------------------------------------------------------------------
291  * Function: usage
292  *
293  * Purpose: Compute the ceiling of log_10(x)
294  *
295  * Return: >0 on success, 0 on failure
296  *
297  *-------------------------------------------------------------------------
298  */
usage(const char * prog)299 static void usage(const char *prog)
300 {
301      HDfflush(stdout);
302      HDfprintf(stdout, "Usage: %s [OPTIONS] file\n", prog);
303      HDfprintf(stdout, "\n");
304      HDfprintf(stdout, "      OPTIONS\n");
305      HDfprintf(stdout, "     -h, --help            Print a usage message and exit\n");
306      HDfprintf(stdout, "     -V, --version         Print version number and exit\n");
307      HDfprintf(stdout, "     -f, --file            Print file information\n");
308      HDfprintf(stdout, "     -F, --filemetadata    Print file space information for file's metadata\n");
309      HDfprintf(stdout, "     -g, --group           Print group information\n");
310      HDfprintf(stdout, "     -l N, --links=N       Set the threshold for the # of links when printing\n");
311      HDfprintf(stdout, "                           information for small groups.  N is an integer greater\n");
312      HDfprintf(stdout, "                           than 0.  The default threshold is 10.\n");
313      HDfprintf(stdout, "     -G, --groupmetadata   Print file space information for groups' metadata\n");
314      HDfprintf(stdout, "     -d, --dset            Print dataset information\n");
315      HDfprintf(stdout, "     -m N, --dims=N        Set the threshold for the dimension sizes when printing\n");
316      HDfprintf(stdout, "                           information for small datasets.  N is an integer greater\n");
317      HDfprintf(stdout, "                           than 0.  The default threshold is 10.\n");
318      HDfprintf(stdout, "     -D, --dsetmetadata    Print file space information for datasets' metadata\n");
319      HDfprintf(stdout, "     -T, --dtypemetadata   Print datasets' datatype information\n");
320      HDfprintf(stdout, "     -A, --attribute       Print attribute information\n");
321      HDfprintf(stdout, "     -a N, --numattrs=N    Set the threshold for the # of attributes when printing\n");
322      HDfprintf(stdout, "                           information for small # of attributes.  N is an integer greater\n");
323      HDfprintf(stdout, "                           than 0.  The default threshold is 10.\n");
324      HDfprintf(stdout, "     -s, --freespace       Print free space information\n");
325      HDfprintf(stdout, "     -S, --summary         Print summary of file space information\n");
326      HDfprintf(stdout, "     --enable-error-stack  Prints messages from the HDF5 error stack as they occur\n");
327      HDfprintf(stdout, "     --s3-cred=<cred>      Access file on S3, using provided credential\n");
328      HDfprintf(stdout, "                           <cred> :: (region,id,key)\n");
329      HDfprintf(stdout, "                           If <cred> == \"(,,)\", no authentication is used.\n");
330      HDfprintf(stdout, "     --hdfs-attrs=<attrs>  Access a file on HDFS with given configuration\n");
331      HDfprintf(stdout, "                           attributes.\n");
332      HDfprintf(stdout, "                           <attrs> :: (<namenode name>,<namenode port>,\n");
333      HDfprintf(stdout, "                                       <kerberos cache path>,<username>,\n");
334      HDfprintf(stdout, "                                       <buffer size>)\n");
335      HDfprintf(stdout, "                           If an attribute is empty, a default value will be\n");
336      HDfprintf(stdout, "                           used.\n");
337 }
338 
339 
340 /*-------------------------------------------------------------------------
341  * Function: ceil_log10
342  *
343  * Purpose: Compute the ceiling of log_10(x)
344  *
345  * Return: >0 on success, 0 on failure
346  *
347  * Programmer: Quincey Koziol
348  *              Monday, August 22, 2005
349  *
350  *-------------------------------------------------------------------------
351  */
352 H5_ATTR_CONST static unsigned
ceil_log10(unsigned long x)353 ceil_log10(unsigned long x)
354 {
355     unsigned long pow10 = 1;
356     unsigned ret = 0;
357 
358     while(x >= pow10) {
359         pow10 *= 10;
360         ret++;
361     } /* end while */
362 
363     return ret;
364 } /* ceil_log10() */
365 
366 
367 /*-------------------------------------------------------------------------
368  * Function: attribute_stats
369  *
370  * Purpose: Gather statistics about attributes on an object
371  *
372  * Return:  Success: 0
373  *
374  *          Failure: -1
375  *
376  * Programmer:    Quincey Koziol
377  *                Tuesday, July 17, 2007
378  *
379  *-------------------------------------------------------------------------
380  */
381 static herr_t
attribute_stats(iter_t * iter,const H5O_info_t * oi)382 attribute_stats(iter_t *iter, const H5O_info_t *oi)
383 {
384     unsigned     bin;               /* "bin" the number of objects falls in */
385 
386     /* Update dataset & attribute metadata info */
387     iter->attrs_btree_storage_size += oi->meta_size.attr.index_size;
388     iter->attrs_heap_storage_size += oi->meta_size.attr.heap_size;
389 
390     /* Update small # of attribute count & limits */
391     if(oi->num_attrs <= (hsize_t)sattrs_threshold)
392         (iter->num_small_attrs[(size_t)oi->num_attrs])++;
393     if(oi->num_attrs > iter->max_attrs)
394         iter->max_attrs = oi->num_attrs;
395 
396     /* Add attribute count to proper bin */
397     bin = ceil_log10((unsigned long)oi->num_attrs);
398     if((bin + 1) > iter->attr_nbins) {
399         iter->attr_bins = (unsigned long *)HDrealloc(iter->attr_bins, (bin + 1) * sizeof(unsigned long));
400         HDassert(iter->attr_bins);
401 
402   /* Initialize counts for intermediate bins */
403         while(iter->attr_nbins < bin)
404             iter->attr_bins[iter->attr_nbins++] = 0;
405         iter->attr_nbins++;
406 
407         /* Initialize count for new bin */
408         iter->attr_bins[bin] = 1;
409      } /* end if */
410      else
411          (iter->attr_bins[bin])++;
412 
413      return 0;
414 } /* end attribute_stats() */
415 
416 
417 /*-------------------------------------------------------------------------
418  * Function: group_stats
419  *
420  * Purpose: Gather statistics about the group
421  *
422  * Return:  Success: 0
423  *          Failure: -1
424  *
425  * Programmer: Quincey Koziol
426  *             Tuesday, August 16, 2005
427  *
428  * Modifications: Refactored code from the walk_function
429  *                EIP, Wednesday, August 16, 2006
430  *
431  *      Vailin Choi 12 July 2007
432  *      1. Gathered storage info for btree and heap
433  *         (groups and attributes)
434  *      2. Gathered info for attributes
435  *
436  *      Vailin Choi 14 July 2007
437  *      Cast "num_objs" and "num_attrs" to size_t
438  *      Due to the -Mbounds problem for the pgi-32 bit compiler on indexing
439  *
440  *-------------------------------------------------------------------------
441  */
442 static herr_t
group_stats(iter_t * iter,const char * name,const H5O_info_t * oi)443 group_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
444 {
445     H5G_info_t ginfo;           /* Group information */
446     unsigned bin;               /* "bin" the number of objects falls in */
447     herr_t ret_value = SUCCEED; /* Return value */
448 
449     /* Gather statistics about this type of object */
450     iter->uniq_groups++;
451 
452     /* Get object header information */
453     iter->group_ohdr_info.total_size += oi->hdr.space.total;
454     iter->group_ohdr_info.free_size += oi->hdr.space.free;
455 
456     /* Get group information */
457     if((ret_value = H5Gget_info_by_name(iter->fid, name, &ginfo, H5P_DEFAULT)) < 0)
458         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Gget_info_by_name() failed");
459 
460     /* Update link stats */
461     /* Collect statistics for small groups */
462     if(ginfo.nlinks < (hsize_t)sgroups_threshold)
463         (iter->num_small_groups[(size_t)ginfo.nlinks])++;
464     /* Determine maximum link count */
465     if(ginfo.nlinks > iter->max_fanout)
466         iter->max_fanout = ginfo.nlinks;
467 
468     /* Add group count to proper bin */
469     bin = ceil_log10((unsigned long)ginfo.nlinks);
470     if((bin + 1) > iter->group_nbins) {
471         /* Allocate more storage for info about dataset's datatype */
472         if((iter->group_bins = (unsigned long *)HDrealloc(iter->group_bins, (bin + 1) * sizeof(unsigned long))) == NULL)
473             HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Drealloc() failed");
474 
475         /* Initialize counts for intermediate bins */
476         while(iter->group_nbins < bin)
477             iter->group_bins[iter->group_nbins++] = 0;
478         iter->group_nbins++;
479 
480         /* Initialize count for new bin */
481         iter->group_bins[bin] = 1;
482     } /* end if */
483     else
484         (iter->group_bins[bin])++;
485 
486     /* Update group metadata info */
487     iter->groups_btree_storage_size += oi->meta_size.obj.index_size;
488     iter->groups_heap_storage_size += oi->meta_size.obj.heap_size;
489 
490     /* Update attribute metadata info */
491     if((ret_value = attribute_stats(iter, oi)) < 0)
492         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "attribute_stats failed");
493 
494 done:
495     return ret_value;
496 } /* end group_stats() */
497 
498 
499 /*-------------------------------------------------------------------------
500  * Function: dataset_stats
501  *
502  * Purpose: Gather statistics about the dataset
503  *
504  * Return:  Success: 0
505  *          Failure: -1
506  *
507  * Programmer:    Quincey Koziol
508  *                Tuesday, August 16, 2005
509  *
510  *-------------------------------------------------------------------------
511  */
512 static herr_t
dataset_stats(iter_t * iter,const char * name,const H5O_info_t * oi)513 dataset_stats(iter_t *iter, const char *name, const H5O_info_t *oi)
514 {
515     unsigned bin;               /* "bin" the number of objects falls in */
516     hid_t did;                  /* Dataset ID */
517     hid_t sid;                  /* Dataspace ID */
518     hid_t tid;                  /* Datatype ID */
519     hid_t dcpl;                 /* Dataset creation property list ID */
520     hsize_t dims[H5S_MAX_RANK]; /* Dimensions of dataset */
521     H5D_layout_t lout;          /* Layout of dataset */
522     unsigned type_found;        /* Whether the dataset's datatype was */
523                                 /* already found */
524     int ndims;                  /* Number of dimensions of dataset */
525     hsize_t storage;            /* Size of dataset storage */
526     unsigned u;                 /* Local index variable */
527     int num_ext;                /* Number of external files for a dataset */
528     int nfltr;                  /* Number of filters for a dataset */
529     H5Z_filter_t fltr;          /* Filter identifier */
530     herr_t ret_value = SUCCEED; /* Return value */
531 
532     /* Gather statistics about this type of object */
533     iter->uniq_dsets++;
534 
535     /* Get object header information */
536     iter->dset_ohdr_info.total_size += oi->hdr.space.total;
537     iter->dset_ohdr_info.free_size += oi->hdr.space.free;
538 
539     if((did = H5Dopen2(iter->fid, name, H5P_DEFAULT)) < 0)
540         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dopen() failed");
541 
542     /* Update dataset metadata info */
543     iter->datasets_index_storage_size += oi->meta_size.obj.index_size;
544     iter->datasets_heap_storage_size += oi->meta_size.obj.heap_size;
545 
546     /* Update attribute metadata info */
547     if((ret_value = attribute_stats(iter, oi)) < 0)
548         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "attribute_stats() failed");
549 
550     /* Get storage info */
551     /* Failure 0 indistinguishable from no-data-stored 0 */
552     storage = H5Dget_storage_size(did);
553 
554     /* Gather layout statistics */
555     if((dcpl = H5Dget_create_plist(did)) < 0)
556         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_create_plist() failed");
557 
558     if((lout = H5Pget_layout(dcpl)) < 0)
559         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pget_layout() failed");
560 
561     /* Object header's total size for H5D_COMPACT layout includes raw data size */
562     /* "storage" also includes H5D_COMPACT raw data size */
563     if(lout == H5D_COMPACT)
564         iter->dset_ohdr_info.total_size -= storage;
565 
566     /* Track the layout type for dataset */
567     (iter->dset_layouts[lout])++;
568 
569     /* Get the number of external files for the dataset */
570     if((num_ext = H5Pget_external_count(dcpl)) < 0)
571         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pget_external_count() failed");
572 
573     /* Accumulate raw data size accordingly */
574     if(num_ext) {
575         iter->nexternal += (unsigned long)num_ext;
576         iter->dset_external_storage_size += (unsigned long)storage;
577     }
578     else
579         iter->dset_storage_size += storage;
580 
581     /* Gather dataspace statistics */
582     if((sid = H5Dget_space(did)) < 0)
583         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_space() failed");
584 
585     if((ndims = H5Sget_simple_extent_dims(sid, dims, NULL)) < 0)
586         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sget_simple_extent_dims() failed");
587 
588     /* Check for larger rank of dataset */
589     if((unsigned)ndims > iter->max_dset_rank)
590         iter->max_dset_rank = (unsigned)ndims;
591 
592     /* Track the number of datasets with each rank */
593     (iter->dset_rank_count[ndims])++;
594 
595     /* Only gather dim size statistics on 1-D datasets */
596     if(ndims == 1) {
597         /* Determine maximum dimension size */
598         if(dims[0] > iter->max_dset_dims)
599             iter->max_dset_dims = dims[0];
600         /* Collect statistics for small datasets */
601         if(dims[0] < (hsize_t)sdsets_threshold)
602             (iter->small_dset_dims[(size_t)dims[0]])++;
603 
604         /* Add dim count to proper bin */
605         bin = ceil_log10((unsigned long)dims[0]);
606         if((bin + 1) > iter->dset_dim_nbins) {
607             /* Allocate more storage for info about dataset's datatype */
608             if((iter->dset_dim_bins = (unsigned long *)HDrealloc(iter->dset_dim_bins, (bin + 1) * sizeof(unsigned long))) == NULL)
609                 HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Drealloc() failed");
610 
611             /* Initialize counts for intermediate bins */
612             while(iter->dset_dim_nbins < bin)
613                 iter->dset_dim_bins[iter->dset_dim_nbins++] = 0;
614             iter->dset_dim_nbins++;
615 
616             /* Initialize count for this bin */
617             iter->dset_dim_bins[bin] = 1;
618         } /* end if */
619         else
620             (iter->dset_dim_bins[bin])++;
621     } /* end if */
622 
623     if(H5Sclose(sid) < 0)
624         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Sclose() failed");
625 
626     /* Gather datatype statistics */
627     if((tid = H5Dget_type(did)) < 0)
628         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dget_type() failed");
629 
630     type_found = FALSE;
631     for(u = 0; u < iter->dset_ntypes; u++)
632         if(H5Tequal(iter->dset_type_info[u].tid, tid) > 0) {
633             type_found = TRUE;
634             break;
635         } /* end for */
636 
637     if(type_found)
638          (iter->dset_type_info[u].count)++;
639     else {
640         unsigned curr_ntype = (unsigned)iter->dset_ntypes;
641 
642         /* Increment # of datatypes seen for datasets */
643         iter->dset_ntypes++;
644 
645         /* Allocate more storage for info about dataset's datatype */
646         if((iter->dset_type_info = (dtype_info_t *)HDrealloc(iter->dset_type_info, iter->dset_ntypes * sizeof(dtype_info_t))) == NULL)
647             HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Drealloc() failed");
648 
649         /* Initialize information about datatype */
650         if((iter->dset_type_info[curr_ntype].tid = H5Tcopy(tid)) < 0)
651             HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tcopy() failed");
652         iter->dset_type_info[curr_ntype].count = 1;
653         iter->dset_type_info[curr_ntype].named = 0;
654 
655         /* Set index for later */
656         u = curr_ntype;
657     } /* end else */
658 
659     /* Check if the datatype is a named datatype */
660     if(H5Tcommitted(tid) > 0)
661         (iter->dset_type_info[u].named)++;
662 
663     if(H5Tclose(tid) < 0)
664         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Tclose() failed");
665 
666     /* Track different filters */
667     if((nfltr = H5Pget_nfilters(dcpl)) >= 0) {
668        if(nfltr == 0)
669            iter->dset_comptype[0]++;
670         for(u = 0; u < (unsigned)nfltr; u++) {
671             fltr = H5Pget_filter2(dcpl, u, 0, 0, 0, 0, 0, NULL);
672             if(fltr >= 0) {
673                 if(fltr < (H5_NFILTERS_IMPL - 1))
674                     iter->dset_comptype[fltr]++;
675                 else
676                     iter->dset_comptype[H5_NFILTERS_IMPL - 1]++; /*other filters*/
677             } /* end if */
678         } /* end for */
679     } /* endif nfltr */
680 
681      if(H5Pclose(dcpl) < 0)
682         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Pclose() failed");
683 
684      if(H5Dclose(did) < 0)
685         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "H5Dclose() failed");
686 
687 done:
688      return ret_value;
689 }  /* end dataset_stats() */
690 
691 
692 /*-------------------------------------------------------------------------
693  * Function: datatype_stats
694  *
695  * Purpose: Gather statistics about the datatype
696  *
697  * Return:  Success: 0
698  *          Failure: -1
699  *
700  * Programmer:    Vailin Choi; July 7th, 2009
701  *
702  *-------------------------------------------------------------------------
703  */
704 static herr_t
datatype_stats(iter_t * iter,const H5O_info_t * oi)705 datatype_stats(iter_t *iter, const H5O_info_t *oi)
706 {
707     herr_t ret_value = SUCCEED;
708 
709     /* Gather statistics about this type of object */
710     iter->uniq_dtypes++;
711 
712     /* Get object header information */
713     iter->dtype_ohdr_info.total_size += oi->hdr.space.total;
714     iter->dtype_ohdr_info.free_size += oi->hdr.space.free;
715 
716     /* Update attribute metadata info */
717     if((ret_value = attribute_stats(iter, oi)) < 0)
718         HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "attribute_stats() failed");
719 done:
720      return ret_value;
721 }  /* end datatype_stats() */
722 
723 
724 /*-------------------------------------------------------------------------
725  * Function: obj_stats
726  *
727  * Purpose: Gather statistics about an object
728  *
729  * Return: Success: 0
730  *       Failure: -1
731  *
732  * Programmer: Quincey Koziol
733  *             Tuesday, November 6, 2007
734  *
735  *-------------------------------------------------------------------------
736  */
737 static herr_t
obj_stats(const char * path,const H5O_info_t * oi,const char * already_visited,void * _iter)738 obj_stats(const char *path, const H5O_info_t *oi, const char *already_visited,
739     void *_iter)
740 {
741     iter_t *iter = (iter_t *)_iter;
742     herr_t ret_value = SUCCEED;
743 
744     /* If the object has already been seen then just return */
745     if(NULL == already_visited) {
746         /* Gather some general statistics about the object */
747         if(oi->rc > iter->max_links)
748             iter->max_links = oi->rc;
749 
750         switch(oi->type) {
751             case H5O_TYPE_GROUP:
752                 if(group_stats(iter, path, oi) < 0)
753                     HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "group_stats failed");
754                 break;
755 
756             case H5O_TYPE_DATASET:
757                 if(dataset_stats(iter, path, oi) < 0)
758                     HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "dataset_stats failed");
759                 break;
760 
761             case H5O_TYPE_NAMED_DATATYPE:
762                 if(datatype_stats(iter, oi) < 0)
763                     HGOTO_ERROR(FAIL, H5E_tools_min_id_g, "datatype_stats failed");
764                 break;
765 
766             case H5O_TYPE_UNKNOWN:
767             case H5O_TYPE_NTYPES:
768             default:
769                 /* Gather statistics about this type of object */
770                 iter->uniq_others++;
771                 break;
772         } /* end switch */
773     } /* end if */
774 
775 done:
776     return ret_value;
777 } /* end obj_stats() */
778 
779 
780 /*-------------------------------------------------------------------------
781  * Function: lnk_stats
782  *
783  * Purpose: Gather statistics about a link
784  *
785  * Return:  Success: 0
786  *          Failure: -1
787  *
788  * Programmer: Quincey Koziol
789  *             Tuesday, November 6, 2007
790  *
791  *-------------------------------------------------------------------------
792  */
793 static herr_t
lnk_stats(const char H5_ATTR_UNUSED * path,const H5L_info_t * li,void * _iter)794 lnk_stats(const char H5_ATTR_UNUSED *path, const H5L_info_t *li, void *_iter)
795 {
796     iter_t *iter = (iter_t *)_iter;
797 
798     switch(li->type) {
799         case H5L_TYPE_SOFT:
800         case H5L_TYPE_EXTERNAL:
801             /* Gather statistics about links and UD links */
802             iter->uniq_links++;
803             break;
804 
805         case H5L_TYPE_HARD:
806         case H5L_TYPE_MAX:
807         case H5L_TYPE_ERROR:
808         default:
809             /* Gather statistics about this type of object */
810             iter->uniq_others++;
811             break;
812     } /* end switch() */
813 
814     return 0;
815 } /* end lnk_stats() */
816 
817 /*-------------------------------------------------------------------------
818  * Function: freespace_stats
819  *
820  * Purpose: Gather statistics for free space sections in the file
821  *
822  * Return: Success: 0
823  *       Failure: -1
824  *
825  * Programmer:  Vailin Choi; July 7th, 2009
826  *
827  *-------------------------------------------------------------------------
828  */
829 static herr_t
freespace_stats(hid_t fid,iter_t * iter)830 freespace_stats(hid_t fid, iter_t *iter)
831 {
832     H5F_sect_info_t *sect_info = NULL;    /* Free space sections */
833     ssize_t   nsects;                   /* Number of free space sections */
834     size_t   u;                        /* Local index variable */
835 
836     /* Query section information */
837     if((nsects = H5Fget_free_sections(fid, H5FD_MEM_DEFAULT, 0, NULL)) < 0)
838         return(FAIL);
839     else if(nsects) {
840         if(NULL == (sect_info = (H5F_sect_info_t *)HDcalloc((size_t)nsects, sizeof(H5F_sect_info_t))))
841             return(FAIL);
842         nsects = H5Fget_free_sections(fid, H5FD_MEM_DEFAULT, (size_t)nsects, sect_info);
843         HDassert(nsects);
844     } /* end else-if */
845 
846     for(u = 0; u < (size_t)nsects; u++) {
847         unsigned   bin;       /* "bin" the number of objects falls in */
848 
849         if(sect_info[u].size < SIZE_SMALL_SECTS)
850             (iter->num_small_sects[(size_t)sect_info[u].size])++;
851 
852         /* Add section size to proper bin */
853         bin = ceil_log10((unsigned long)sect_info[u].size);
854         if(bin >= iter->sect_nbins) {
855             /* Allocate more storage for section info */
856             iter->sect_bins = (unsigned long *)HDrealloc(iter->sect_bins, (bin + 1) * sizeof(unsigned long));
857             HDassert(iter->sect_bins);
858 
859             /* Initialize counts for intermediate bins */
860             while(iter->sect_nbins < bin)
861                 iter->sect_bins[iter->sect_nbins++] = 0;
862             iter->sect_nbins++;
863 
864             /* Initialize count for this bin */
865             iter->sect_bins[bin] = 1;
866         } /* end if */
867         else
868             (iter->sect_bins[bin])++;
869     } /* end for */
870 
871     if(sect_info)
872         HDfree(sect_info);
873 
874     return 0;
875 } /* end freespace_stats() */
876 
877 
878 /*-------------------------------------------------------------------------
879  * Function: hand_free
880  *
881  * Purpose: Free handler structure
882  *
883  * Return: Success: 0
884  *
885  * Failure: Never fails
886  *
887  *-------------------------------------------------------------------------
888  */
889 static void
hand_free(struct handler_t * hand)890 hand_free(struct handler_t *hand)
891 {
892     if(hand) {
893         unsigned u;
894 
895         for(u = 0; u < hand->obj_count; u++)
896             if(hand->obj[u]) {
897                 HDfree(hand->obj[u]);
898                 hand->obj[u] = NULL;
899             } /* end if */
900         hand->obj_count = 0;
901         HDfree(hand->obj);
902         HDfree(hand);
903     } /* end if */
904 } /* end hand_free() */
905 
906 
907 /*-------------------------------------------------------------------------
908  * Function: parse_command_line
909  *
910  * Purpose: Parses command line and sets up global variable to control output
911  *
912  * Return: Success: 0
913  *
914  * Failure: -1
915  *
916  * Programmer: Elena Pourmal
917  *             Saturday, August 12, 2006
918  *
919  *-------------------------------------------------------------------------
920  */
921 static int
parse_command_line(int argc,const char * argv[],struct handler_t ** hand_ret)922 parse_command_line(int argc, const char *argv[], struct handler_t **hand_ret)
923 {
924     int                opt;
925     unsigned           u;
926     struct handler_t   *hand = NULL;
927 
928     /* parse command line options */
929     while((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
930         switch((char)opt) {
931             case 'h':
932                 usage(h5tools_getprogname());
933                 h5tools_setstatus(EXIT_SUCCESS);
934                 goto done;
935                 break;
936 
937             case 'V':
938                 print_version(h5tools_getprogname());
939                 h5tools_setstatus(EXIT_SUCCESS);
940                 goto done;
941                 break;
942 
943             case 'E':
944                 enable_error_stack = 1;
945                 break;
946 
947             case 'F':
948                 display_all = FALSE;
949                 display_file_metadata = TRUE;
950                 break;
951 
952             case 'f':
953                 display_all = FALSE;
954                 display_file = TRUE;
955                 break;
956 
957             case 'G':
958                 display_all = FALSE;
959                 display_group_metadata = TRUE;
960                 break;
961 
962             case 'g':
963                 display_all = FALSE;
964                 display_group = TRUE;
965                 break;
966 
967             case 'l':
968                 if(opt_arg) {
969                     sgroups_threshold = HDatoi(opt_arg);
970                     if(sgroups_threshold < 1) {
971                         error_msg("Invalid threshold for small groups\n");
972                         goto error;
973                     }
974                 }
975                 else
976                     error_msg("Missing threshold for small groups\n");
977 
978                 break;
979 
980             case 'D':
981                 display_all = FALSE;
982                 display_dset_metadata = TRUE;
983                 break;
984 
985             case 'd':
986                 display_all = FALSE;
987                 display_dset = TRUE;
988                 break;
989 
990             case 'm':
991                 if(opt_arg) {
992                     sdsets_threshold = HDatoi(opt_arg);
993                     if(sdsets_threshold < 1) {
994                         error_msg("Invalid threshold for small datasets\n");
995                         goto error;
996                     }
997                 }
998                 else
999                     error_msg("Missing threshold for small datasets\n");
1000 
1001                 break;
1002 
1003             case 'T':
1004                 display_all = FALSE;
1005                 display_dset_dtype_meta = TRUE;
1006                 break;
1007 
1008             case 'A':
1009                 display_all = FALSE;
1010                 display_attr = TRUE;
1011                 break;
1012 
1013             case 'a':
1014                 if(opt_arg) {
1015                     sattrs_threshold = HDatoi(opt_arg);
1016                     if(sattrs_threshold < 1) {
1017                         error_msg("Invalid threshold for small # of attributes\n");
1018                         goto error;
1019                     }
1020                 }
1021                 else
1022                     error_msg("Missing threshold for small # of attributes\n");
1023 
1024                 break;
1025 
1026             case 's':
1027                 display_all = FALSE;
1028                 display_free_sections = TRUE;
1029                 break;
1030 
1031             case 'S':
1032                 display_all = FALSE;
1033                 display_summary = TRUE;
1034                 break;
1035 
1036             case 'O':
1037                 display_all = FALSE;
1038                 display_object = TRUE;
1039 
1040                 /* Allocate space to hold the command line info */
1041                 if(NULL == (hand = (struct handler_t *)HDcalloc((size_t)1, sizeof(struct handler_t)))) {
1042                     error_msg("unable to allocate memory for object struct\n");
1043                     goto error;
1044                 } /* end if */
1045 
1046                 /* Allocate space to hold the object strings */
1047                 hand->obj_count = (size_t)argc;
1048                 if(NULL == (hand->obj = (char **)HDcalloc((size_t)argc, sizeof(char *)))) {
1049                     error_msg("unable to allocate memory for object array\n");
1050                     goto error;
1051                 } /* end if */
1052 
1053                 /* Store object names */
1054                 for(u = 0; u < hand->obj_count; u++)
1055                     if(NULL == (hand->obj[u] = HDstrdup(opt_arg))) {
1056                         error_msg("unable to allocate memory for object name\n");
1057                         goto error;
1058                     } /* end if */
1059                 break;
1060 
1061             case 'w':
1062 #ifndef H5_HAVE_ROS3_VFD
1063                 error_msg("Read-Only S3 VFD not enabled.\n");
1064                 goto error;
1065 #else
1066                 {
1067                     char        *cred_str = NULL;
1068                     unsigned     nelems   = 0;
1069                     char       **cred     = NULL;
1070                     char const  *ccred[3];
1071 
1072                     if (FAIL == parse_tuple((const char *)opt_arg, ',', &cred_str, &nelems, &cred)) {
1073                         error_msg("Unable to parse s3 credential\n");
1074                         goto error;
1075                     }
1076                     if (nelems != 3) {
1077                         error_msg("s3 credential must have three elements\n");
1078                         goto error;
1079                     }
1080                     ccred[0] = (const char *)cred[0];
1081                     ccred[1] = (const char *)cred[1];
1082                     ccred[2] = (const char *)cred[2];
1083                     if (0 == h5tools_populate_ros3_fapl(&ros3_fa, ccred)) {
1084                         error_msg("Unable to set ros3 fapl config\n");
1085                         goto error;
1086                     }
1087                     HDfree(cred);
1088                     HDfree(cred_str);
1089                 } /* parse s3-cred block */
1090                 drivername = "ros3";
1091                 break;
1092 #endif /* H5_HAVE_ROS3_VFD */
1093 
1094             case 'H':
1095 #ifndef H5_HAVE_LIBHDFS
1096                 error_msg("HDFS VFD is not enabled.\n");
1097                 goto error;
1098 #else
1099                 {
1100                     unsigned         nelems    = 0;
1101                     char            *props_src = NULL;
1102                     char           **props     = NULL;
1103                     unsigned long    k         = 0;
1104                     if (FAIL == parse_tuple((const char *)opt_arg,
1105                             ',', &props_src, &nelems, &props)) {
1106                         error_msg("unable to parse hdfs properties tuple\n");
1107                         goto error;
1108                     }
1109                     /* sanity-check tuple count
1110                      */
1111                     if (nelems != 5) {
1112                         char str[64] = "";
1113                         HDsprintf(str,
1114                                 "expected 5 elements in hdfs properties tuple "
1115                                 "but found %u\n",
1116                                 nelems);
1117                         HDfree(props);
1118                         HDfree(props_src);
1119                         error_msg(str);
1120                         goto error;
1121                     }
1122                     /* Populate fapl configuration structure with given
1123                      * properties.
1124                      * TODO/WARNING: No error-checking is done on length of
1125                      *         input strings... Silent overflow is possible,
1126                      *         albeit unlikely.
1127                      */
1128                     if (HDstrncmp(props[0], "", 1)) {
1129                         HDstrncpy(hdfs_fa.namenode_name,(const char *)props[0], HDstrlen(props[0]));
1130                     }
1131                     if (HDstrncmp(props[1], "", 1)) {
1132                         k = strtoul((const char *)props[1], NULL, 0);
1133                         if (errno == ERANGE) {
1134                             error_msg("supposed port number wasn't.\n");
1135                             goto error;
1136                         }
1137                         hdfs_fa.namenode_port = (int32_t)k;
1138                     }
1139                     if (HDstrncmp(props[2], "", 1)) {
1140                         HDstrncpy(hdfs_fa.kerberos_ticket_cache, (const char *)props[2], HDstrlen(props[2]));
1141                     }
1142                     if (HDstrncmp(props[3], "", 1)) {
1143                         HDstrncpy(hdfs_fa.user_name, (const char *)props[3], HDstrlen(props[3]));
1144                     }
1145                     if (strncmp(props[4], "", 1)) {
1146                         k = HDstrtoul((const char *)props[4], NULL, 0);
1147                         if (errno == ERANGE) {
1148                             error_msg("supposed buffersize number wasn't.\n");
1149                             goto error;
1150                         }
1151                         hdfs_fa.stream_buffer_size = (int32_t)k;
1152                     }
1153                     HDfree(props);
1154                     HDfree(props_src);
1155                     drivername = "hdfs";
1156                 }
1157                 break;
1158 #endif /* H5_HAVE_LIBHDFS */
1159 
1160             default:
1161                 usage(h5tools_getprogname());
1162                 goto error;
1163         } /* end switch */
1164     } /* end while */
1165 
1166     /* check for file name to be processed */
1167     if(argc <= opt_ind) {
1168         error_msg("missing file name\n");
1169         usage(h5tools_getprogname());
1170         goto error;
1171     } /* end if */
1172 
1173     /* Set handler structure */
1174     *hand_ret = hand;
1175 
1176 done:
1177     return 0;
1178 
1179 error:
1180     hand_free(hand);
1181     h5tools_setstatus(EXIT_FAILURE);
1182 
1183     return -1;
1184 }
1185 
1186 
1187 /*-------------------------------------------------------------------------
1188  * Function: iter_free
1189  *
1190  * Purpose: Free iter structure
1191  *
1192  * Return: Success: 0
1193  *
1194  * Failure: Never fails
1195  *
1196  *-------------------------------------------------------------------------
1197  */
1198 static void
iter_free(iter_t * iter)1199 iter_free(iter_t *iter)
1200 {
1201 
1202     /* Clear array of bins for group counts */
1203     if(iter->group_bins) {
1204         HDfree(iter->group_bins);
1205         iter->group_bins = NULL;
1206     } /* end if */
1207 
1208     /* Clear array for tracking small groups */
1209     if(iter->num_small_groups) {
1210         HDfree(iter->num_small_groups);
1211         iter->num_small_groups = NULL;
1212     } /* end if */
1213 
1214     /* Clear array of bins for attribute counts */
1215     if(iter->attr_bins) {
1216         HDfree(iter->attr_bins);
1217         iter->attr_bins = NULL;
1218     } /* end if */
1219 
1220     /* Clear array for tracking small attributes */
1221     if(iter->num_small_attrs) {
1222         HDfree(iter->num_small_attrs);
1223         iter->num_small_attrs= NULL;
1224     } /* end if */
1225 
1226     /* Clear dataset datatype information found */
1227     if(iter->dset_type_info) {
1228         HDfree(iter->dset_type_info);
1229         iter->dset_type_info = NULL;
1230     } /* end if */
1231 
1232     /* Clear array of bins for dataset dimensions */
1233     if(iter->dset_dim_bins) {
1234         HDfree(iter->dset_dim_bins);
1235         iter->dset_dim_bins = NULL;
1236     } /* end if */
1237 
1238     /* Clear array of tracking 1-D small datasets */
1239     if(iter->small_dset_dims) {
1240         HDfree(iter->small_dset_dims);
1241         iter->small_dset_dims = NULL;
1242     } /* end if */
1243 
1244     /* Clear array of bins for free-space section sizes */
1245     if(iter->sect_bins) {
1246         HDfree(iter->sect_bins);
1247         iter->sect_bins = NULL;
1248     } /* end if */
1249 } /* end iter_free() */
1250 
1251 
1252 /*-------------------------------------------------------------------------
1253  * Function: print_file_info
1254  *
1255  * Purpose: Prints information about file
1256  *
1257  * Return: Success: 0
1258  *
1259  * Failure: Never fails
1260  *
1261  * Programmer: Elena Pourmal
1262  *             Saturday, August 12, 2006
1263  *
1264  * Modifications:
1265  *
1266  *-------------------------------------------------------------------------
1267  */
1268 static herr_t
print_file_info(const iter_t * iter)1269 print_file_info(const iter_t *iter)
1270 {
1271     HDprintf("File information\n");
1272     HDprintf("\t# of unique groups: %lu\n", iter->uniq_groups);
1273     HDprintf("\t# of unique datasets: %lu\n", iter->uniq_dsets);
1274     HDprintf("\t# of unique named datatypes: %lu\n", iter->uniq_dtypes);
1275     HDprintf("\t# of unique links: %lu\n", iter->uniq_links);
1276     HDprintf("\t# of unique other: %lu\n", iter->uniq_others);
1277     HDprintf("\tMax. # of links to object: %lu\n", iter->max_links);
1278     HDfprintf(stdout, "\tMax. # of objects in group: %Hu\n", iter->max_fanout);
1279 
1280     return 0;
1281 } /* print_file_info() */
1282 
1283 
1284 /*-------------------------------------------------------------------------
1285  * Function: print_file_metadata
1286  *
1287  * Purpose: Prints file space information for file's metadata
1288  *
1289  * Return: Success: 0
1290  *
1291  * Failure: Never fails
1292  *
1293  * Programmer: Elena Pourmal
1294  *             Saturday, August 12, 2006
1295  *
1296  *-------------------------------------------------------------------------
1297  */
1298 static herr_t
print_file_metadata(const iter_t * iter)1299 print_file_metadata(const iter_t *iter)
1300 {
1301     HDfprintf(stdout, "File space information for file metadata (in bytes):\n");
1302     HDfprintf(stdout, "\tSuperblock: %Hu\n", iter->super_size);
1303     HDfprintf(stdout, "\tSuperblock extension: %Hu\n", iter->super_ext_size);
1304     HDfprintf(stdout, "\tUser block: %Hu\n", iter->ublk_size);
1305 
1306     HDfprintf(stdout, "\tObject headers: (total/unused)\n");
1307     HDfprintf(stdout, "\t\tGroups: %Hu/%Hu\n", iter->group_ohdr_info.total_size,
1308             iter->group_ohdr_info.free_size);
1309     HDfprintf(stdout, "\t\tDatasets(exclude compact data): %Hu/%Hu\n",
1310             iter->dset_ohdr_info.total_size, iter->dset_ohdr_info.free_size);
1311     HDfprintf(stdout, "\t\tDatatypes: %Hu/%Hu\n", iter->dtype_ohdr_info.total_size,
1312             iter->dtype_ohdr_info.free_size);
1313 
1314     HDfprintf(stdout, "\tGroups:\n");
1315     HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->groups_btree_storage_size);
1316     HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->groups_heap_storage_size);
1317 
1318     HDfprintf(stdout, "\tAttributes:\n");
1319     HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->attrs_btree_storage_size);
1320     HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->attrs_heap_storage_size);
1321 
1322     HDfprintf(stdout, "\tChunked datasets:\n");
1323     HDfprintf(stdout, "\t\tIndex: %Hu\n", iter->datasets_index_storage_size);
1324 
1325     HDfprintf(stdout, "\tDatasets:\n");
1326     HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->datasets_heap_storage_size);
1327 
1328     HDfprintf(stdout, "\tShared Messages:\n");
1329     HDfprintf(stdout, "\t\tHeader: %Hu\n", iter->SM_hdr_storage_size);
1330     HDfprintf(stdout, "\t\tB-tree/List: %Hu\n", iter->SM_index_storage_size);
1331     HDfprintf(stdout, "\t\tHeap: %Hu\n", iter->SM_heap_storage_size);
1332 
1333     HDfprintf(stdout, "\tFree-space managers:\n");
1334     HDfprintf(stdout, "\t\tHeader: %Hu\n", iter->free_hdr);
1335     HDfprintf(stdout, "\t\tAmount of free space: %Hu\n", iter->free_space);
1336 
1337     return 0;
1338 } /* print_file_metadata() */
1339 
1340 
1341 /*-------------------------------------------------------------------------
1342  * Function: print_group_info
1343  *
1344  * Purpose: Prints information about groups in the file
1345  *
1346  * Return: Success: 0
1347  *
1348  * Failure: Never fails
1349  *
1350  * Programmer: Elena Pourmal
1351  *             Saturday, August 12, 2006
1352  *
1353  * Modifications:
1354  *  bug #1253; Oct 6th 2008; Vailin Choi
1355  *  Fixed segmentation fault: print iter->group_bins[0] when
1356  *  there is iter->group_nbins
1357  *
1358  *-------------------------------------------------------------------------
1359  */
1360 static herr_t
print_group_info(const iter_t * iter)1361 print_group_info(const iter_t *iter)
1362 {
1363     unsigned long power;        /* Temporary "power" for bins */
1364     unsigned long total;        /* Total count for various statistics */
1365     unsigned u;                 /* Local index variable */
1366 
1367     HDprintf("Small groups (with 0 to %u links):\n", sgroups_threshold-1);
1368     total = 0;
1369     for(u = 0; u < (unsigned)sgroups_threshold; u++) {
1370         if(iter->num_small_groups[u] > 0) {
1371             HDprintf("\t# of groups with %u link(s): %lu\n", u, iter->num_small_groups[u]);
1372             total += iter->num_small_groups[u];
1373         } /* end if */
1374     } /* end for */
1375     HDprintf("\tTotal # of small groups: %lu\n", total);
1376 
1377     HDprintf("Group bins:\n");
1378     total = 0;
1379     if((iter->group_nbins > 0) && (iter->group_bins[0] > 0)) {
1380        HDprintf("\t# of groups with 0 link: %lu\n", iter->group_bins[0]);
1381        total = iter->group_bins[0];
1382     } /* end if */
1383     power = 1;
1384     for(u = 1; u < iter->group_nbins; u++) {
1385         if(iter->group_bins[u] > 0) {
1386            HDprintf("\t# of groups with %lu - %lu links: %lu\n", power, (power * 10) - 1,
1387                     iter->group_bins[u]);
1388            total += iter->group_bins[u];
1389         } /* end if */
1390         power *= 10;
1391     } /* end for */
1392     HDprintf("\tTotal # of groups: %lu\n", total);
1393 
1394     return 0;
1395 } /* print_group_info() */
1396 
1397 
1398 /*-------------------------------------------------------------------------
1399  * Function: print_group_metadata
1400  *
1401  * Purpose: Prints file space information for groups' metadata
1402  *
1403  * Return:  Success: 0
1404  *          Failure: Never fails
1405  *
1406  * Programmer: Vailin Choi; October 2009
1407  *
1408  *-------------------------------------------------------------------------
1409  */
1410 static herr_t
print_group_metadata(const iter_t * iter)1411 print_group_metadata(const iter_t *iter)
1412 {
1413     HDprintf("File space information for groups' metadata (in bytes):\n");
1414 
1415     HDfprintf(stdout, "\tObject headers (total/unused): %Hu/%Hu\n",
1416             iter->group_ohdr_info.total_size, iter->group_ohdr_info.free_size);
1417 
1418     HDfprintf(stdout, "\tB-tree/List: %Hu\n", iter->groups_btree_storage_size);
1419     HDfprintf(stdout, "\tHeap: %Hu\n", iter->groups_heap_storage_size);
1420 
1421     return 0;
1422 } /* print_group_metadata() */
1423 
1424 
1425 /*-------------------------------------------------------------------------
1426  * Function: print_dataset_info
1427  *
1428  * Purpose: Prints information about datasets in the file
1429  *
1430  * Return:  Success: 0
1431  *          Failure: Never fails
1432  *
1433  * Programmer: Elena Pourmal
1434  *             Saturday, August 12, 2006
1435  *
1436  *-------------------------------------------------------------------------
1437  */
1438 static herr_t
print_dataset_info(const iter_t * iter)1439 print_dataset_info(const iter_t *iter)
1440 {
1441     unsigned long power;        /* Temporary "power" for bins */
1442     unsigned long total;        /* Total count for various statistics */
1443     unsigned u;                 /* Local index variable */
1444 
1445     if(iter->uniq_dsets > 0) {
1446         HDprintf("Dataset dimension information:\n");
1447         HDprintf("\tMax. rank of datasets: %u\n", iter->max_dset_rank);
1448         HDprintf("\tDataset ranks:\n");
1449         for(u = 0; u < H5S_MAX_RANK; u++)
1450             if(iter->dset_rank_count[u] > 0)
1451                 HDprintf("\t\t# of dataset with rank %u: %lu\n", u, iter->dset_rank_count[u]);
1452 
1453         HDprintf("1-D Dataset information:\n");
1454         HDfprintf(stdout, "\tMax. dimension size of 1-D datasets: %Hu\n", iter->max_dset_dims);
1455         HDprintf("\tSmall 1-D datasets (with dimension sizes 0 to %u):\n", sdsets_threshold - 1);
1456         total = 0;
1457         for(u = 0; u < (unsigned)sdsets_threshold; u++) {
1458             if(iter->small_dset_dims[u] > 0) {
1459                 HDprintf("\t\t# of datasets with dimension sizes %u: %lu\n", u,
1460                          iter->small_dset_dims[u]);
1461                 total += iter->small_dset_dims[u];
1462             } /* end if */
1463         } /* end for */
1464         HDprintf("\t\tTotal # of small datasets: %lu\n", total);
1465 
1466         /* Protect against no datasets in file */
1467         if(iter->dset_dim_nbins > 0) {
1468             HDprintf("\t1-D Dataset dimension bins:\n");
1469             total = 0;
1470             if(iter->dset_dim_bins[0] > 0) {
1471                 HDprintf("\t\t# of datasets with dimension size 0: %lu\n", iter->dset_dim_bins[0]);
1472                 total = iter->dset_dim_bins[0];
1473             } /* end if */
1474             power = 1;
1475             for(u = 1; u < iter->dset_dim_nbins; u++) {
1476                 if(iter->dset_dim_bins[u] > 0) {
1477                     HDprintf("\t\t# of datasets with dimension size %lu - %lu: %lu\n", power, (power * 10) - 1,
1478                              iter->dset_dim_bins[u]);
1479                     total += iter->dset_dim_bins[u];
1480                 } /* end if */
1481                 power *= 10;
1482             } /* end for */
1483             HDprintf("\t\tTotal # of datasets: %lu\n", total);
1484         } /* end if */
1485 
1486         HDprintf("Dataset storage information:\n");
1487         HDfprintf(stdout, "\tTotal raw data size: %Hu\n", iter->dset_storage_size);
1488         HDfprintf(stdout, "\tTotal external raw data size: %Hu\n", iter->dset_external_storage_size);
1489 
1490         HDprintf("Dataset layout information:\n");
1491         for(u = 0; u < H5D_NLAYOUTS; u++)
1492             HDprintf("\tDataset layout counts[%s]: %lu\n", (u == H5D_COMPACT ? "COMPACT" :
1493                 (u == H5D_CONTIGUOUS ? "CONTIG" : (u == H5D_CHUNKED ? "CHUNKED" : "VIRTUAL"))), iter->dset_layouts[u]);
1494         HDprintf("\tNumber of external files : %lu\n", iter->nexternal);
1495 
1496         HDprintf("Dataset filters information:\n");
1497         HDprintf("\tNumber of datasets with:\n");
1498         HDprintf("\t\tNO filter: %lu\n", iter->dset_comptype[H5Z_FILTER_ERROR+1]);
1499         HDprintf("\t\tGZIP filter: %lu\n", iter->dset_comptype[H5Z_FILTER_DEFLATE]);
1500         HDprintf("\t\tSHUFFLE filter: %lu\n", iter->dset_comptype[H5Z_FILTER_SHUFFLE]);
1501         HDprintf("\t\tFLETCHER32 filter: %lu\n", iter->dset_comptype[H5Z_FILTER_FLETCHER32]);
1502         HDprintf("\t\tSZIP filter: %lu\n", iter->dset_comptype[H5Z_FILTER_SZIP]);
1503         HDprintf("\t\tNBIT filter: %lu\n", iter->dset_comptype[H5Z_FILTER_NBIT]);
1504         HDprintf("\t\tSCALEOFFSET filter: %lu\n", iter->dset_comptype[H5Z_FILTER_SCALEOFFSET]);
1505         HDprintf("\t\tUSER-DEFINED filter: %lu\n", iter->dset_comptype[H5_NFILTERS_IMPL-1]);
1506     } /* end if */
1507 
1508     return 0;
1509 } /* print_dataset_info() */
1510 
1511 
1512 /*-------------------------------------------------------------------------
1513  * Function: print_dataset_metadata
1514  *
1515  * Purpose: Prints file space information for datasets' metadata
1516  *
1517  * Return: Success: 0
1518  *
1519  * Failure: Never fails
1520  *
1521  * Programmer:  Vailin Choi; October 2009
1522  *
1523  *-------------------------------------------------------------------------
1524  */
1525 static herr_t
print_dset_metadata(const iter_t * iter)1526 print_dset_metadata(const iter_t *iter)
1527 {
1528     HDprintf("File space information for datasets' metadata (in bytes):\n");
1529 
1530     HDfprintf(stdout, "\tObject headers (total/unused): %Hu/%Hu\n",
1531             iter->dset_ohdr_info.total_size, iter->dset_ohdr_info.free_size);
1532 
1533     HDfprintf(stdout, "\tIndex for Chunked datasets: %Hu\n",
1534             iter->datasets_index_storage_size);
1535     HDfprintf(stdout, "\tHeap: %Hu\n", iter->datasets_heap_storage_size);
1536 
1537     return 0;
1538 } /* print_dset_metadata() */
1539 
1540 
1541 /*-------------------------------------------------------------------------
1542  * Function: print_dset_dtype_meta
1543  *
1544  * Purpose: Prints datasets' datatype information
1545  *
1546  * Return: Success: 0
1547  *
1548  * Failure: Never fails
1549  *
1550  * Programmer: Vailin Choi; October 2009
1551  *
1552  *-------------------------------------------------------------------------
1553  */
1554 static herr_t
print_dset_dtype_meta(const iter_t * iter)1555 print_dset_dtype_meta(const iter_t *iter)
1556 {
1557     unsigned long total;        /* Total count for various statistics */
1558     size_t   dtype_size;        /* Size of encoded datatype */
1559     unsigned u;                 /* Local index variable */
1560 
1561     if(iter->dset_ntypes) {
1562         HDprintf("Dataset datatype information:\n");
1563         HDprintf("\t# of unique datatypes used by datasets: %lu\n", iter->dset_ntypes);
1564         total = 0;
1565         for(u = 0; u < iter->dset_ntypes; u++) {
1566             H5Tencode(iter->dset_type_info[u].tid, NULL, &dtype_size);
1567             HDprintf("\tDataset datatype #%u:\n", u);
1568             HDprintf("\t\tCount (total/named) = (%lu/%lu)\n",
1569                     iter->dset_type_info[u].count, iter->dset_type_info[u].named);
1570             HDprintf("\t\tSize (desc./elmt) = (%lu/%lu)\n", (unsigned long)dtype_size,
1571                     (unsigned long)H5Tget_size(iter->dset_type_info[u].tid));
1572             H5Tclose(iter->dset_type_info[u].tid);
1573             total += iter->dset_type_info[u].count;
1574         } /* end for */
1575         HDprintf("\tTotal dataset datatype count: %lu\n", total);
1576     } /* end if */
1577 
1578     return 0;
1579 } /* print_dset_dtype_meta() */
1580 
1581 
1582 /*-------------------------------------------------------------------------
1583  * Function: print_attr_info
1584  *
1585  * Purpose: Prints information about attributes in the file
1586  *
1587  * Return: Success: 0
1588  *
1589  * Failure: Never fails
1590  *
1591  * Programmer: Vailin Choi
1592  *             July 12, 2007
1593  *
1594  *-------------------------------------------------------------------------
1595  */
1596 static herr_t
print_attr_info(const iter_t * iter)1597 print_attr_info(const iter_t *iter)
1598 {
1599     unsigned long power;        /* Temporary "power" for bins */
1600     unsigned long total;        /* Total count for various statistics */
1601     unsigned u;                 /* Local index variable */
1602 
1603     HDprintf("Small # of attributes (objects with 1 to %u attributes):\n", sattrs_threshold);
1604     total = 0;
1605     for(u = 1; u <= (unsigned)sattrs_threshold; u++) {
1606         if(iter->num_small_attrs[u] > 0) {
1607             HDprintf("\t# of objects with %u attributes: %lu\n", u, iter->num_small_attrs[u]);
1608             total += iter->num_small_attrs[u];
1609         } /* end if */
1610     } /* end for */
1611     HDprintf("\tTotal # of objects with small # of attributes: %lu\n", total);
1612 
1613     HDprintf("Attribute bins:\n");
1614     total = 0;
1615     power = 1;
1616     for(u = 1; u < iter->attr_nbins; u++) {
1617         if(iter->attr_bins[u] > 0) {
1618            HDprintf("\t# of objects with %lu - %lu attributes: %lu\n", power, (power * 10) - 1,
1619                     iter->attr_bins[u]);
1620            total += iter->attr_bins[u];
1621         } /* end if */
1622         power *= 10;
1623     } /* end for */
1624     HDprintf("\tTotal # of objects with attributes: %lu\n", total);
1625     HDprintf("\tMax. # of attributes to objects: %lu\n", (unsigned long)iter->max_attrs);
1626 
1627     return 0;
1628 } /* print_attr_info() */
1629 
1630 
1631 /*-------------------------------------------------------------------------
1632  * Function: print_freespace_info
1633  *
1634  * Purpose: Prints information about free space in the file
1635  *
1636  * Return: Success: 0
1637  *
1638  * Failure: Never fails
1639  *
1640  * Programmer: Vailin Choi; July 7th, 2009
1641  *
1642  *-------------------------------------------------------------------------
1643  */
1644 static herr_t
print_freespace_info(const iter_t * iter)1645 print_freespace_info(const iter_t *iter)
1646 {
1647     unsigned long power;        /* Temporary "power" for bins */
1648     unsigned long total;        /* Total count for various statistics */
1649     unsigned u;                 /* Local index variable */
1650 
1651     HDfprintf(stdout, "Free-space persist: %s\n", iter->fs_persist ? "TRUE" : "FALSE");
1652     HDfprintf(stdout, "Free-space section threshold: %Hu bytes\n", iter->fs_threshold);
1653     HDprintf("Small size free-space sections (< %u bytes):\n", (unsigned)SIZE_SMALL_SECTS);
1654     total = 0;
1655     for(u = 0; u < SIZE_SMALL_SECTS; u++) {
1656         if(iter->num_small_sects[u] > 0) {
1657             HDprintf("\t# of sections of size %u: %lu\n", u, iter->num_small_sects[u]);
1658             total += iter->num_small_sects[u];
1659         } /* end if */
1660     } /* end for */
1661     HDprintf("\tTotal # of small size sections: %lu\n", total);
1662 
1663     HDprintf("Free-space section bins:\n");
1664 
1665     total = 0;
1666     power = 1;
1667     for(u = 1; u < iter->sect_nbins; u++) {
1668         if(iter->sect_bins[u] > 0) {
1669            HDprintf("\t# of sections of size %lu - %lu: %lu\n", power, (power * 10) - 1,
1670                     iter->sect_bins[u]);
1671            total += iter->sect_bins[u];
1672         } /* end if */
1673         power *= 10;
1674     } /* end for */
1675     HDprintf("\tTotal # of sections: %lu\n", total);
1676 
1677     return 0;
1678 } /* print_freespace_info() */
1679 
1680 
1681 /*-------------------------------------------------------------------------
1682  * Function: print_storage_summary
1683  *
1684  * Purpose: Prints file space information for the file
1685  *
1686  * Return: Success: 0
1687  *
1688  * Failure: Never fails
1689  *
1690  * Programmer: Vailin Choi; August 2009
1691  *
1692  *-------------------------------------------------------------------------
1693  */
1694 static herr_t
print_storage_summary(const iter_t * iter)1695 print_storage_summary(const iter_t *iter)
1696 {
1697     hsize_t total_meta = 0;
1698     hsize_t unaccount = 0;
1699     double  percent = 0.0f;
1700 
1701     HDfprintf(stdout, "File space management strategy: %s\n", FS_STRATEGY_NAME[iter->fs_strategy]);
1702     HDfprintf(stdout, "File space page size: %Hu bytes\n", iter->fsp_size);
1703     HDprintf("Summary of file space information:\n");
1704     total_meta =
1705             iter->super_size + iter->super_ext_size + iter->ublk_size +
1706             iter->group_ohdr_info.total_size +
1707             iter->dset_ohdr_info.total_size +
1708             iter->dtype_ohdr_info.total_size +
1709             iter->groups_btree_storage_size +
1710             iter->groups_heap_storage_size +
1711             iter->attrs_btree_storage_size +
1712             iter->attrs_heap_storage_size +
1713             iter->datasets_index_storage_size +
1714             iter->datasets_heap_storage_size +
1715             iter->SM_hdr_storage_size +
1716             iter->SM_index_storage_size +
1717             iter->SM_heap_storage_size +
1718             iter->free_hdr;
1719 
1720     HDfprintf(stdout, "  File metadata: %Hu bytes\n", total_meta);
1721     HDfprintf(stdout, "  Raw data: %Hu bytes\n", iter->dset_storage_size);
1722 
1723     percent = ((double)iter->free_space / (double)iter->filesize) * (double)100.0f;
1724     HDfprintf(stdout, "  Amount/Percent of tracked free space: %Hu bytes/%3.1f%\n",
1725                 iter->free_space, percent);
1726 
1727     if(iter->filesize < (total_meta + iter->dset_storage_size + iter->free_space)) {
1728         unaccount = (total_meta + iter->dset_storage_size + iter->free_space) - iter->filesize;
1729         HDfprintf(stdout, "  ??? File has %Hu more bytes accounted for than its size! ???\n", unaccount);
1730     }
1731     else {
1732         unaccount = iter->filesize - (total_meta + iter->dset_storage_size + iter->free_space);
1733         HDfprintf(stdout, "  Unaccounted space: %Hu bytes\n", unaccount);
1734     }
1735 
1736     HDfprintf(stdout, "Total space: %Hu bytes\n", total_meta + iter->dset_storage_size + iter->free_space + unaccount);
1737 
1738     if(iter->nexternal)
1739         HDfprintf(stdout, "External raw data: %Hu bytes\n", iter->dset_external_storage_size);
1740 
1741     return 0;
1742 } /* print_storage_summary() */
1743 
1744 
1745 /*-------------------------------------------------------------------------
1746  * Function: print_file_statistics
1747  *
1748  * Purpose: Prints file statistics
1749  *
1750  * Return: Success: 0
1751  *
1752  * Failure: Never fails
1753  *
1754  * Programmer: Elena Pourmal
1755  *             Saturday, August 12, 2006
1756  *
1757  *-------------------------------------------------------------------------
1758  */
1759 static void
print_file_statistics(const iter_t * iter)1760 print_file_statistics(const iter_t *iter)
1761 {
1762     if(display_all) {
1763         display_file = TRUE;
1764         display_group = TRUE;
1765         display_dset = TRUE;
1766         display_dset_dtype_meta = TRUE;
1767         display_attr = TRUE;
1768         display_free_sections = TRUE;
1769         display_summary = TRUE;
1770 
1771         display_file_metadata = TRUE;
1772         display_group_metadata = TRUE;
1773         display_dset_metadata = TRUE;
1774     }
1775 
1776     if(display_file)            print_file_info(iter);
1777     if(display_file_metadata)   print_file_metadata(iter);
1778 
1779     if(display_group)           print_group_info(iter);
1780     if(!display_all && display_group_metadata)   print_group_metadata(iter);
1781 
1782     if(display_dset)            print_dataset_info(iter);
1783     if(display_dset_dtype_meta) print_dset_dtype_meta(iter);
1784     if(!display_all && display_dset_metadata)   print_dset_metadata(iter);
1785 
1786     if(display_attr)            print_attr_info(iter);
1787     if(display_free_sections)   print_freespace_info(iter);
1788     if(display_summary)         print_storage_summary(iter);
1789 } /* print_file_statistics() */
1790 
1791 
1792 /*-------------------------------------------------------------------------
1793  * Function: print_object_statistics
1794  *
1795  * Purpose: Prints object statistics
1796  *
1797  * Return: Success: 0
1798  *
1799  * Failure: Never fails
1800  *
1801  * Programmer: Elena Pourmal
1802  *             Thursday, August 17, 2006
1803  *
1804  * Modifications:
1805  *
1806  *-------------------------------------------------------------------------
1807  */
1808 static void
print_object_statistics(const char * name)1809 print_object_statistics(const char *name)
1810 {
1811     HDprintf("Object name %s\n", name);
1812 } /* print_object_statistics() */
1813 
1814 
1815 /*-------------------------------------------------------------------------
1816  * Function: print_statistics
1817  *
1818  * Purpose: Prints statistics
1819  *
1820  * Return: Success: 0
1821  *
1822  * Failure: Never fails
1823  *
1824  * Programmer: Elena Pourmal
1825  *             Thursday, August 17, 2006
1826  *
1827  * Modifications:
1828  *
1829  *-------------------------------------------------------------------------
1830  */
1831 static void
print_statistics(const char * name,const iter_t * iter)1832 print_statistics(const char *name, const iter_t *iter)
1833 {
1834     if(display_object)
1835         print_object_statistics(name);
1836     else
1837         print_file_statistics(iter);
1838 } /* print_statistics() */
1839 
1840 
1841 /*-------------------------------------------------------------------------
1842  * Function: main
1843  *
1844  * Modifications:
1845  *      2/2010; Vailin Choi
1846  *      Get the size of user block
1847  *
1848  *-------------------------------------------------------------------------
1849  */
1850 int
main(int argc,const char * argv[])1851 main(int argc, const char *argv[])
1852 {
1853     iter_t              iter;
1854     const char         *fname = NULL;
1855     hid_t               fid = -1;
1856     H5E_auto2_t         func;
1857     H5E_auto2_t         tools_func;
1858     void               *edata;
1859     void               *tools_edata;
1860     struct handler_t   *hand = NULL;
1861     hid_t               fapl_id = H5P_DEFAULT;
1862 
1863     h5tools_setprogname(PROGRAMNAME);
1864     h5tools_setstatus(EXIT_SUCCESS);
1865 
1866     /* Disable error reporting */
1867     H5Eget_auto2(H5E_DEFAULT, &func, &edata);
1868     H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
1869 
1870     /* Initialize h5tools lib */
1871     h5tools_init();
1872 
1873     /* Disable tools error reporting */
1874     H5Eget_auto2(H5tools_ERR_STACK_g, &tools_func, &tools_edata);
1875     H5Eset_auto2(H5tools_ERR_STACK_g, NULL, NULL);
1876 
1877     HDmemset(&iter, 0, sizeof(iter));
1878 
1879     if(parse_command_line(argc, argv, &hand) < 0)
1880         goto done;
1881 
1882     /* if drivername is not null, probably need to set the fapl */
1883     if (HDstrcmp(drivername, "")) {
1884         void *conf_fa = NULL;
1885 
1886         if (!HDstrcmp(drivername, "ros3")) {
1887 #ifndef H5_HAVE_ROS3_VFD
1888             error_msg("Read-Only S3 VFD not enabled.\n\n");
1889             goto done;
1890 #else
1891             conf_fa = (void *)&ros3_fa;
1892 #endif /* H5_HAVE_ROS3_VFD */
1893 
1894         }
1895         else if (!HDstrcmp(drivername, "hdfs")) {
1896 #ifndef H5_HAVE_LIBHDFS
1897             error_msg("HDFS VFD not enabled.\n\n");
1898             goto done;
1899 #else
1900             conf_fa = (void *)&hdfs_fa;
1901 #endif /* H5_HAVE_LIBHDFS */
1902         }
1903 
1904         if (conf_fa != NULL) {
1905             HDassert(fapl_id == H5P_DEFAULT);
1906             fapl_id = H5Pcreate(H5P_FILE_ACCESS);
1907             if (fapl_id < 0) {
1908                 error_msg("Unable to create fapl entry\n");
1909                 goto done;
1910             }
1911             if (1 > h5tools_set_configured_fapl(fapl_id, drivername, conf_fa)) {
1912                 error_msg("Unable to set fapl\n");
1913                 goto done;
1914             }
1915         }
1916     } /* drivername set */
1917 
1918     fname = argv[opt_ind];
1919 
1920     if(enable_error_stack > 0) {
1921         H5Eset_auto2(H5E_DEFAULT, func, edata);
1922         H5Eset_auto2(H5tools_ERR_STACK_g, tools_func, tools_edata);
1923     }
1924 
1925     /* Check for filename given */
1926     if(fname) {
1927         hid_t               fcpl;
1928         H5F_info2_t         finfo;
1929 
1930         HDprintf("Filename: %s\n", fname);
1931 
1932         fid = H5Fopen(fname, H5F_ACC_RDONLY, fapl_id);
1933         if(fid < 0) {
1934             error_msg("unable to open file \"%s\"\n", fname);
1935             h5tools_setstatus(EXIT_FAILURE);
1936             goto done;
1937         } /* end if */
1938 
1939         /* Initialize iter structure */
1940         iter.fid = fid;
1941 
1942         if(H5Fget_filesize(fid, &iter.filesize) < 0)
1943             warn_msg("Unable to retrieve file size\n");
1944         HDassert(iter.filesize != 0);
1945 
1946         /* Get storge info for file-level structures */
1947         if(H5Fget_info2(fid, &finfo) < 0)
1948             warn_msg("Unable to retrieve file info\n");
1949         else {
1950             iter.super_size = finfo.super.super_size;
1951             iter.super_ext_size = finfo.super.super_ext_size;
1952             iter.SM_hdr_storage_size = finfo.sohm.hdr_size;
1953             iter.SM_index_storage_size = finfo.sohm.msgs_info.index_size;
1954             iter.SM_heap_storage_size = finfo.sohm.msgs_info.heap_size;
1955             iter.free_space = finfo.free.tot_space;
1956             iter.free_hdr = finfo.free.meta_size;
1957         } /* end else */
1958 
1959         iter.num_small_groups = (unsigned long *)HDcalloc((size_t)sgroups_threshold, sizeof(unsigned long));
1960         iter.num_small_attrs = (unsigned long *)HDcalloc((size_t)(sattrs_threshold+1), sizeof(unsigned long));
1961         iter.small_dset_dims = (unsigned long *)HDcalloc((size_t)sdsets_threshold, sizeof(unsigned long));
1962 
1963         if(iter.num_small_groups == NULL || iter.num_small_attrs == NULL || iter.small_dset_dims == NULL) {
1964             error_msg("Unable to allocate memory for tracking small groups/datasets/attributes\n");
1965             h5tools_setstatus(EXIT_FAILURE);
1966             goto done;
1967         }
1968 
1969         if((fcpl = H5Fget_create_plist(fid)) < 0)
1970             warn_msg("Unable to retrieve file creation property\n");
1971 
1972         if(H5Pget_userblock(fcpl, &iter.ublk_size) < 0)
1973             warn_msg("Unable to retrieve userblock size\n");
1974 
1975         if(H5Pget_file_space_strategy(fcpl, &iter.fs_strategy, &iter.fs_persist, &iter.fs_threshold) < 0)
1976             warn_msg("Unable to retrieve file space information\n");
1977         HDassert(iter.fs_strategy >= 0 && iter.fs_strategy < H5F_FSPACE_STRATEGY_NTYPES);
1978 
1979         if(H5Pget_file_space_page_size(fcpl, &iter.fsp_size) < 0)
1980             warn_msg("Unable to retrieve file space page size\n");
1981 
1982         /* get information for free-space sections */
1983         if(freespace_stats(fid, &iter) < 0)
1984             warn_msg("Unable to retrieve freespace info\n");
1985 
1986         /* Walk the objects or all file */
1987         if(display_object) {
1988             unsigned u;
1989 
1990             for(u = 0; u < hand->obj_count; u++) {
1991                 if(h5trav_visit(fid, hand->obj[u], TRUE, TRUE, obj_stats, lnk_stats, &iter, H5O_INFO_ALL) < 0) {
1992                     error_msg("unable to traverse object \"%s\"\n", hand->obj[u]);
1993                     h5tools_setstatus(EXIT_FAILURE);
1994                 }
1995                 else
1996                     print_statistics(hand->obj[u], &iter);
1997             } /* end for */
1998         } /* end if */
1999         else {
2000             if(h5trav_visit(fid, "/", TRUE, TRUE, obj_stats, lnk_stats, &iter, H5O_INFO_ALL) < 0) {
2001                 error_msg("unable to traverse objects/links in file \"%s\"\n", fname);
2002                 h5tools_setstatus(EXIT_FAILURE);
2003             }
2004             else
2005                 print_statistics("/", &iter);
2006         } /* end else */
2007     } /* end if */
2008 
2009 done:
2010     hand_free(hand);
2011 
2012     /* Free iter structure */
2013     iter_free(&iter);
2014 
2015     if (fapl_id != H5P_DEFAULT) {
2016         if (H5Pclose(fapl_id) < 0) {
2017             error_msg("unable to close fapl entry\n");
2018             h5tools_setstatus(EXIT_FAILURE);
2019         }
2020     }
2021 
2022     if(fid >= 0 && H5Fclose(fid) < 0) {
2023         error_msg("unable to close file \"%s\"\n", fname);
2024         h5tools_setstatus(EXIT_FAILURE);
2025     } /* end if */
2026 
2027     H5Eset_auto2(H5E_DEFAULT, func, edata);
2028 
2029     leave(h5tools_getstatus());
2030 } /* end main() */
2031 
2032