Files
hdf5/tools/h5format_convert/h5format_convert.c
Quincey Koziol d3396a7953 [svn-r30075] Description:
Bring object/dataset/group/named datatype features from revise_chunks
branch to trunk.  Also CMake support for h5format_convert and a bunch of
misc. cleanups.

Tested on:
    MacOSX/64 10.11.5 (amazon) w/serial, parallel & production
    (h5committest forthcoming)
2016-06-14 18:07:03 -05:00

475 lines
14 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright by The HDF Group. *
* Copyright by the Board of Trustees of the University of Illinois. *
* All rights reserved. *
* *
* This file is part of HDF5. The full HDF5 copyright notice, including *
* terms governing use, modification, and redistribution, is contained in *
* the files COPYING and Copyright.html. COPYING can be found at the root *
* of the source code distribution tree; Copyright.html can be found at the *
* root level of an installed copy of the electronic HDF5 document set and *
* is linked from the top-level documents page. It can also be found at *
* http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
* access to either file, you may request a copy from help@hdfgroup.org. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
* Programmer: Vailin Choi; Feb 2015
*/
/*
* We include the private header file so we can get to the uniform
* programming environment it declares.
* HDF5 API functions (except for H5G_basename())
*/
#include "H5private.h"
#include "h5tools.h"
#include "h5tools_utils.h"
#include "h5trav.h"
/* Name of tool */
#define PROGRAMNAME "h5format_convert"
static char *fname_g = NULL;
static char *dname_g = NULL;
static int dset_g = FALSE;
static int noop_g = FALSE;
static int verbose_g = 0;
/*
* Command-line options: The user can specify short or long-named
* parameters.
*/
static const char *s_opts = "hVvd:n";
static struct long_options l_opts[] = {
{ "help", no_arg, 'h' },
{ "hel", no_arg, 'h'},
{ "he", no_arg, 'h'},
{ "version", no_arg, 'V' },
{ "version", no_arg, 'V' },
{ "versio", no_arg, 'V' },
{ "versi", no_arg, 'V' },
{ "vers", no_arg, 'V' },
{ "verbose", no_arg, 'v' },
{ "verbos", no_arg, 'v' },
{ "verbo", no_arg, 'v' },
{ "verb", no_arg, 'v' },
{ "dname", require_arg, 'd' },
{ "dnam", require_arg, 'd' },
{ "dna", require_arg, 'd' },
{ "dn", require_arg, 'd' },
{ "noop", no_arg, 'n' },
{ "noo", no_arg, 'n' },
{ "no", no_arg, 'n' },
{ NULL, 0, '\0' }
};
/*-------------------------------------------------------------------------
* Function: usage
*
* Purpose: print usage
*
* Return: void
*
*-------------------------------------------------------------------------
*/
static void usage(const char *prog)
{
HDfprintf(stdout, "usage: %s [OPTIONS] file_name\n", prog);
HDfprintf(stdout, " OPTIONS\n");
HDfprintf(stdout, " -h, --help Print a usage message and exit\n");
HDfprintf(stdout, " -V, --version Print version number and exit\n");
HDfprintf(stdout, " -v, --verbose Turn on verbose mode\n");
HDfprintf(stdout, " -d dname, --dname=dataset_name Pathname for the dataset\n");
HDfprintf(stdout, " -n, --noop Perform all the steps except the actual conversion\n");
HDfprintf(stdout, "\n");
HDfprintf(stdout, "Examples of use:\n");
HDfprintf(stdout, "\n");
HDfprintf(stdout, "h5format_convert -d /group/dataset file_name\n");
HDfprintf(stdout, " Convert the dataset </group/dataset> in the HDF5 file <file_name>:\n");
HDfprintf(stdout, " a. chunked dataset: convert the chunk indexing type to version 1 B-tree\n");
HDfprintf(stdout, " b. compact/contiguous dataset: downgrade the layout version to 3\n");
HDfprintf(stdout, " c. virtual dataset: no action\n");
HDfprintf(stdout, "\n");
HDfprintf(stdout, "h5format_convert file_name\n");
HDfprintf(stdout, " Convert all datasets in the HDF5 file <file_name>:\n");
HDfprintf(stdout, " a. chunked dataset: convert the chunk indexing type to version 1 B-tree\n");
HDfprintf(stdout, " b. compact/contiguous dataset: downgrade the layout version to 3\n");
HDfprintf(stdout, " c. virtual dataset: no action\n");
HDfprintf(stdout, "\n");
HDfprintf(stdout, "h5format_convert -n -d /group/dataset file_name\n");
HDfprintf(stdout, " Go through all the steps except the actual conversion when \n");
HDfprintf(stdout, " converting the dataset </group/dataset> in the HDF5 file <file_name>.\n");
} /* usage() */
/*-------------------------------------------------------------------------
* Function: parse_command_line
*
* Purpose: parse command line input
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
parse_command_line(int argc, const char **argv)
{
int opt;
/* no arguments */
if (argc == 1) {
usage(h5tools_getprogname());
h5tools_setstatus(EXIT_FAILURE);
goto error;
}
/* parse command line options */
while ((opt = get_option(argc, argv, s_opts, l_opts)) != EOF) {
switch((char) opt) {
case 'h':
usage(h5tools_getprogname());
h5tools_setstatus(EXIT_SUCCESS);
goto error;
case 'V':
print_version(h5tools_getprogname());
h5tools_setstatus(EXIT_SUCCESS);
goto error;
case 'v':
verbose_g = TRUE;
break;
case 'd': /* -d dname */
if(opt_arg != NULL && *opt_arg)
dname_g = HDstrdup(opt_arg);
if(dname_g == NULL) {
h5tools_setstatus(EXIT_FAILURE);
error_msg("No dataset name\n", opt_arg);
usage(h5tools_getprogname());
goto error;
}
dset_g = TRUE;
break;
case 'n': /* -n */
noop_g = TRUE;
break;
default:
h5tools_setstatus(EXIT_FAILURE);
usage(h5tools_getprogname());
goto error;
break;
} /* switch */
} /* while */
if (argc <= opt_ind) {
error_msg("missing file name\n");
usage(h5tools_getprogname());
h5tools_setstatus(EXIT_FAILURE);
goto error;
}
fname_g = HDstrdup(argv[opt_ind]);
return(0);
error:
return(-1); ;
} /* parse_command_line() */
/*-------------------------------------------------------------------------
* Function: leave
*
* Purpose: Close HDF5
*
* Return: Does not return
*
*-------------------------------------------------------------------------
*/
static void
leave(int ret)
{
h5tools_close();
HDexit(ret);
} /* leave() */
/*-------------------------------------------------------------------------
* Function: convert()
*
* Purpose: To downgrade a dataset's indexing type or layout version:
* For chunked:
* Downgrade the chunk indexing type to version 1 B-tree
* If type is already version 1 B-tree, no further action
* For compact/contiguous:
* Downgrade the layout version from 4 to 3
* If version is already <= 3, no further action
* For virtual:
* No further action
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
static int
convert(hid_t fid, const char *dname)
{
hid_t dcpl = -1;
hid_t did = -1;
H5D_layout_t layout_type;
H5D_chunk_index_t idx_type;
/* Open the dataset */
if((did = H5Dopen2(fid, dname, H5P_DEFAULT)) < 0) {
error_msg("unable to open dataset \"%s\"\n", dname);
h5tools_setstatus(EXIT_FAILURE);
goto error;
} else if(verbose_g)
HDfprintf(stdout, "Open the dataset\n");
/* Get the dataset's creation property list */
if((dcpl = H5Dget_create_plist(did)) < 0) {
error_msg("unable to get the dataset creation property list\n");
h5tools_setstatus(EXIT_FAILURE);
goto error;
}
/* Get the dataset's layout */
if((layout_type = H5Pget_layout(dcpl)) < 0) {
error_msg("unable to get the dataset layout type\n");
h5tools_setstatus(EXIT_FAILURE);
goto error;
} else if(verbose_g)
HDfprintf(stdout, "Retrieve the dataset's layout\n");
switch(layout_type) {
case H5D_CHUNKED:
if(verbose_g)
HDfprintf(stdout, "Dataset is a chunked dataset\n");
/* Get the dataset's chunk indexing type */
if(H5Dget_chunk_index_type(did, &idx_type) < 0) {
error_msg("unable to get the chunk indexing type for \"%s\"\n", dname);
h5tools_setstatus(EXIT_FAILURE);
goto error;
} else if(verbose_g)
HDfprintf(stdout, "Retrieve the dataset's chunk indexing type\n");
if(idx_type == H5D_CHUNK_IDX_BTREE) {
if(verbose_g)
HDfprintf(stdout, "Dataset's chunk indexing type is already version 1 B-tree: no further action\n");
h5tools_setstatus(EXIT_SUCCESS);
goto done;
} else if (verbose_g)
HDfprintf(stdout, "Dataset's chunk indexing type is not version 1 B-tree\n");
break;
case H5D_CONTIGUOUS:
if(verbose_g)
HDfprintf(stdout, "Dataset is a contiguous dataset: downgrade layout version as needed\n");
break;
case H5D_COMPACT:
if(verbose_g)
HDfprintf(stdout, "Dataset is a compact dataset: downgrade layout version as needed\n");
break;
case H5D_VIRTUAL:
if(verbose_g)
HDfprintf(stdout, "No further action for virtual dataset\n");
goto done;
case H5D_NLAYOUTS:
case H5D_LAYOUT_ERROR:
default:
error_msg("unknown layout type for \"%s\"\n", dname);
h5tools_setstatus(EXIT_FAILURE);
goto error;
} /* end switch */
/* No further action if it is a noop */
if(noop_g) {
if(verbose_g)
HDfprintf(stdout, "Not converting the dataset\n");
h5tools_setstatus(EXIT_SUCCESS);
goto done;
}
if(verbose_g)
HDfprintf(stdout, "Converting the dataset...\n");
/* Downgrade the dataset */
if(H5Dformat_convert(did) < 0) {
error_msg("unable to downgrade dataset \"%s\"\n", dname);
h5tools_setstatus(EXIT_FAILURE);
goto error;
} else if(verbose_g)
HDfprintf(stdout, "Done\n");
done:
/* Close the dataset */
if(H5Dclose(did) < 0) {
error_msg("unable to close dataset \"%s\"\n", dname);
h5tools_setstatus(EXIT_FAILURE);
goto error;
} else if(verbose_g)
HDfprintf(stdout, "Close the dataset\n");
/* Close the dataset creation property list */
if(H5Pclose(dcpl) < 0) {
error_msg("unable to close dataset creation property list\n");
h5tools_setstatus(EXIT_FAILURE);
goto error;
} else if(verbose_g)
printf("Close the dataset creation property list\n");
return(0);
error:
if(verbose_g)
HDfprintf(stdout, "Error encountered\n");
H5E_BEGIN_TRY {
H5Pclose(dcpl);
H5Dclose(did);
} H5E_END_TRY;
return(-1);
} /* convert() */
/*-------------------------------------------------------------------------
* Function: convert_dsets_cb()
*
* Purpose: The callback routine from the traversal to convert the
* chunk indexing type of the dataset object.
*
* Return: Success: 0
* Failure: 1
*-------------------------------------------------------------------------
*/
static int
convert_dsets_cb(const char *path, const H5O_info_t *oi, const char *already_visited, void *_fid)
{
hid_t fid = *(hid_t *)_fid;
/* If the object has already been seen then just return */
if(NULL == already_visited) {
if(oi->type == H5O_TYPE_DATASET) {
if(verbose_g)
HDfprintf(stdout, "Going to process dataset:%s...\n", path);
if(convert(fid, path) < 0)
goto error;
} /* end if */
} /* end if */
return 0;
error:
return -1;
} /* end convert_dsets_cb() */
/*-------------------------------------------------------------------------
* Function: main
*
* Purpose: To convert the chunk indexing type of a dataset in a file to
* version 1 B-tree.
*
* Return: Success: 0
* Failure: 1
*
*-------------------------------------------------------------------------
*/
int
main(int argc, const char *argv[])
{
H5E_auto2_t func;
void *edata;
hid_t fid = -1;
h5tools_setprogname(PROGRAMNAME);
h5tools_setstatus(EXIT_SUCCESS);
/* Disable error reporting */
H5Eget_auto2(H5E_DEFAULT, &func, &edata);
H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
/* Initialize h5tools lib */
h5tools_init();
/* Parse command line options */
if(parse_command_line(argc, argv) < 0)
goto done;
else if(verbose_g)
HDfprintf(stdout, "Process command line options\n");
if(noop_g && verbose_g)
HDfprintf(stdout, "It is noop...\n");
/* Open the HDF5 file */
if((fid = h5tools_fopen(fname_g, H5F_ACC_RDWR, H5P_DEFAULT, NULL, NULL, 0)) < 0) {
error_msg("unable to open file \"%s\"\n", fname_g);
h5tools_setstatus(EXIT_FAILURE);
goto done;
} else if(verbose_g)
HDfprintf(stdout, "Open the file %s\n", fname_g);
if(dset_g) { /* Convert a specified dataset in the file */
if(verbose_g)
HDfprintf(stdout, "Going to process dataset: %s...\n", dname_g);
if(convert(fid, dname_g) < 0)
goto done;
} else { /* Convert all datasets in the file */
if(verbose_g)
HDfprintf(stdout, "Processing all datasets in the file...\n");
if(h5trav_visit(fid, "/", TRUE, TRUE, convert_dsets_cb, NULL, &fid) < 0)
goto done;
} /* end else */
if(verbose_g) {
if(noop_g) {
HDfprintf(stdout, "Not processing the file's superblock...\n");
h5tools_setstatus(EXIT_SUCCESS);
goto done;
} /* end if */
HDfprintf(stdout, "Processing the file's superblock...\n");
} /* end if */
/* Process superblock */
if(H5Fformat_convert(fid) < 0) {
error_msg("unable to convert file's superblock\"%s\"\n", fname_g);
h5tools_setstatus(EXIT_FAILURE);
goto done;
} /* end if */
done:
/* Close the file */
if(fid >= 0) {
if(H5Fclose(fid) < 0) {
error_msg("unable to close file \"%s\"\n", fname_g);
h5tools_setstatus(EXIT_FAILURE);
} else if(verbose_g)
HDfprintf(stdout, "Close the file\n");
} /* end if */
if(fname_g)
HDfree(fname_g);
if(dname_g)
HDfree(dname_g);
H5Eset_auto2(H5E_DEFAULT, func, edata);
leave(h5tools_getstatus());
} /* end main() */