netcdf-c/nczarr_test/zs3parse.c
Dennis Heimbigner f3e711e2b8 Add support for setting HDF5 alignment property when creating a file
re: https://github.com/Unidata/netcdf-c/issues/2177
re: https://github.com/Unidata/netcdf-c/pull/2178

Provide get/set functions to store global data alignment
information and apply it when a file is created.

The api is as follows:
````
int nc_set_alignment(int threshold, int alignment);
int nc_get_alignment(int* thresholdp, int* alignmentp);
````

If defined, then for every file created opened after the call to
nc_set_alignment, for every new variable added to the file, the
most recently set threshold and alignment values will be applied
to that variable.

The nc_get_alignment function return the last values set by
nc_set_alignment.  If nc_set_alignment has not been called, then
it returns the value 0 for both threshold and alignment.

The alignment parameters are stored in the NCglobalstate object
(see below) for use as needed. Repeated calls to nc_set_alignment
will overwrite any existing values in NCglobalstate.

The alignment parameters are applied in libhdf5/hdf5create.c
and libhdf5/hdf5open.c

The set/get alignment functions are defined in libsrc4/nc4internal.c.

A test program was added as nc_test4/tst_alignment.c.

## Misc. Changes Unrelated to Alignment

* The NCRCglobalstate type was renamed to NCglobalstate to
  indicate that it represented more general global state than
  just .rc data.  It was also moved to nc4internal.h.  This led
  to a large number of small changes: mostly renaming. The
  global state management functions were moved to nc4internal.c.

* The global chunk cache variables have been moved into
  NCglobalstate.  As warranted, other global state will be moved
  as well.

* Some misc. problems with the nczarr performance tests were corrected.
2022-01-29 15:27:52 -07:00

170 lines
3.7 KiB
C

/*
* Copyright 2018, University Corporation for Atmospheric Research
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#if defined(_WIN32) && !defined(__MINGW32__)
#include "XGetopt.h"
#endif
#include "zincludes.h"
#include "ncpathmgr.h"
#undef DEBUG
#define AWSHOST ".amazonaws.com"
typedef enum S3op {
S3_NONE=0,
S3_HOST=1,
S3_BUCKET=2,
S3_KEY=3,
} S3op;
/* Command line options */
struct S3options {
int debug;
S3op op;
char* url;
} s3options;
/*Forward*/
static int processurl(S3op op, const char* url, char** piece);
static void
zs3usage(void)
{
fprintf(stderr,"usage: zs3parse [-h|-b|-k] <url>|<file>\n");
exit(1);
}
int
main(int argc, char** argv)
{
int stat = NC_NOERR;
int c;
char* piece = NULL;
memset((void*)&s3options,0,sizeof(s3options));
while ((c = getopt(argc, argv, "vhbk")) != EOF) {
switch(c) {
case 'b':
s3options.op = S3_BUCKET;
break;
case 'h':
s3options.op = S3_HOST;
break;
case 'k':
s3options.op = S3_KEY;
break;
case 'v':
zs3usage();
goto done;
case '?':
fprintf(stderr,"unknown option: %c\n",c);
goto fail;
}
}
/* get url|file argument */
argc -= optind;
argv += optind;
if (argc > 1) {
fprintf(stderr, "zs3parse: only one url|file argument permitted\n");
goto fail;
}
if (argc == 0) {
fprintf(stderr, "zs3parse: no url|file specified\n");
goto fail;
}
s3options.url = strdup(argv[0]);
stat = processurl(s3options.op, s3options.url, &piece);
if(stat == NC_NOERR) {
if(piece == NULL) goto fail;
printf("%s",piece);
}
done:
nullfree(piece);
/* Reclaim s3options */
nullfree(s3options.url);
if(stat)
fprintf(stderr,"fail: %s\n",nc_strerror(stat));
return (stat ? 1 : 0);
fail:
stat = NC_EINVAL;
goto done;
}
static int
processurl(S3op op, const char* surl, char** piece)
{
int stat = NC_NOERR;
NClist* segments = NULL;
NCbytes* buf = ncbytesnew();
char* value = NULL;
char* host = NULL;
char* bucket = NULL;
char* prefix = NULL;
NCURI* url = NULL;
ncuriparse(surl,&url);
if(url == NULL)
{stat = NC_EURL; goto done;}
/* do some verification */
if(strcmp(url->protocol,"https") != 0
&& strcmp(url->protocol,"http") != 0)
{stat = NC_EURL; goto done;}
if(url->host == NULL || strlen(url->host) == 0)
{stat = NC_EURL; goto done;}
if((host = strdup(url->host))==NULL)
{stat = NC_ENOMEM; goto done;}
/* We have to process the path to get the bucket,
and remove it from the path */
if(url->path == NULL || strlen(url->path) == 0)
{stat = NC_EURL; goto done;}
/* split the path by "/" */
nclistfreeall(segments);
segments = nclistnew();
if((stat = nczm_split_delim(url->path,'/',segments))) goto done;
if(nclistlength(segments) == 0)
{stat = NC_EURL; goto done;}
bucket = ((char*)nclistremove(segments,0));
if((stat = nczm_join(segments,&prefix))) goto done;
nclistfreeall(segments); segments = NULL;
switch (op) {
case S3_HOST: value = host; host = NULL; break;
case S3_BUCKET: value = bucket; bucket = NULL; break;
case S3_KEY: value = prefix; prefix = NULL; break;
default: stat = NC_EURL; goto done;
}
if(piece) {*piece = value; value = NULL;}
done:
ncurifree(url);
nullfree(value);
nullfree(host);
nullfree(bucket);
nullfree(prefix);
ncbytesfree(buf);
nclistfreeall(segments);
return stat;
}