aboutsummaryrefslogtreecommitdiff
path: root/flatcc/test/load_test/load_test.c
blob: 466f5ccbcec82b7b244891b6fb24044cf73512a0 (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#include <stdio.h>
#include "monster_test_builder.h"
#include "flatcc/support/elapsed.h"

#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(MyGame_Example, x)
#define nsc(x) FLATBUFFERS_WRAP_NAMESPACE(flatbuffers, x)
#define c_vec_len(V) (sizeof(V)/sizeof((V)[0]))

#define MEASURE_DECODE 1
#define MONSTER_REP 1000
#define NAME_REP 100
#define INVENTORY_REP 100

static uint8_t invdata[1000];

static ns(Monster_ref_t) create_monster(flatcc_builder_t *B)
{
    size_t i;

    ns(Monster_start(B));
    ns(Monster_name_start(B));
    for (i = 0; i < NAME_REP; ++i) {
        nsc(string_append(B, "Monster", 7));
    }
    ns(Monster_name_end(B));
    ns(Monster_inventory_start(B));
    for (i = 0; i < INVENTORY_REP; ++i) {
        nsc(uint8_vec_append(B, invdata, c_vec_len(invdata)));
    }
    ns(Monster_inventory_end(B));
    return ns(Monster_end(B));
}

static ns(Monster_vec_ref_t) create_monsters(flatcc_builder_t *B)
{
    size_t i;
    ns(Monster_ref_t) m;

    ns(Monster_vec_start(B));
    for (i = 0; i < MONSTER_REP; ++i) {
        m = create_monster(B);
        assert(m);
        ns(Monster_vec_push(B, m));
    }
    return ns(Monster_vec_end(B));
}

static int create_root_monster(flatcc_builder_t *B)
{
    ns(Monster_vec_ref_t) mv;

    flatcc_builder_reset(B);
    ns(Monster_start_as_root(B));
    ns(Monster_name_create_str(B, "root_monster"));
    mv = create_monsters(B);
    assert(mv);
    ns(Monster_testarrayoftables_add(B, mv));
    ns(Monster_end_as_root(B));
    return 0;
}

#if MEASURE_DECODE
static int verify_monster(const char *base, ns(Monster_table_t) mon)
{
    size_t i;
    nsc(string_t) s = ns(Monster_name(mon));
    /*
     * This only works because it is a byte, otherwise
     * vec_at should be used to convert endian format.
     */
    const uint8_t *inv = ns(Monster_inventory(mon));

    if (nsc(string_len(s)) != NAME_REP * 7) {
        assert(0);
        return -1;
    }
    if (nsc(uint8_vec_len(inv)) != INVENTORY_REP * c_vec_len(invdata)) {
        assert(0);
        return -1;
    }
    for (i = 0; i < NAME_REP; ++i) {
        if (memcmp(s + i * 7, "Monster", 7)) {
            printf("failed monster name at %lu: %s\n", (unsigned long)i, s ? s : "NULL");
            printf("offset: %ld\n", (long)(s + i * 7 - base));
            assert(0);
            return -1;
        }
    }
    for (i = 0; i < INVENTORY_REP; ++i) {
        if (memcmp(inv + i * c_vec_len(invdata), invdata, c_vec_len(invdata))) {
            assert(0);
            return -1;
        }
    }
    return 0;
}
#endif

int main(int argc, char *argv[])
{
    FILE *fp;
    void *buffer;
    size_t size;
    flatcc_builder_t builder, *B;
    ns(Monster_table_t) mon;
    ns(Monster_vec_t) mv;
    double t1, t2;
    int rep = 10, i;
    int ret = 0;

#if MEASURE_DECODE
    size_t j;
#endif

    (void)argc;
    (void)argv;

    B = &builder;
    flatcc_builder_init(B);
    create_root_monster(B);
    buffer = flatcc_builder_finalize_buffer(B, &size);
    fp = fopen("monster_load_test.dat", "wb");
    if (!fp) {
        ret = -1;
        goto done;
    }
    ret |= size != fwrite(buffer, 1, size, fp);
    fclose(fp);
    if (ret) {
        goto done;
    }
    printf("buffer size: %lu\n", (unsigned long)size);
    printf("start timing ...\n");
    t1 = elapsed_realtime();
    for (i = 0; i < rep; ++i) {
        create_root_monster(B);
        flatcc_builder_copy_buffer(B, buffer, size);
        mon = ns(Monster_as_root(buffer));
        ret |= strcmp(ns(Monster_name(mon)), "root_monster");
        assert(ret == 0);
        mv = ns(Monster_testarrayoftables(mon));
        /* Negated logic, 0 is OK. */
        ret |=  ns(Monster_vec_len(mv)) != MONSTER_REP;
        assert(ret == 0);
#if MEASURE_DECODE
        for (j = 0; j < MONSTER_REP; ++j) {
            ret |= verify_monster(buffer, ns(Monster_vec_at(mv, j)));
            assert(ret == 0);
        }
#endif
        if (ret) {
            goto done;
        }
    }
    t2 = elapsed_realtime();
    show_benchmark("encode and partially decode large buffer", t1, t2, size, rep, 0);
done:
    flatcc_builder_clear(B);
    free(buffer);
    if (ret) {
        printf("load test failed\n");
    }
    return ret;
}