static bool compare_histogram(struct hdr_histogram* a, struct hdr_histogram* b) { size_t a_size = hdr_get_memory_size(a); size_t b_size = hdr_get_memory_size(b); if (a_size == b_size && memcmp(a, b, a_size) == 0) { return true; } printf("Sizes a: %zu, b: %zu\n", a_size, b_size); struct hdr_iter iter_a; struct hdr_iter iter_b; hdr_iter_init(&iter_a, a); hdr_iter_init(&iter_b, b); while (hdr_iter_next(&iter_a) && hdr_iter_next(&iter_b)) { if (iter_a.count_at_index != iter_b.count_at_index || iter_a.value_from_index != iter_b.value_from_index) { printf( "A - value: %"PRIu64", count: %"PRIu64", B - value: %"PRIu64", count: %"PRIu64"\n", iter_a.value_from_index, iter_a.count_at_index, iter_b.value_from_index, iter_b.count_at_index); } } return false; }
static char* test_linear_values() { load_histograms(); struct hdr_iter iter; int index; // Raw Histogram hdr_iter_linear_init(&iter, raw_histogram, 100000); index = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.linear.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Count at 0 is not 10000", count_added_in_this_bucket == 10000); } else if (index == 999) { mu_assert("Count at 999 is not 1", count_added_in_this_bucket == 1); } else { mu_assert("Count should be 0", count_added_in_this_bucket == 0); } index++; } mu_assert("Should of met 1000 values", index == 1000); // Corrected Histogram hdr_iter_linear_init(&iter, cor_histogram, 10000); index = 0; int64_t total_added_count = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.linear.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Count at 0 is not 10001", count_added_in_this_bucket == 10001); } total_added_count += count_added_in_this_bucket; index++; } mu_assert("Should of met 10001 values", index == 10000); mu_assert("Should of met 20000 counts", total_added_count == 20000); return 0; }
static char* test_logarithmic_values() { load_histograms(); struct hdr_iter iter; int index; hdr_iter_log_init(&iter, raw_histogram, 10000, 2.0); index = 0; while(hdr_iter_next(&iter)) { long count_added_in_this_bucket = iter.specifics.log.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Raw Logarithmic 10 msec bucket # 0 added a count of 10000", 10000 == count_added_in_this_bucket); } else if (index == 14) { mu_assert("Raw Logarithmic 10 msec bucket # 14 added a count of 1", 1 == count_added_in_this_bucket); } else { mu_assert("Raw Logarithmic 10 msec bucket added a count of 0", 0 == count_added_in_this_bucket); } index++; } mu_assert("Should of seen 14 values", index - 1 == 14); hdr_iter_log_init(&iter, cor_histogram, 10000, 2.0); index = 0; int total_added_count = 0; while (hdr_iter_next(&iter)) { long count_added_in_this_bucket = iter.specifics.log.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Corrected Logarithmic 10 msec bucket # 0 added a count of 10001", 10001 == count_added_in_this_bucket); } total_added_count += count_added_in_this_bucket; index++; } mu_assert("Should of seen 14 values", index - 1 == 14); mu_assert("Should of seen count of 20000", total_added_count == 20000); return 0; }
static char* test_recorded_values() { load_histograms(); struct hdr_iter iter; int index; // Raw Histogram hdr_iter_recorded_init(&iter, raw_histogram); index = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.recorded.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Value at 0 is not 10000", count_added_in_this_bucket == 10000); } else { mu_assert("Value at 1 is not 1", count_added_in_this_bucket == 1); } index++; } mu_assert("Should have encountered 2 values", index == 2); // Corrected Histogram hdr_iter_recorded_init(&iter, cor_histogram); index = 0; int64_t total_added_count = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.recorded.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Count at 0 is not 10000", count_added_in_this_bucket == 10000); } mu_assert("Count should not be 0", iter.count_at_index != 0); mu_assert("Count at value iterated to should be count added in this step", iter.count_at_index == count_added_in_this_bucket); total_added_count += count_added_in_this_bucket; index++; } mu_assert("Total counts should be 20000", total_added_count == 20000); return 0; }
long double stats_within_stdev(stats *stats, long double mean, long double stdev, uint64_t n) { long double upper = mean + (stdev * n); long double lower = mean - (stdev * n); if (stats->histogram != NULL) { int64_t total_count = stats->histogram->total_count; if (total_count == 0) { return 0.0; } int64_t upper_value = upper; int64_t lower_value = lower; struct hdr_iter iter; hdr_iter_init(&iter, stats->histogram); int64_t lower_count = 0; int64_t upper_count = 0; bool found_upper = false; while (hdr_iter_next(&iter)) { if (lower_value > iter.value_from_index) { lower_count = iter.count_to_index; } if (upper_value < iter.highest_equivalent_value) { upper_count = iter.count_to_index; found_upper = true; break; } } if (!found_upper) { upper_count = total_count; } return 100.0 * (upper_count - lower_count) / (double) total_count; } uint64_t sum = 0; for (uint64_t i = 0; i < stats->limit; i++) { uint64_t x = stats->data[i]; if (x >= lower && x <= upper) sum++; } return (sum / (long double) stats->limit) * 100; }
static bool compare_histogram(struct hdr_histogram* a, struct hdr_histogram* b) { if (a->counts_len != b->counts_len) { printf( "a.counts_len = %"PRIu32", b.counts_len = %"PRIu32"\n", a->counts_len, b->counts_len); return false; } int64_t a_max = hdr_max(a); int64_t b_max = hdr_max(b); if (a_max != b_max) { printf("a.max = %"PRIu64", b.max = %"PRIu64"\n", a_max, b_max); // return false; } int64_t a_min = hdr_min(a); int64_t b_min = hdr_min(b); if (a_min != b_min) { printf("a.min = %"PRIu64", b.min = %"PRIu64"\n", a_min, b_min); // return false; } size_t a_size = hdr_get_memory_size(a); size_t b_size = hdr_get_memory_size(b); if (a_size != b_size) { printf("a.size: %zu, b.size: %zu\n", a_size, b_size); return false; } size_t counts_size = a->counts_len * sizeof(int64_t); if (memcmp(a->counts, b->counts, counts_size) == 0) { return true; } printf("%s\n", "Counts incorrect"); struct hdr_iter iter_a; struct hdr_iter iter_b; hdr_iter_init(&iter_a, a); hdr_iter_init(&iter_b, b); while (hdr_iter_next(&iter_a) && hdr_iter_next(&iter_b)) { if (iter_a.count != iter_b.count || iter_a.value != iter_b.value) { printf( "A - value: %"PRIu64", count: %"PRIu64", B - value: %"PRIu64", count: %"PRIu64"\n", iter_a.value, iter_a.count, iter_b.value, iter_b.count); } } return false; }
static char* log_reader_aggregates_into_single_histogram() { const char* file_name = "histogram.log"; hdr_timespec timestamp; hdr_timespec interval; hdr_gettime(×tamp); interval.tv_sec = 5; interval.tv_nsec = 2000000; struct hdr_log_writer writer; struct hdr_log_reader reader; hdr_log_writer_init(&writer); hdr_log_reader_init(&reader); int rc = 0; FILE* log_file = fopen(file_name, "w+"); hdr_log_write_header(&writer, log_file, "Test log", ×tamp); hdr_log_write(&writer, log_file, ×tamp, &interval, cor_histogram); hdr_log_write(&writer, log_file, ×tamp, &interval, raw_histogram); fflush(log_file); fclose(log_file); log_file = fopen(file_name, "r"); struct hdr_histogram* histogram; hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &histogram); rc = hdr_log_read_header(&reader, log_file); mu_assert("Failed header read", validate_return_code(rc)); rc = hdr_log_read(&reader, log_file, &histogram, NULL, NULL); mu_assert("Failed corrected read", validate_return_code(rc)); rc = hdr_log_read(&reader, log_file, &histogram, NULL, NULL); mu_assert("Failed raw read", validate_return_code(rc)); struct hdr_iter iter; hdr_iter_recorded_init(&iter, histogram); int64_t expected_total_count = raw_histogram->total_count + cor_histogram->total_count; mu_assert( "Total counts incorrect", compare_int64(histogram->total_count, expected_total_count)); while (hdr_iter_next(&iter)) { int64_t count = iter.count; int64_t value = iter.value; int64_t expected_count = hdr_count_at_value(raw_histogram, value) + hdr_count_at_value(cor_histogram, value); mu_assert("Incorrect count", compare_int64(count, expected_count)); } fclose(log_file); remove(file_name); free(histogram); return 0; }