blob: fe0b189c3333f4f59e3088a6f6fe095f32b7670a [file] [log] [blame]
/**
* @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;
}