summaryrefslogtreecommitdiff
path: root/c_src/permdbtest.c
blob: 7fb17b7b5b12ce21dc6255f12f68c38d31faf866 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <stdarg.h>
#include <stdint.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <err.h>
#include <sys/resource.h>
#include "permdb.h"
#ifdef HAVE_COMMON_CRYPTO
#include <CommonCrypto/CommonDigest.h>
#else
#include <rhash.h>
#endif
static void
usage()
{
        errx(1, "usage: permdbtest <store> <entries> <datasize> <fsync>");
}

void *
gentestdata(long long nentries)
{
#ifndef HAVE_COMMON_CRYPTO
        rhash_library_init();
#endif
        unsigned char *testdata = malloc(nentries * 32 * 2);
        for (long long i = 0; i < nentries; i++) {
                uint32_t key[2];
                uint32_t value[2];
                key[0] = htonl(i);
                key[1] = htonl(0);
                value[0] = htonl(i);
                value[1] = htonl(1);
#ifdef HAVE_COMMON_CRYPTO
                CC_SHA256(key, sizeof(key), testdata + i * 32 * 2);
                CC_SHA256(value, sizeof(value), testdata + i * 32 * 2 + 32);
#else
                rhash_msg(RHASH_SHA256, key, sizeof(key), testdata + i * 32 * 2);
                rhash_msg(RHASH_SHA256, value, sizeof(value), testdata + i * 32 * 2 + 32);
#endif
        }
        return testdata;
}

int
main(int argc, char *argv[])
{
        if (argc != 5) {
                usage();
        }
        const char *store = argv[1];
        long long nentries = atol(argv[2]);
        int datasize = atoi(argv[3]);
        int nfsync = atoi(argv[4]);

        permdb_object *state = permdb_alloc(store);

        if (state == NULL) {
                errx(1, "permdb object creation failed\n");
        }

        printf("generating test data\n");
        void *testdata = gentestdata(nentries);
        printf("inserting test data\n");
        int written_since_fsync = 0;
        int datamultiplier = datasize / 32;
        if (datasize % 32 != 0) {
                printf("datasize %d not multiple of 32, truncating to %d\n", datasize, datamultiplier * 32);
        }
        datasize = datamultiplier * 32;
        unsigned char *value = malloc(datasize);
        for (long long i = 0; i < nentries; i++) {
		unsigned char *key = testdata + i * 32 * 2;
                for (int j = 0; j < datamultiplier; j++) {
                        memcpy(value + j * 32, testdata + i * 32 * 2 + 32, 32);
                }
                
                int result = addvalue(state, key, 32, value, datasize);
                if (result < 0) {
                        errx(1, "addvalue: %d\n", result);
                }
                written_since_fsync += 1;
                if (written_since_fsync >= nfsync) {
                        result = committree(state);
                        if (result < 0) {
                                errx(1, "committree: %d\n", result);
                        }
                        written_since_fsync = 0;
                }
        }
        free(value);
        int result = committree(state);
        if (result < 0) {
                errx(1, "committree: %d\n", result);
        }
        written_since_fsync = 0;
        
        printf("reading test data\n");
        for (long long i = 0; i < nentries; i++) {
                unsigned char *key = testdata + i * 32 * 2;
                size_t datalen;
                unsigned char *result = getvalue(state, key, 32, &datalen);
                if (datalen != datasize) {
                        errx(1, "getvalue returned datalen %zd\n", datalen);
                }
                for (int j = 0; j < datamultiplier; j++) {
                        if (memcmp(result + j * 32, testdata + i * 32 * 2 + 32, 32)) {
                                errx(1, "getvalue returned incorrect data\n");
                        }
                }
                free(result);
        }

        struct rusage rusage;
        getrusage(RUSAGE_SELF, &rusage);
        fprintf(stderr, "user %ld.%d sys %ld.%d maxrss %ld M\n", rusage.ru_utime.tv_sec, (int)rusage.ru_utime.tv_usec, rusage.ru_stime.tv_sec, (int)rusage.ru_utime.tv_usec, rusage.ru_maxrss/1024);

        free(testdata);
        permdb_free(state);

        return 0;
}