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
used_time(void)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 */
speed_test(int nr_item,char const * test_name)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
do_speed_test(void)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
test(int nr_item,int nr_unique_item)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
do_test(void)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
sanity_check(char const * filename)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
main(int argc,char * argv[1])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