1 /** 2 * @file db_test.c 3 * Tests for DB hash 4 * 5 * @remark Copyright 2002 OProfile authors 6 * @remark Read the file COPYING 7 * 8 * @author Philippe Elie 9 */ 10 11 #include <sys/types.h> 12 #include <sys/time.h> 13 #include <sys/resource.h> 14 #include <stdlib.h> 15 #include <stdio.h> 16 #include <string.h> 17 #include <fcntl.h> 18 19 #include "op_sample_file.h" 20 #include "odb.h" 21 22 #define TEST_FILENAME "test-hash-db.dat" 23 24 static int nr_error; 25 26 static int verbose = 0; 27 28 #define verbprintf(args...) \ 29 do { \ 30 if (verbose) \ 31 printf(args); \ 32 } while (0) 33 34 static double used_time(void) 35 { 36 struct rusage usage; 37 38 getrusage(RUSAGE_SELF, &usage); 39 40 return (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1E9 + 41 ((usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)) * 1000; 42 } 43 44 45 /* update nr item */ 46 static void speed_test(int nr_item, char const * test_name) 47 { 48 int i; 49 double begin, end; 50 odb_t hash; 51 int rc; 52 53 rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header)); 54 if (rc) { 55 fprintf(stderr, "%s", strerror(rc)); 56 exit(EXIT_FAILURE); 57 } 58 begin = used_time(); 59 for (i = 0 ; i < nr_item ; ++i) { 60 rc = odb_update_node(&hash, i); 61 if (rc != EXIT_SUCCESS) { 62 fprintf(stderr, "%s", strerror(rc)); 63 exit(EXIT_FAILURE); 64 } 65 } 66 67 end = used_time(); 68 odb_close(&hash); 69 70 verbprintf("%s: nr item: %d, elapsed: %f ns\n", 71 test_name, nr_item, (end - begin) / nr_item); 72 } 73 74 75 static void do_speed_test(void) 76 { 77 int i; 78 79 for (i = 100000; i <= 10000000; i *= 10) { 80 // first test count insertion, second fetch and incr count 81 speed_test(i, "insert"); 82 speed_test(i, "update"); 83 remove(TEST_FILENAME); 84 } 85 } 86 87 88 static int test(int nr_item, int nr_unique_item) 89 { 90 int i; 91 odb_t hash; 92 int ret; 93 int rc; 94 95 rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header)); 96 if (rc) { 97 fprintf(stderr, "%s", strerror(rc)); 98 exit(EXIT_FAILURE); 99 } 100 101 102 for (i = 0 ; i < nr_item ; ++i) { 103 odb_key_t key = (random() % nr_unique_item) + 1; 104 rc = odb_update_node(&hash, key); 105 if (rc != EXIT_SUCCESS) { 106 fprintf(stderr, "%s", strerror(rc)); 107 exit(EXIT_FAILURE); 108 } 109 } 110 111 ret = odb_check_hash(&hash); 112 113 odb_close(&hash); 114 115 remove(TEST_FILENAME); 116 117 return ret; 118 } 119 120 121 static void do_test(void) 122 { 123 int i, j; 124 125 for (i = 1000; i <= 100000; i *= 10) { 126 for (j = 100 ; j <= i / 10 ; j *= 10) { 127 if (test(i, j)) { 128 fprintf(stderr, "%s:%d failure for %d %d\n", 129 __FILE__, __LINE__, i, j); 130 nr_error++; 131 } else { 132 verbprintf("test() ok %d %d\n", i, j); 133 } 134 } 135 } 136 } 137 138 139 static void sanity_check(char const * filename) 140 { 141 odb_t hash; 142 int rc; 143 144 rc = odb_open(&hash, filename, ODB_RDONLY, sizeof(struct opd_header)); 145 if (rc) { 146 fprintf(stderr, "%s", strerror(rc)); 147 exit(EXIT_FAILURE); 148 } 149 150 if (odb_check_hash(&hash)) { 151 fprintf(stderr, "checking file %s FAIL\n", filename); 152 ++nr_error; 153 } else if (verbose) { 154 odb_hash_stat_t * stats; 155 stats = odb_hash_stat(&hash); 156 odb_hash_display_stat(stats); 157 odb_hash_free_stat(stats); 158 } 159 160 odb_close(&hash); 161 } 162 163 int main(int argc, char * argv[1]) 164 { 165 /* if a filename is given take it as: "check this db" */ 166 if (argc > 1) { 167 int i; 168 verbose = 1; 169 if (!strcmp(argv[1], "--speed")) 170 goto speed_test; 171 for (i = 1 ; i < argc ; ++i) 172 sanity_check(argv[i]); 173 return 0; 174 } 175 176 speed_test: 177 remove(TEST_FILENAME); 178 179 do_test(); 180 181 do_speed_test(); 182 183 if (nr_error) 184 printf("%d error occured\n", nr_error); 185 186 return nr_error ? EXIT_FAILURE : EXIT_SUCCESS; 187 } 188