| /** |
| * @file db_test.c |
| * Tests for DB hash |
| * |
| * @remark Copyright 2002 OProfile authors |
| * @remark Read the file COPYING |
| * |
| * @author Philippe Elie |
| */ |
| |
| #include <sys/types.h> |
| #include <sys/time.h> |
| #include <sys/resource.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <fcntl.h> |
| |
| #include "op_sample_file.h" |
| #include "odb.h" |
| |
| #define TEST_FILENAME "test-hash-db.dat" |
| |
| static int nr_error; |
| |
| static int verbose = 0; |
| |
| #define verbprintf(args...) \ |
| do { \ |
| if (verbose) \ |
| printf(args); \ |
| } while (0) |
| |
| static double used_time(void) |
| { |
| struct rusage usage; |
| |
| getrusage(RUSAGE_SELF, &usage); |
| |
| return (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1E9 + |
| ((usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)) * 1000; |
| } |
| |
| |
| /* update nr item */ |
| static void speed_test(int nr_item, char const * test_name) |
| { |
| int i; |
| double begin, end; |
| odb_t hash; |
| int rc; |
| |
| rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header)); |
| if (rc) { |
| fprintf(stderr, "%s", strerror(rc)); |
| exit(EXIT_FAILURE); |
| } |
| begin = used_time(); |
| for (i = 0 ; i < nr_item ; ++i) { |
| rc = odb_update_node(&hash, i); |
| if (rc != EXIT_SUCCESS) { |
| fprintf(stderr, "%s", strerror(rc)); |
| exit(EXIT_FAILURE); |
| } |
| } |
| |
| end = used_time(); |
| odb_close(&hash); |
| |
| verbprintf("%s: nr item: %d, elapsed: %f ns\n", |
| test_name, nr_item, (end - begin) / nr_item); |
| } |
| |
| |
| static void do_speed_test(void) |
| { |
| int i; |
| |
| for (i = 100000; i <= 10000000; i *= 10) { |
| // first test count insertion, second fetch and incr count |
| speed_test(i, "insert"); |
| speed_test(i, "update"); |
| remove(TEST_FILENAME); |
| } |
| } |
| |
| |
| static int test(int nr_item, int nr_unique_item) |
| { |
| int i; |
| odb_t hash; |
| int ret; |
| int rc; |
| |
| rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header)); |
| if (rc) { |
| fprintf(stderr, "%s", strerror(rc)); |
| exit(EXIT_FAILURE); |
| } |
| |
| |
| for (i = 0 ; i < nr_item ; ++i) { |
| odb_key_t key = (random() % nr_unique_item) + 1; |
| rc = odb_update_node(&hash, key); |
| if (rc != EXIT_SUCCESS) { |
| fprintf(stderr, "%s", strerror(rc)); |
| exit(EXIT_FAILURE); |
| } |
| } |
| |
| ret = odb_check_hash(&hash); |
| |
| odb_close(&hash); |
| |
| remove(TEST_FILENAME); |
| |
| return ret; |
| } |
| |
| |
| static void do_test(void) |
| { |
| int i, j; |
| |
| for (i = 1000; i <= 100000; i *= 10) { |
| for (j = 100 ; j <= i / 10 ; j *= 10) { |
| if (test(i, j)) { |
| fprintf(stderr, "%s:%d failure for %d %d\n", |
| __FILE__, __LINE__, i, j); |
| nr_error++; |
| } else { |
| verbprintf("test() ok %d %d\n", i, j); |
| } |
| } |
| } |
| } |
| |
| |
| static void sanity_check(char const * filename) |
| { |
| odb_t hash; |
| int rc; |
| |
| rc = odb_open(&hash, filename, ODB_RDONLY, sizeof(struct opd_header)); |
| if (rc) { |
| fprintf(stderr, "%s", strerror(rc)); |
| exit(EXIT_FAILURE); |
| } |
| |
| if (odb_check_hash(&hash)) { |
| fprintf(stderr, "checking file %s FAIL\n", filename); |
| ++nr_error; |
| } else if (verbose) { |
| odb_hash_stat_t * stats; |
| stats = odb_hash_stat(&hash); |
| odb_hash_display_stat(stats); |
| odb_hash_free_stat(stats); |
| } |
| |
| odb_close(&hash); |
| } |
| |
| int main(int argc, char * argv[1]) |
| { |
| /* if a filename is given take it as: "check this db" */ |
| if (argc > 1) { |
| int i; |
| verbose = 1; |
| if (!strcmp(argv[1], "--speed")) |
| goto speed_test; |
| for (i = 1 ; i < argc ; ++i) |
| sanity_check(argv[i]); |
| return 0; |
| } |
| |
| speed_test: |
| remove(TEST_FILENAME); |
| |
| do_test(); |
| |
| do_speed_test(); |
| |
| if (nr_error) |
| printf("%d error occured\n", nr_error); |
| |
| return nr_error ? EXIT_FAILURE : EXIT_SUCCESS; |
| } |