diff options
author | Allen Byrne <byrn@hdfgroup.org> | 2020-10-13 20:51:06 (GMT) |
---|---|---|
committer | Allen Byrne <byrn@hdfgroup.org> | 2020-10-15 13:09:48 (GMT) |
commit | 48d171b04730aff7beade684e9afd164f0204b0c (patch) | |
tree | 81bb97f196a1f35bc94624ab5f1b8e9fbbccaa81 /src/H5FDros3.c | |
parent | 1ce4c8dd7ddaa344ad041514b1d3aa4979497275 (diff) | |
download | hdf5-48d171b04730aff7beade684e9afd164f0204b0c.zip hdf5-48d171b04730aff7beade684e9afd164f0204b0c.tar.gz hdf5-48d171b04730aff7beade684e9afd164f0204b0c.tar.bz2 |
Merge from 1.10
Comments, whitespace
Simple init and if block brackets.
Minimal code changes limited to return value and spelling
Diffstat (limited to 'src/H5FDros3.c')
-rw-r--r-- | src/H5FDros3.c | 1317 |
1 files changed, 621 insertions, 696 deletions
diff --git a/src/H5FDros3.c b/src/H5FDros3.c index 002b858..13ced31 100644 --- a/src/H5FDros3.c +++ b/src/H5FDros3.c @@ -13,11 +13,13 @@ /* * Read-Only S3 Virtual File Driver (VFD) * - * Programmer: Jacob Smith <jake.smith@hdfgroup.org> + * Programmer: Jacob Smith * 2017-10-13 * - * Purpose: Provide read-only access to files hosted on Amazon's S3 service. - * Relies on "s3comms" utility layer to implement the AWS REST API. + * Purpose: + * + * Provide read-only access to files hosted on Amazon's S3 service. + * Relies on "s3comms" utility layer to implement the AWS REST API. */ /* Interface initialization */ @@ -305,8 +307,10 @@ H5FD_ros3_init_interface(void) hid_t H5FD_ros3_init(void) { - hid_t ret_value = H5I_INVALID_HID; + hid_t ret_value = H5I_INVALID_HID; +#if ROS3_STATS unsigned int bin_i; +#endif FUNC_ENTER_NOAPI(FAIL) @@ -322,6 +326,7 @@ H5FD_ros3_init(void) */ for (bin_i = 0; bin_i < ROS3_STATS_BIN_COUNT; bin_i++) { unsigned long long value = 0; + ROS3_STATS_POW(bin_i, &value) ros3_stats_boundaries[bin_i] = value; } @@ -390,7 +395,8 @@ H5Pset_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa) HDfprintf(stdout, "H5Pset_fapl_ros3() called.\n"); #endif - if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) + plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS); + if (plist == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") if (FAIL == H5FD_ros3_validate_config(fa)) @@ -403,12 +409,266 @@ done: } /* end H5Pset_fapl_ros3() */ /*------------------------------------------------------------------------- + * Function: H5FD_ros3_validate_config() + * + * Purpose: Test to see if the supplied instance of H5FD_ros3_fapl_t + * contains internally consistant data. Return SUCCEED if so, + * and FAIL otherwise. + * + * Note the difference between internally consistant and + * correct. As we will have to try to access the target + * object to determine whether the supplied data is correct, + * we will settle for internal consistancy at this point + * + * Return: SUCCEED if instance of H5FD_ros3_fapl_t contains internally + * consistant data, FAIL otherwise. + * + * Programmer: Jacob Smith + * 9/10/17 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_ros3_validate_config(const H5FD_ros3_fapl_t *fa) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + + HDassert(fa != NULL); + + if (fa->version != H5FD_CURR_ROS3_FAPL_T_VERSION) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown H5FD_ros3_fapl_t version"); + + /* if set to authenticate, region and id cannot be empty strings */ + if (fa->authenticate == TRUE) + if ((fa->aws_region[0] == '\0') || (fa->secret_id[0] == '\0')) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Inconsistent authentication information"); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_ros3_validate_config() */ + +/*------------------------------------------------------------------------- + * Function: H5Pget_fapl_ros3 + * + * Purpose: Returns information about the ros3 file access property + * list though the function arguments. + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: John Mainzer + * 9/10/17 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa_out) +{ + const H5FD_ros3_fapl_t *fa = NULL; + H5P_genplist_t * plist = NULL; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_API(FAIL) + H5TRACE2("e", "i*x", fapl_id, fa_out); + +#if ROS3_DEBUG + HDfprintf(stdout, "H5Pget_fapl_ros3() called.\n"); +#endif + + if (fa_out == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "fa_out is NULL") + + plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS); + if (plist == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list") + + if (H5FD_ROS3 != H5P_get_driver(plist)) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver") + + fa = (const H5FD_ros3_fapl_t *)H5P_get_driver_info(plist); + if (fa == NULL) + HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info") + + /* Copy the ros3 fapl data out */ + HDmemcpy(fa_out, fa, sizeof(H5FD_ros3_fapl_t)); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_fapl_ros3() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_ros3_fapl_get + * + * Purpose: Gets a file access property list which could be used to + * create an identical file. + * + * Return: Success: Ptr to new file access property list value. + * + * Failure: NULL + * + * Programmer: John Mainzer + * 9/8/17 + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_ros3_fapl_get(H5FD_t *_file) +{ + H5FD_ros3_t * file = (H5FD_ros3_t *)_file; + H5FD_ros3_fapl_t *fa = NULL; + void * ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + fa = (H5FD_ros3_fapl_t *)H5MM_calloc(sizeof(H5FD_ros3_fapl_t)); + if (fa == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Copy the fields of the structure */ + HDmemcpy(fa, &(file->fa), sizeof(H5FD_ros3_fapl_t)); + + /* Set return value */ + ret_value = fa; + +done: + if (ret_value == NULL) + if (fa != NULL) + H5MM_xfree(fa); + +} /* end H5FD_ros3_fapl_get() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_ros3_fapl_copy + * + * Purpose: Copies the ros3-specific file access properties. + * + * Return: Success: Ptr to a new property list + * + * Failure: NULL + * + * Programmer: John Mainzer + * 9/8/17 + * + *------------------------------------------------------------------------- + */ +static void * +H5FD_ros3_fapl_copy(const void *_old_fa) +{ + const H5FD_ros3_fapl_t *old_fa = (const H5FD_ros3_fapl_t *)_old_fa; + H5FD_ros3_fapl_t * new_fa = NULL; + void * ret_value = NULL; + + FUNC_ENTER_NOAPI_NOINIT + + new_fa = (H5FD_ros3_fapl_t *)H5MM_malloc(sizeof(H5FD_ros3_fapl_t)); + if (new_fa == NULL) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + + HDmemcpy(new_fa, old_fa, sizeof(H5FD_ros3_fapl_t)); + ret_value = new_fa; + +done: + if (ret_value == NULL) + if (new_fa != NULL) + H5MM_xfree(new_fa); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5FD_ros3_fapl_copy() */ + +/*------------------------------------------------------------------------- + * Function: H5FD_ros3_fapl_free + * + * Purpose: Frees the ros3-specific file access properties. + * + * Return: SUCCEED (cannot fail) + * + * Programmer: John Mainzer + * 9/8/17 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5FD_ros3_fapl_free(void *_fa) +{ + H5FD_ros3_fapl_t *fa = (H5FD_ros3_fapl_t *)_fa; + + FUNC_ENTER_NOAPI_NOINIT_NOERR + + HDassert(fa != NULL); /* sanity check */ + + H5MM_xfree(fa); + + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD_ros3_fapl_free() */ + +#if ROS3_STATS +/*---------------------------------------------------------------------------- + * + * Function: ros3_reset_stats() + * + * Purpose: + * + * Reset the stats collection elements in this virtual file structure. + * + * Clears any set data in stats bins; initializes/zeroes values. + * + * Return: + * + * - SUCCESS: `SUCCEED` + * - FAILURE: `FAIL` + * - Occurs if the file is invalid somehow + * + * Programmer: Jacob Smith + * 2017-12-08 + * + *---------------------------------------------------------------------------- + */ +static herr_t +ros3_reset_stats(H5FD_ros3_t *file) +{ + unsigned i = 0; + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI_NOINIT + +#if ROS3_DEBUG + HDprintf("ros3_reset_stats() called\n"); +#endif + + if (file == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file was null"); + + for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { + file->raw[i].bytes = 0; + file->raw[i].count = 0; + file->raw[i].min = (unsigned long long)ROS3_STATS_STARTING_MIN; + file->raw[i].max = 0; + + file->meta[i].bytes = 0; + file->meta[i].count = 0; + file->meta[i].min = (unsigned long long)ROS3_STATS_STARTING_MIN; + file->meta[i].max = 0; + } + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end ros3_reset_stats() */ +#endif /* ROS3_STATS */ + +/*------------------------------------------------------------------------- + * * Function: H5FD_ros3_open() * - * Purpose: Create and/or opens a file as an HDF5 file. - * Any flag except H5F_ACC_RDONLY will cause an error. + * Purpose: + * + * Create and/or opens a file as an HDF5 file. + * + * Any flag except H5F_ACC_RDONLY will cause an error. * - * Name (as received from `H5FD_open()`) must conform to web url: + * Name (as received from `H5FD_open()`) must conform to web url: * NAME :: HTTP "://" DOMAIN [PORT] ["/" [URI] [QUERY] ] * HTTP :: "http" [ "s" ] * DOMAIN :: e.g., "mybucket.host.org" @@ -416,10 +676,13 @@ done: * URI :: <string> (e.g., "path/to/resource.hd5" ) * QUERY :: "?" <string> (e.g., "arg1=param1&arg2=param2") * - * Return: Success: A pointer to a new file data structure. - * The public fields will be initialized by the caller, which is - * always H5FD_open(). - * Failure: NULL + * Return: + * + * Success: A pointer to a new file data structure. + * The public fields will be initialized by the caller, which is + * always H5FD_open(). + * + * Failure: NULL * * Programmer: Jacob Smith * 2017-11-02 @@ -475,27 +738,23 @@ H5FD_ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) if (ISO8601NOW(iso8601now, now) != (ISO8601_SIZE - 1)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "problem while writing iso8601 timestamp") if (FAIL == H5FD_s3comms_signing_key(signing_key, (const char *)fa.secret_key, - (const char *)fa.aws_region, (const char *)iso8601now)) { + (const char *)fa.aws_region, (const char *)iso8601now)) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "problem while computing signing key") - } handle = H5FD_s3comms_s3r_open(url, (const char *)fa.aws_region, (const char *)fa.secret_id, (const unsigned char *)signing_key); } - else { + else handle = H5FD_s3comms_s3r_open(url, NULL, NULL, NULL); - } /* if/else should authenticate */ - if (handle == NULL) { + if (handle == NULL) /* If we want to check CURL's say on the matter in a controlled * fashion, this is the place to do it, but would need to make a * few minor changes to s3comms `s3r_t` and `s3r_read()`. */ HGOTO_ERROR(H5E_VFL, H5E_CANTOPENFILE, NULL, "could not open"); - } - /* create new file struct - */ + /* create new file struct */ file = H5FL_CALLOC(H5FD_ros3_t); if (file == NULL) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") @@ -512,19 +771,297 @@ H5FD_ros3_open(const char *url, unsigned flags, hid_t fapl_id, haddr_t maxaddr) done: if (ret_value == NULL) { - if (handle != NULL) { + if (handle != NULL) if (FAIL == H5FD_s3comms_s3r_close(handle)) HDONE_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, NULL, "unable to close s3 file handle") - } - if (file != NULL) { + if (file != NULL) file = H5FL_FREE(H5FD_ros3_t, file); - } curl_global_cleanup(); /* early cleanup because open failed */ } /* end if null return value (error) */ FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_ros3_open() */ +#if ROS3_STATS +/*---------------------------------------------------------------------------- + * + * Function: ros3_fprint_stats() + * + * Purpose: + * + * Tabulate and pretty-print statistics for this virtual file. + * + * Should be called upon file close. + * + * Shows number of reads and bytes read, broken down by + * "raw" (H5FD_MEM_DRAW) + * or "meta" (any other flag) + * + * Prints filename and listing of total number of reads and bytes read, + * both as a grand total and separate meta- and rawdata reads. + * + * If any reads were done, prints out two tables: + * + * 1. overview of raw- and metadata reads + * - min (smallest size read) + * - average of size read + * - k,M,G suffixes by powers of 1024 (2^10) + * - max (largest size read) + * 2. tabulation of "bins", sepraring reads into exponentially-larger + * ranges of size. + * - columns for number of reads, total bytes, and average size, with + * separate sub-colums for raw- and metadata reads. + * - each row represents one bin, identified by the top of its range + * + * Bin ranges can be modified with pound-defines at the top of this file. + * + * Bins without any reads in their bounds are not printed. + * + * An "overflow" bin is also present, to catch "big" reads. + * + * Output for all bins (and range ceiling and average size report) + * is divied by powers of 1024. By corollary, four digits before the decimal + * is valid. + * + * - 41080 bytes is represented by 40.177k, not 41.080k + * - 1004.831M represents approx. 1052642000 bytes + * + * Return: + * + * - SUCCESS: `SUCCEED` + * - FAILURE: `FAIL` + * - occurs if the file passed in is invalid + * - TODO: if stream is invalid? how can we check this? + * + * Programmer: Jacob Smith + * + *---------------------------------------------------------------------------- + */ +static herr_t +ros3_fprint_stats(FILE *stream, const H5FD_ros3_t *file) +{ + herr_t ret_value = SUCCEED; + parsed_url_t * purl = NULL; + unsigned i = 0; + unsigned long count_meta = 0; + unsigned long count_raw = 0; + double average_meta = 0.0; + double average_raw = 0.0; + unsigned long long min_meta = (unsigned long long)ROS3_STATS_STARTING_MIN; + unsigned long long min_raw = (unsigned long long)ROS3_STATS_STARTING_MIN; + unsigned long long max_meta = 0; + unsigned long long max_raw = 0; + unsigned long long bytes_raw = 0; + unsigned long long bytes_meta = 0; + double re_dub = 0.0; /* re-usable double variable */ + unsigned suffix_i = 0; + const char suffixes[] = {' ', 'K', 'M', 'G', 'T', 'P'}; + + FUNC_ENTER_NOAPI_NOINIT + + if (stream == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file stream cannot be null"); + if (file == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file cannot be null"); + if (file->s3r_handle == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "s3 request handle cannot be null"); + if (file->s3r_handle->purl == NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parsed url structure cannot be null"); + purl = file->s3r_handle->purl; + + /****************** + * PRINT FILENAME * + ******************/ + + HDfprintf(stream, "stats for %s://%s", purl->scheme, purl->host); + if (purl->port != NULL && purl->port[0] != '\0') + HDfprintf(stream, ":%s", purl->port); + if (purl->query != NULL && purl->query[0] != '\0') { + if (purl->path != NULL && purl->path[0] != '\0') + HDfprintf(stream, "/%s", purl->path); + else + HDfprintf(stream, "/"); + HDfprintf(stream, "?%s", purl->query); + } + else if (purl->path != NULL && purl->path[0] != '\0') { + HDfprintf(stream, "/%s", purl->path); + } + HDfprintf(stream, "\n"); + + /******************* + * AGGREGATE STATS * + *******************/ + + for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { + const ros3_statsbin *r = &file->raw[i]; + const ros3_statsbin *m = &file->meta[i]; + + if (m->min < min_meta) + min_meta = m->min; + if (r->min < min_raw) + min_raw = r->min; + if (m->max > max_meta) + max_meta = m->max; + if (r->max > max_raw) + max_raw = r->max; + + count_raw += r->count; + count_meta += m->count; + bytes_raw += r->bytes; + bytes_meta += m->bytes; + } + if (count_raw > 0) + average_raw = (double)bytes_raw / (double)count_raw; + if (count_meta > 0) + average_meta = (double)bytes_meta / (double)count_meta; + + /****************** + * PRINT OVERVIEW * + ******************/ + + HDfprintf(stream, "TOTAL READS: %llu (%llu meta, %llu raw)\n", count_raw + count_meta, count_meta, + count_raw); + HDfprintf(stream, "TOTAL BYTES: %llu (%llu meta, %llu raw)\n", bytes_raw + bytes_meta, bytes_meta, + bytes_raw); + + if (count_raw + count_meta == 0) + goto done; + + /************************* + * PRINT AGGREGATE STATS * + *************************/ + + HDfprintf(stream, "SIZES meta raw\n"); + HDfprintf(stream, " min "); + if (count_meta == 0) + HDfprintf(stream, " 0.000 "); + else { + re_dub = (double)min_meta; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + HDfprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); + } + + if (count_raw == 0) + HDfprintf(stream, " 0.000 \n"); + else { + re_dub = (double)min_raw; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + HDfprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); + } + + HDfprintf(stream, " avg "); + re_dub = (double)average_meta; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + HDfprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); + + re_dub = (double)average_raw; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + HDfprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); + + HDfprintf(stream, " max "); + re_dub = (double)max_meta; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + HDfprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); + + re_dub = (double)max_raw; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + HDfprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); + + /****************************** + * PRINT INDIVIDUAL BIN STATS * + ******************************/ + + HDfprintf(stream, "BINS # of reads total bytes average size\n"); + HDfprintf(stream, " up-to meta raw meta raw meta raw\n"); + + for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { + const ros3_statsbin *m; + const ros3_statsbin *r; + unsigned long long range_end = 0; + char bm_suffix = ' '; /* bytes-meta */ + double bm_val = 0.0; + char br_suffix = ' '; /* bytes-raw */ + double br_val = 0.0; + char am_suffix = ' '; /* average-meta */ + double am_val = 0.0; + char ar_suffix = ' '; /* average-raw */ + double ar_val = 0.0; + + m = &file->meta[i]; + r = &file->raw[i]; + if (r->count == 0 && m->count == 0) + continue; + + range_end = ros3_stats_boundaries[i]; + + if (i == ROS3_STATS_BIN_COUNT) { + range_end = ros3_stats_boundaries[i - 1]; + HDfprintf(stream, ">"); + } + else + HDfprintf(stream, " "); + + bm_val = (double)m->bytes; + for (suffix_i = 0; bm_val >= 1024.0; suffix_i++) + bm_val /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + bm_suffix = suffixes[suffix_i]; + + br_val = (double)r->bytes; + for (suffix_i = 0; br_val >= 1024.0; suffix_i++) + br_val /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + br_suffix = suffixes[suffix_i]; + + if (m->count > 0) + am_val = (double)(m->bytes) / (double)(m->count); + for (suffix_i = 0; am_val >= 1024.0; suffix_i++) + am_val /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + am_suffix = suffixes[suffix_i]; + + if (r->count > 0) + ar_val = (double)(r->bytes) / (double)(r->count); + for (suffix_i = 0; ar_val >= 1024.0; suffix_i++) + ar_val /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + ar_suffix = suffixes[suffix_i]; + + re_dub = (double)range_end; + for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) + re_dub /= 1024.0; + HDassert(suffix_i < sizeof(suffixes)); + + HDfprintf(stream, " %8.3f%c %7d %7d %8.3f%c %8.3f%c %8.3f%c %8.3f%c\n", re_dub, + suffixes[suffix_i], /* bin ceiling */ + m->count, /* metadata reads */ + r->count, /* rawdata reads */ + bm_val, bm_suffix, /* metadata bytes */ + br_val, br_suffix, /* rawdata bytes */ + am_val, am_suffix, /* metadata average */ + ar_val, ar_suffix); /* rawdata average */ + + HDfflush(stream); + } + +done: + FUNC_LEAVE_NOAPI(ret_value); + +} /* ros3_fprint_stats */ +#endif /* ROS3_STATS */ + /*------------------------------------------------------------------------- * * Function: H5FD_ros3_close() @@ -554,33 +1091,28 @@ H5FD_ros3_close(H5FD_t H5_ATTR_UNUSED *_file) HDfprintf(stdout, "H5FD_ros3_close() called.\n"); #endif - /* Sanity checks - */ + /* Sanity checks */ HDassert(file != NULL); HDassert(file->s3r_handle != NULL); /* Close the underlying request handle */ - if (FAIL == H5FD_s3comms_s3r_close(file->s3r_handle)) { + if (FAIL == H5FD_s3comms_s3r_close(file->s3r_handle)) HGOTO_ERROR(H5E_VFL, H5E_CANTCLOSEFILE, FAIL, "unable to close S3 request handle") - } #if ROS3_STATS /* TODO: mechanism to re-target stats printout */ - if (ros3_fprint_stats(stdout, file) == FAIL) { + if (ros3_fprint_stats(stdout, file) == FAIL) HGOTO_ERROR(H5E_INTERNAL, H5E_ERROR, FAIL, "problem while writing file statistics") - } #endif /* ROS3_STATS */ - /* Release the file info - */ + /* Release the file info */ file = H5FL_FREE(H5FD_ros3_t, file); done: curl_global_cleanup(); /* cleanup to answer init on open */ FUNC_LEAVE_NOAPI(ret_value) - } /* end H5FD_ros3_close() */ /*------------------------------------------------------------------------- @@ -641,96 +1173,75 @@ H5FD_ros3_cmp(const H5FD_t *_f1, const H5FD_t *_f2) HDassert(purl2->host != NULL); /* URL: SCHEME */ - if (HDstrcmp(purl1->scheme, purl2->scheme)) { - HGOTO_DONE(-1); - } + if (HDstrcmp(purl1->scheme, purl2->scheme)) + HGOTO_DONE(-1) /* URL: HOST */ - if (HDstrcmp(purl1->host, purl2->host)) { - HGOTO_DONE(-1); - } + if (HDstrcmp(purl1->host, purl2->host)) + HGOTO_DONE(-1) /* URL: PORT */ if (purl1->port && purl2->port) { - if (HDstrcmp(purl1->port, purl2->port)) { - HGOTO_DONE(-1); - } - } - else if (purl1->port) { - HGOTO_DONE(-1); - } - else if (purl2->port) { - HGOTO_DONE(-1); + if (HDstrcmp(purl1->port, purl2->port)) + HGOTO_DONE(-1) } + else if (purl1->port) + HGOTO_DONE(-1) + else if (purl2->port) + HGOTO_DONE(-1) /* URL: PATH */ if (purl1->path && purl2->path) { - if (HDstrcmp(purl1->path, purl2->path)) { - HGOTO_DONE(-1); - } - } - else if (purl1->path && !purl2->path) { - HGOTO_DONE(-1); - } - else if (purl2->path && !purl1->path) { - HGOTO_DONE(-1); + if (HDstrcmp(purl1->path, purl2->path)) + HGOTO_DONE(-1) } + else if (purl1->path && !purl2->path) + HGOTO_DONE(-1) + else if (purl2->path && !purl1->path) + HGOTO_DONE(-1) /* URL: QUERY */ if (purl1->query && purl2->query) { - if (HDstrcmp(purl1->query, purl2->query)) { - HGOTO_DONE(-1); - } - } - else if (purl1->query && !purl2->query) { - HGOTO_DONE(-1); - } - else if (purl2->query && !purl1->query) { - HGOTO_DONE(-1); + if (HDstrcmp(purl1->query, purl2->query)) + HGOTO_DONE(-1) } + else if (purl1->query && !purl2->query) + HGOTO_DONE(-1) + else if (purl2->query && !purl1->query) + HGOTO_DONE(-1) /* FAPL: AWS_REGION */ - if (f1->fa.aws_region[0] != '\0' && f1->fa.aws_region[0] != '\0') { - if (HDstrcmp(f1->fa.aws_region, f2->fa.aws_region)) { - HGOTO_DONE(-1); - } - } - else if (f1->fa.aws_region[0] != '\0') { - HGOTO_DONE(-1); - } - else if (f2->fa.aws_region[0] != '\0') { - HGOTO_DONE(-1); + if (f1->fa.aws_region[0] != '\0' && f2->fa.aws_region[0] != '\0') { + if (HDstrcmp(f1->fa.aws_region, f2->fa.aws_region)) + HGOTO_DONE(-1) } + else if (f1->fa.aws_region[0] != '\0') + HGOTO_DONE(-1) + else if (f2->fa.aws_region[0] != '\0') + HGOTO_DONE(-1) /* FAPL: SECRET_ID */ - if (f1->fa.secret_id[0] != '\0' && f1->fa.secret_id[0] != '\0') { - if (HDstrcmp(f1->fa.secret_id, f2->fa.secret_id)) { - HGOTO_DONE(-1); - } - } - else if (f1->fa.secret_id[0] != '\0') { - HGOTO_DONE(-1); - } - else if (f2->fa.secret_id[0] != '\0') { - HGOTO_DONE(-1); + if (f1->fa.secret_id[0] != '\0' && f2->fa.secret_id[0] != '\0') { + if (HDstrcmp(f1->fa.secret_id, f2->fa.secret_id)) + HGOTO_DONE(-1) } + else if (f1->fa.secret_id[0] != '\0') + HGOTO_DONE(-1) + else if (f2->fa.secret_id[0] != '\0') + HGOTO_DONE(-1) /* FAPL: SECRET_KEY */ - if (f1->fa.secret_key[0] != '\0' && f1->fa.secret_key[0] != '\0') { - if (HDstrcmp(f1->fa.secret_key, f2->fa.secret_key)) { - HGOTO_DONE(-1); - } - } - else if (f1->fa.secret_key[0] != '\0') { - HGOTO_DONE(-1); - } - else if (f2->fa.secret_key[0] != '\0') { - HGOTO_DONE(-1); + if (f1->fa.secret_key[0] != '\0' && f2->fa.secret_key[0] != '\0') { + if (HDstrcmp(f1->fa.secret_key, f2->fa.secret_key)) + HGOTO_DONE(-1) } + else if (f1->fa.secret_key[0] != '\0') + HGOTO_DONE(-1) + else if (f2->fa.secret_key[0] != '\0') + HGOTO_DONE(-1) done: FUNC_LEAVE_NOAPI(ret_value) - } /* H5FD_ros3_cmp() */ /*------------------------------------------------------------------------- @@ -769,7 +1280,6 @@ H5FD_ros3_query(const H5FD_t H5_ATTR_UNUSED *_file, unsigned long *flags /* out } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) - } /* H5FD_ros3_query() */ /*------------------------------------------------------------------------- @@ -803,7 +1313,6 @@ H5FD_ros3_get_eoa(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) #endif FUNC_LEAVE_NOAPI(file->eoa) - } /* end H5FD_ros3_get_eoa() */ /*------------------------------------------------------------------------- @@ -837,7 +1346,6 @@ H5FD_ros3_set_eoa(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, haddr_t addr) file->eoa = addr; FUNC_LEAVE_NOAPI(SUCCEED) - } /* H5FD_ros3_set_eoa() */ /*------------------------------------------------------------------------- @@ -870,7 +1378,6 @@ H5FD_ros3_get_eof(const H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type) #endif FUNC_LEAVE_NOAPI(H5FD_s3comms_s3r_get_filesize(file->s3r_handle)) - } /* end H5FD_ros3_get_eof() */ /*------------------------------------------------------------------------- @@ -902,15 +1409,13 @@ H5FD_ros3_get_handle(H5FD_t *_file, hid_t H5_ATTR_UNUSED fapl, void **file_handl HDfprintf(stdout, "H5FD_ros3_get_handle() called.\n"); #endif - if (!file_handle) { + if (!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") - } *file_handle = file->s3r_handle; done: FUNC_LEAVE_NOAPI(ret_value) - } /* end H5FD_ros3_get_handle() */ /*------------------------------------------------------------------------- @@ -936,10 +1441,8 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5FD_ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED dxpl_id, - haddr_t addr, /* start offset */ - size_t size, /* length of read */ - void * buf) /* out */ +H5FD_ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUSED dxpl_id, haddr_t addr, + size_t size, void *buf) { H5FD_ros3_t *file = (H5FD_ros3_t *)_file; size_t filesize = 0; @@ -962,38 +1465,30 @@ H5FD_ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUS filesize = H5FD_s3comms_s3r_get_filesize(file->s3r_handle); - if ((addr > filesize) || ((addr + size) > filesize)) { + if ((addr > filesize) || ((addr + size) > filesize)) HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "range exceeds file address") - } - if (H5FD_s3comms_s3r_read(file->s3r_handle, addr, size, buf) == FAIL) { + if (H5FD_s3comms_s3r_read(file->s3r_handle, addr, size, buf) == FAIL) HGOTO_ERROR(H5E_VFL, H5E_READERROR, FAIL, "unable to execute read") - } #if ROS3_STATS - /* Find which "bin" this read fits in. Can be "overflow" bin. - */ - for (bin_i = 0; bin_i < ROS3_STATS_BIN_COUNT; bin_i++) { - if ((unsigned long long)size < ros3_stats_boundaries[bin_i]) { + /* Find which "bin" this read fits in. Can be "overflow" bin. */ + for (bin_i = 0; bin_i < ROS3_STATS_BIN_COUNT; bin_i++) + if ((unsigned long long)size < ros3_stats_boundaries[bin_i]) break; - } - } bin = (type == H5FD_MEM_DRAW) ? &file->raw[bin_i] : &file->meta[bin_i]; - /* Store collected stats in appropriate bin - */ + /* Store collected stats in appropriate bin */ if (bin->count == 0) { bin->min = size; bin->max = size; } else { - if (size < bin->min) { + if (size < bin->min) bin->min = size; - } - if (size > bin->max) { + if (size > bin->max) bin->max = size; - } } bin->count++; bin->bytes += (unsigned long long)size; @@ -1002,7 +1497,6 @@ H5FD_ros3_read(H5FD_t *_file, H5FD_mem_t H5_ATTR_UNUSED type, hid_t H5_ATTR_UNUS done: FUNC_LEAVE_NOAPI(ret_value) - } /* end H5FD_ros3_read() */ /*------------------------------------------------------------------------- @@ -1039,7 +1533,6 @@ H5FD_ros3_write(H5FD_t H5_ATTR_UNUSED *_file, H5FD_mem_t H5_ATTR_UNUSED type, hi done: FUNC_LEAVE_NOAPI(ret_value) - } /* H5FD_ros3_write() */ /*------------------------------------------------------------------------- @@ -1077,7 +1570,6 @@ H5FD_ros3_truncate(H5FD_t H5_ATTR_UNUSED *_file, hid_t H5_ATTR_UNUSED dxpl_id, h done: FUNC_LEAVE_NOAPI(ret_value) - } /* end H5FD_ros3_truncate() */ /*------------------------------------------------------------------------- @@ -1105,8 +1597,8 @@ static herr_t H5FD_ros3_lock(H5FD_t H5_ATTR_UNUSED *_file, hbool_t H5_ATTR_UNUSED rw) { FUNC_ENTER_NOAPI_NOINIT_NOERR - FUNC_LEAVE_NOAPI(SUCCEED) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD_ros3_lock() */ /*------------------------------------------------------------------------- @@ -1131,575 +1623,8 @@ static herr_t H5FD_ros3_unlock(H5FD_t H5_ATTR_UNUSED *_file) { FUNC_ENTER_NOAPI_NOINIT_NOERR - FUNC_LEAVE_NOAPI(SUCCEED) - -} /* end H5FD_ros3_unlock() */ - -/*------------------------------------------------------------------------- - * Function: H5FD_ros3_validate_config() - * - * Purpose: Test to see if the supplied instance of H5FD_ros3_fapl_t - * contains internally consistant data. Return SUCCEED if so, - * and FAIL otherwise. - * - * Note the difference between internally consistant and - * correct. As we will have to try to access the target - * object to determine whether the supplied data is correct, - * we will settle for internal consistancy at this point - * - * Return: SUCCEED if instance of H5FD_ros3_fapl_t contains internally - * consistant data, FAIL otherwise. - * - * Programmer: Jacob Smith - * 9/10/17 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_ros3_validate_config(const H5FD_ros3_fapl_t *fa) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - - HDassert(fa != NULL); - - if (fa->version != H5FD_CURR_ROS3_FAPL_T_VERSION) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Unknown H5FD_ros3_fapl_t version"); - } - - /* if set to authenticate, region and id cannot be empty strings - */ - if (fa->authenticate == TRUE) { - if ((fa->aws_region[0] == '\0') || (fa->secret_id[0] == '\0')) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Inconsistent authentication information"); - } - } - -done: - FUNC_LEAVE_NOAPI(ret_value) - -} /* end H5FD_ros3_validate_config() */ - -/*------------------------------------------------------------------------- - * Function: H5Pget_fapl_ros3 - * - * Purpose: Returns information about the ros3 file access property - * list though the function arguments. - * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: John Mainzer - * 9/10/17 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_fapl_ros3(hid_t fapl_id, H5FD_ros3_fapl_t *fa_out) -{ - const H5FD_ros3_fapl_t *fa = NULL; - H5P_genplist_t * plist = NULL; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_API(FAIL) - H5TRACE2("e", "i*x", fapl_id, fa_out); - -#if ROS3_DEBUG - HDfprintf(stdout, "H5Pget_fapl_ros3() called.\n"); -#endif - - if (fa_out == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "fa_out is NULL") - } - - plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS); - if (plist == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access list") - } - - if (H5FD_ROS3 != H5P_get_driver(plist)) { - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver") - } - - fa = (const H5FD_ros3_fapl_t *)H5P_get_driver_info(plist); - if (fa == NULL) { - HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info") - } - - /* Copy the ros3 fapl data out */ - HDmemcpy(fa_out, fa, sizeof(H5FD_ros3_fapl_t)); - -done: - FUNC_LEAVE_API(ret_value) - -} /* end H5Pget_fapl_ros3() */ - -/*------------------------------------------------------------------------- - * Function: H5FD_ros3_fapl_get - * - * Purpose: Gets a file access property list which could be used to - * create an identical file. - * - * Return: Success: Ptr to new file access property list value. - * - * Failure: NULL - * - * Programmer: John Mainzer - * 9/8/17 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void * -H5FD_ros3_fapl_get(H5FD_t *_file) -{ - H5FD_ros3_t * file = (H5FD_ros3_t *)_file; - H5FD_ros3_fapl_t *fa = NULL; - void * ret_value = NULL; - - FUNC_ENTER_NOAPI_NOINIT - - fa = (H5FD_ros3_fapl_t *)H5MM_calloc(sizeof(H5FD_ros3_fapl_t)); - if (fa == NULL) { - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - } - - /* Copy the fields of the structure */ - HDmemcpy(fa, &(file->fa), sizeof(H5FD_ros3_fapl_t)); - - /* Set return value */ - ret_value = fa; - -done: - if (ret_value == NULL) { - if (fa != NULL) { - H5MM_xfree(fa); - } - } - FUNC_LEAVE_NOAPI(ret_value) - -} /* end H5FD_ros3_fapl_get() */ - -/*------------------------------------------------------------------------- - * Function: H5FD_ros3_fapl_copy - * - * Purpose: Copies the ros3-specific file access properties. - * - * Return: Success: Ptr to a new property list - * - * Failure: NULL - * - * Programmer: John Mainzer - * 9/8/17 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static void * -H5FD_ros3_fapl_copy(const void *_old_fa) -{ - const H5FD_ros3_fapl_t *old_fa = (const H5FD_ros3_fapl_t *)_old_fa; - H5FD_ros3_fapl_t * new_fa = NULL; - void * ret_value = NULL; - - FUNC_ENTER_NOAPI_NOINIT - - new_fa = (H5FD_ros3_fapl_t *)H5MM_malloc(sizeof(H5FD_ros3_fapl_t)); - if (new_fa == NULL) { - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - } - - HDmemcpy(new_fa, old_fa, sizeof(H5FD_ros3_fapl_t)); - ret_value = new_fa; - -done: - if (ret_value == NULL) { - if (new_fa != NULL) { - H5MM_xfree(new_fa); - } - } - FUNC_LEAVE_NOAPI(ret_value) - -} /* end H5FD_ros3_fapl_copy() */ - -/*------------------------------------------------------------------------- - * Function: H5FD_ros3_fapl_free - * - * Purpose: Frees the ros3-specific file access properties. - * - * Return: SUCCEED (cannot fail) - * - * Programmer: John Mainzer - * 9/8/17 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5FD_ros3_fapl_free(void *_fa) -{ - H5FD_ros3_fapl_t *fa = (H5FD_ros3_fapl_t *)_fa; - - FUNC_ENTER_NOAPI_NOINIT_NOERR - - HDassert(fa != NULL); /* sanity check */ - - H5MM_xfree(fa); FUNC_LEAVE_NOAPI(SUCCEED) - -} /* end H5FD_ros3_fapl_free() */ - -#if ROS3_STATS - -/*---------------------------------------------------------------------------- - * - * Function: ros3_reset_stats() - * - * Purpose: - * - * Reset the stats collection elements in this virtual file structure. - * - * Clears any set data in stats bins; initializes/zeroes values. - * - * Return: - * - * - SUCCESS: `SUCCEED` - * - FAILURE: `FAIL` - * - Occurs if the file is invalid somehow - * - * Programmer: Jacob Smith - * 2017-12-08 - * - *---------------------------------------------------------------------------- - */ -static herr_t -ros3_reset_stats(H5FD_ros3_t *file) -{ - unsigned i = 0; - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI_NOINIT - -#if ROS3_DEBUG - HDprintf("ros3_reset_stats() called\n"); -#endif - - if (file == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file was null"); - } - - for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { - file->raw[i].bytes = 0; - file->raw[i].count = 0; - file->raw[i].min = (unsigned long long)ROS3_STATS_STARTING_MIN; - file->raw[i].max = 0; - - file->meta[i].bytes = 0; - file->meta[i].count = 0; - file->meta[i].min = (unsigned long long)ROS3_STATS_STARTING_MIN; - file->meta[i].max = 0; - } - -done: - FUNC_LEAVE_NOAPI(ret_value); - -} /* end ros3_reset_stats() */ - -#endif /* ROS3_STATS */ -#if ROS3_STATS - -/*---------------------------------------------------------------------------- - * - * Function: ros3_fprint_stats() - * - * Purpose: - * - * Tabulate and pretty-print statistics for this virtual file. - * - * Should be called upon file close. - * - * Shows number of reads and bytes read, broken down by - * "raw" (H5FD_MEM_DRAW) - * or "meta" (any other flag) - * - * Prints filename and listing of total number of reads and bytes read, - * both as a grand total and separate meta- and rawdata reads. - * - * If any reads were done, prints out two tables: - * - * 1. overview of raw- and metadata reads - * - min (smallest size read) - * - average of size read - * - k,M,G suffixes by powers of 1024 (2^10) - * - max (largest size read) - * 2. tabulation of "bins", sepraring reads into exponentially-larger - * ranges of size. - * - columns for number of reads, total bytes, and average size, with - * separate sub-colums for raw- and metadata reads. - * - each row represents one bin, identified by the top of its range - * - * Bin ranges can be modified with pound-defines at the top of this file. - * - * Bins without any reads in their bounds are not printed. - * - * An "overflow" bin is also present, to catch "big" reads. - * - * Output for all bins (and range ceiling and average size report) - * is divied by powers of 1024. By corollary, four digits before the decimal - * is valid. - * - * - 41080 bytes is represented by 40.177k, not 41.080k - * - 1004.831M represents approx. 1052642000 bytes - * - * Return: - * - * - SUCCESS: `SUCCEED` - * - FAILURE: `FAIL` - * - occurs if the file passed in is invalid - * - TODO: if stream is invalid? how can we check this? - * - * Programmer: Jacob Smith - * - *---------------------------------------------------------------------------- - */ -static herr_t -ros3_fprint_stats(FILE *stream, const H5FD_ros3_t *file) -{ - herr_t ret_value = SUCCEED; - parsed_url_t * purl = NULL; - unsigned i = 0; - unsigned long count_meta = 0; - unsigned long count_raw = 0; - double average_meta = 0.0; - double average_raw = 0.0; - unsigned long long min_meta = (unsigned long long)ROS3_STATS_STARTING_MIN; - unsigned long long min_raw = (unsigned long long)ROS3_STATS_STARTING_MIN; - unsigned long long max_meta = 0; - unsigned long long max_raw = 0; - unsigned long long bytes_raw = 0; - unsigned long long bytes_meta = 0; - double re_dub = 0.0; /* re-usable double variable */ - unsigned suffix_i = 0; - const char suffixes[] = {' ', 'K', 'M', 'G', 'T', 'P'}; - - FUNC_ENTER_NOAPI_NOINIT - - if (stream == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file stream cannot be null"); - } - if (file == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file cannot be null"); - } - if (file->s3r_handle == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "s3 request handle cannot be null"); - } - if (file->s3r_handle->purl == NULL) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parsed url structure cannot be null"); - } - purl = file->s3r_handle->purl; - - /****************** - * PRINT FILENAME * - ******************/ - - HDfprintf(stream, "stats for %s://%s", purl->scheme, purl->host); - if (purl->port != NULL && purl->port[0] != '\0') - HDfprintf(stream, ":%s", purl->port); - if (purl->query != NULL && purl->query[0] != '\0') { - if (purl->path != NULL && purl->path[0] != '\0') - HDfprintf(stream, "/%s", purl->path); - else - HDfprintf(stream, "/"); - HDfprintf(stream, "?%s", purl->query); - } - else if (purl->path != NULL && purl->path[0] != '\0') { - HDfprintf(stream, "/%s", purl->path); - } - HDfprintf(stream, "\n"); - - /******************* - * AGGREGATE STATS * - *******************/ - - for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { - const ros3_statsbin *r = &file->raw[i]; - const ros3_statsbin *m = &file->meta[i]; - - if (m->min < min_meta) - min_meta = m->min; - if (r->min < min_raw) - min_raw = r->min; - if (m->max > max_meta) - max_meta = m->max; - if (r->max > max_raw) - max_raw = r->max; - - count_raw += r->count; - count_meta += m->count; - bytes_raw += r->bytes; - bytes_meta += m->bytes; - } - if (count_raw > 0) - average_raw = (double)bytes_raw / (double)count_raw; - if (count_meta > 0) - average_meta = (double)bytes_meta / (double)count_meta; - - /****************** - * PRINT OVERVIEW * - ******************/ - - HDfprintf(stream, "TOTAL READS: %llu (%llu meta, %llu raw)\n", count_raw + count_meta, count_meta, - count_raw); - HDfprintf(stream, "TOTAL BYTES: %llu (%llu meta, %llu raw)\n", bytes_raw + bytes_meta, bytes_meta, - bytes_raw); - - if (count_raw + count_meta == 0) - goto done; - - /************************* - * PRINT AGGREGATE STATS * - *************************/ - - HDfprintf(stream, "SIZES meta raw\n"); - HDfprintf(stream, " min "); - if (count_meta == 0) { - HDfprintf(stream, " 0.000 "); - } - else { - re_dub = (double)min_meta; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - HDfprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); - } - - if (count_raw == 0) { - HDfprintf(stream, " 0.000 \n"); - } - else { - re_dub = (double)min_raw; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - HDfprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); - } - - HDfprintf(stream, " avg "); - re_dub = (double)average_meta; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - HDfprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); - - re_dub = (double)average_raw; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - HDfprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); - - HDfprintf(stream, " max "); - re_dub = (double)max_meta; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - HDfprintf(stream, "%8.3lf%c ", re_dub, suffixes[suffix_i]); - - re_dub = (double)max_raw; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - HDfprintf(stream, "%8.3lf%c\n", re_dub, suffixes[suffix_i]); - - /****************************** - * PRINT INDIVIDUAL BIN STATS * - ******************************/ - - HDfprintf(stream, "BINS # of reads total bytes average size\n"); - HDfprintf(stream, " up-to meta raw meta raw meta raw\n"); - - for (i = 0; i <= ROS3_STATS_BIN_COUNT; i++) { - const ros3_statsbin *m; - const ros3_statsbin *r; - unsigned long long range_end = 0; - char bm_suffix = ' '; /* bytes-meta */ - double bm_val = 0.0; - char br_suffix = ' '; /* bytes-raw */ - double br_val = 0.0; - char am_suffix = ' '; /* average-meta */ - double am_val = 0.0; - char ar_suffix = ' '; /* average-raw */ - double ar_val = 0.0; - - m = &file->meta[i]; - r = &file->raw[i]; - if (r->count == 0 && m->count == 0) - continue; - - range_end = ros3_stats_boundaries[i]; - - if (i == ROS3_STATS_BIN_COUNT) { - range_end = ros3_stats_boundaries[i - 1]; - HDfprintf(stream, ">"); - } - else { - HDfprintf(stream, " "); - } - - bm_val = (double)m->bytes; - for (suffix_i = 0; bm_val >= 1024.0; suffix_i++) - bm_val /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - bm_suffix = suffixes[suffix_i]; - - br_val = (double)r->bytes; - for (suffix_i = 0; br_val >= 1024.0; suffix_i++) - br_val /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - br_suffix = suffixes[suffix_i]; - - if (m->count > 0) - am_val = (double)(m->bytes) / (double)(m->count); - for (suffix_i = 0; am_val >= 1024.0; suffix_i++) - am_val /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - am_suffix = suffixes[suffix_i]; - - if (r->count > 0) - ar_val = (double)(r->bytes) / (double)(r->count); - for (suffix_i = 0; ar_val >= 1024.0; suffix_i++) - ar_val /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - ar_suffix = suffixes[suffix_i]; - - re_dub = (double)range_end; - for (suffix_i = 0; re_dub >= 1024.0; suffix_i++) - re_dub /= 1024.0; - HDassert(suffix_i < sizeof(suffixes)); - - HDfprintf(stream, " %8.3f%c %7d %7d %8.3f%c %8.3f%c %8.3f%c %8.3f%c\n", re_dub, - suffixes[suffix_i], /* bin ceiling */ - m->count, /* metadata reads */ - r->count, /* rawdata reads */ - bm_val, bm_suffix, /* metadata bytes */ - br_val, br_suffix, /* rawdata bytes */ - am_val, am_suffix, /* metadata average */ - ar_val, ar_suffix); /* rawdata average */ - - fflush(stream); - } - -done: - FUNC_LEAVE_NOAPI(ret_value); - -} /* ros3_fprint_stats */ -#endif /* ROS3_STATS */ +} /* end H5FD_ros3_unlock() */ #endif /* H5_HAVE_ROS3_VFD */ |