00001
00011 #include <sys/types.h>
00012 #include <sys/time.h>
00013 #include <sys/resource.h>
00014 #include <stdlib.h>
00015 #include <stdio.h>
00016 #include <string.h>
00017 #include <fcntl.h>
00018
00019 #include "op_sample_file.h"
00020 #include "odb.h"
00021
00022 #define TEST_FILENAME "test-hash-db.dat"
00023
00024 static int nr_error;
00025
00026 static int verbose = 0;
00027
00028 #define verbprintf(args...) \
00029 do { \
00030 if (verbose) \
00031 printf(args); \
00032 } while (0)
00033
00034 static double used_time(void)
00035 {
00036 struct rusage usage;
00037
00038 getrusage(RUSAGE_SELF, &usage);
00039
00040 return (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) * 1E9 +
00041 ((usage.ru_utime.tv_usec + usage.ru_stime.tv_usec)) * 1000;
00042 }
00043
00044
00045
00046 static void speed_test(int nr_item, char const * test_name)
00047 {
00048 int i;
00049 double begin, end;
00050 odb_t hash;
00051 int rc;
00052
00053 rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header));
00054 if (rc) {
00055 fprintf(stderr, "%s", strerror(rc));
00056 exit(EXIT_FAILURE);
00057 }
00058 begin = used_time();
00059 for (i = 0 ; i < nr_item ; ++i) {
00060 rc = odb_update_node(&hash, i);
00061 if (rc != EXIT_SUCCESS) {
00062 fprintf(stderr, "%s", strerror(rc));
00063 exit(EXIT_FAILURE);
00064 }
00065 }
00066
00067 end = used_time();
00068 odb_close(&hash);
00069
00070 verbprintf("%s: nr item: %d, elapsed: %f ns\n",
00071 test_name, nr_item, (end - begin) / nr_item);
00072 }
00073
00074
00075 static void do_speed_test(void)
00076 {
00077 int i;
00078
00079 for (i = 100000; i <= 10000000; i *= 10) {
00080
00081 speed_test(i, "insert");
00082 speed_test(i, "update");
00083 remove(TEST_FILENAME);
00084 }
00085 }
00086
00087
00088 static int test(int nr_item, int nr_unique_item)
00089 {
00090 int i;
00091 odb_t hash;
00092 int ret;
00093 int rc;
00094
00095 rc = odb_open(&hash, TEST_FILENAME, ODB_RDWR, sizeof(struct opd_header));
00096 if (rc) {
00097 fprintf(stderr, "%s", strerror(rc));
00098 exit(EXIT_FAILURE);
00099 }
00100
00101
00102 for (i = 0 ; i < nr_item ; ++i) {
00103 odb_key_t key = (random() % nr_unique_item) + 1;
00104 rc = odb_update_node(&hash, key);
00105 if (rc != EXIT_SUCCESS) {
00106 fprintf(stderr, "%s", strerror(rc));
00107 exit(EXIT_FAILURE);
00108 }
00109 }
00110
00111 ret = odb_check_hash(&hash);
00112
00113 odb_close(&hash);
00114
00115 remove(TEST_FILENAME);
00116
00117 return ret;
00118 }
00119
00120
00121 static void do_test(void)
00122 {
00123 int i, j;
00124
00125 for (i = 1000; i <= 100000; i *= 10) {
00126 for (j = 100 ; j <= i / 10 ; j *= 10) {
00127 if (test(i, j)) {
00128 fprintf(stderr, "%s:%d failure for %d %d\n",
00129 __FILE__, __LINE__, i, j);
00130 nr_error++;
00131 } else {
00132 verbprintf("test() ok %d %d\n", i, j);
00133 }
00134 }
00135 }
00136 }
00137
00138
00139 static void sanity_check(char const * filename)
00140 {
00141 odb_t hash;
00142 int rc;
00143
00144 rc = odb_open(&hash, filename, ODB_RDONLY, sizeof(struct opd_header));
00145 if (rc) {
00146 fprintf(stderr, "%s", strerror(rc));
00147 exit(EXIT_FAILURE);
00148 }
00149
00150 if (odb_check_hash(&hash)) {
00151 fprintf(stderr, "checking file %s FAIL\n", filename);
00152 ++nr_error;
00153 } else if (verbose) {
00154 odb_hash_stat_t * stats;
00155 stats = odb_hash_stat(&hash);
00156 odb_hash_display_stat(stats);
00157 odb_hash_free_stat(stats);
00158 }
00159
00160 odb_close(&hash);
00161 }
00162
00163 int main(int argc, char * argv[1])
00164 {
00165
00166 if (argc > 1) {
00167 int i;
00168 verbose = 1;
00169 if (!strcmp(argv[1], "--speed"))
00170 goto speed_test;
00171 for (i = 1 ; i < argc ; ++i)
00172 sanity_check(argv[i]);
00173 return 0;
00174 }
00175
00176 speed_test:
00177 remove(TEST_FILENAME);
00178
00179 do_test();
00180
00181 do_speed_test();
00182
00183 if (nr_error)
00184 printf("%d error occured\n", nr_error);
00185
00186 return nr_error ? EXIT_FAILURE : EXIT_SUCCESS;
00187 }