~ubuntu-branches/ubuntu/vivid/ctdb/vivid-proposed

« back to all changes in this revision

Viewing changes to tests/ctdb_fetch.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Parent
  • Date: 2008-04-26 15:21:27 UTC
  • Revision ID: james.westby@ubuntu.com-20080426152127-58mv5ojv5q362ise
Tags: upstream-1.0.34+git200804242206
ImportĀ upstreamĀ versionĀ 1.0.34+git200804242206

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   simple ctdb benchmark
 
3
 
 
4
   Copyright (C) Andrew Tridgell  2006
 
5
 
 
6
   This program is free software; you can redistribute it and/or modify
 
7
   it under the terms of the GNU General Public License as published by
 
8
   the Free Software Foundation; either version 3 of the License, or
 
9
   (at your option) any later version.
 
10
   
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
   
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program; if not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include "includes.h"
 
21
#include "lib/events/events.h"
 
22
#include "system/filesys.h"
 
23
#include "popt.h"
 
24
#include "cmdline.h"
 
25
 
 
26
#include <sys/time.h>
 
27
#include <time.h>
 
28
 
 
29
static struct timeval tp1,tp2;
 
30
 
 
31
static void start_timer(void)
 
32
{
 
33
        gettimeofday(&tp1,NULL);
 
34
}
 
35
 
 
36
static double end_timer(void)
 
37
{
 
38
        gettimeofday(&tp2,NULL);
 
39
        return (tp2.tv_sec + (tp2.tv_usec*1.0e-6)) - 
 
40
                (tp1.tv_sec + (tp1.tv_usec*1.0e-6));
 
41
}
 
42
 
 
43
 
 
44
static int timelimit = 10;
 
45
static int num_records = 10;
 
46
static int num_nodes;
 
47
static int msg_count;
 
48
 
 
49
#define TESTKEY "testkey"
 
50
 
 
51
/*
 
52
  fetch a record
 
53
  store a expanded record
 
54
  send a message to next node to tell it to do the same
 
55
*/
 
56
static void bench_fetch_1node(struct ctdb_context *ctdb)
 
57
{
 
58
        TDB_DATA key, data, nulldata;
 
59
        struct ctdb_db_context *ctdb_db;
 
60
        TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 
61
        int dest, ret;
 
62
        struct ctdb_record_handle *h;
 
63
 
 
64
        key.dptr = discard_const(TESTKEY);
 
65
        key.dsize = strlen(TESTKEY);
 
66
 
 
67
        ctdb_db = ctdb_db_handle(ctdb, "test.tdb");
 
68
 
 
69
        h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
 
70
        if (h == NULL) {
 
71
                printf("Failed to fetch record '%s' on node %d\n", 
 
72
                       (const char *)key.dptr, ctdb_get_pnn(ctdb));
 
73
                talloc_free(tmp_ctx);
 
74
                return;
 
75
        }
 
76
 
 
77
        if (data.dsize > 1000) {
 
78
                data.dsize = 0;
 
79
        }
 
80
 
 
81
        if (data.dsize == 0) {
 
82
                data.dptr = (uint8_t *)talloc_asprintf(tmp_ctx, "Test data\n");
 
83
        }
 
84
        data.dptr = (uint8_t *)talloc_asprintf_append((char *)data.dptr, 
 
85
                                                      "msg_count=%d on node %d\n",
 
86
                                                      msg_count, ctdb_get_pnn(ctdb));
 
87
        data.dsize = strlen((const char *)data.dptr)+1;
 
88
 
 
89
        ret = ctdb_record_store(h, data);
 
90
        talloc_free(h);
 
91
        if (ret != 0) {
 
92
                printf("Failed to store record\n");
 
93
        }
 
94
 
 
95
        talloc_free(tmp_ctx);
 
96
 
 
97
        /* tell the next node to do the same */
 
98
        nulldata.dptr = NULL;
 
99
        nulldata.dsize = 0;
 
100
 
 
101
        dest = (ctdb_get_pnn(ctdb) + 1) % num_nodes;
 
102
        ctdb_send_message(ctdb, dest, 0, nulldata);
 
103
}
 
104
 
 
105
/*
 
106
  handler for messages in bench_ring()
 
107
*/
 
108
static void message_handler(struct ctdb_context *ctdb, uint64_t srvid, 
 
109
                            TDB_DATA data, void *private_data)
 
110
{
 
111
        msg_count++;
 
112
        bench_fetch_1node(ctdb);
 
113
}
 
114
 
 
115
 
 
116
/*
 
117
  benchmark the following:
 
118
 
 
119
  fetch a record
 
120
  store a expanded record
 
121
  send a message to next node to tell it to do the same
 
122
 
 
123
*/
 
124
static void bench_fetch(struct ctdb_context *ctdb, struct event_context *ev)
 
125
{
 
126
        int pnn=ctdb_get_pnn(ctdb);
 
127
 
 
128
        if (pnn == num_nodes - 1) {
 
129
                bench_fetch_1node(ctdb);
 
130
        }
 
131
        
 
132
        start_timer();
 
133
 
 
134
        while (end_timer() < timelimit) {
 
135
                if (pnn == 0 && msg_count % 100 == 0) {
 
136
                        printf("Fetch: %.2f msgs/sec\r", msg_count/end_timer());
 
137
                        fflush(stdout);
 
138
                }
 
139
                if (event_loop_once(ev) != 0) {
 
140
                        printf("Event loop failed!\n");
 
141
                        break;
 
142
                }
 
143
        }
 
144
 
 
145
        printf("Fetch: %.2f msgs/sec\n", msg_count/end_timer());
 
146
}
 
147
 
 
148
enum my_functions {FUNC_FETCH=1};
 
149
 
 
150
/*
 
151
  ctdb call function to fetch a record
 
152
*/
 
153
static int fetch_func(struct ctdb_call_info *call)
 
154
{
 
155
        call->reply_data = &call->record_data;
 
156
        return 0;
 
157
}
 
158
 
 
159
/*
 
160
  handler for reconfigure message
 
161
*/
 
162
static void reconfigure_handler(struct ctdb_context *ctdb, uint64_t srvid, 
 
163
                                TDB_DATA data, void *private_data)
 
164
{
 
165
        int *ready = (int *)private_data;
 
166
        *ready = 1;
 
167
}
 
168
 
 
169
/*
 
170
  main program
 
171
*/
 
172
int main(int argc, const char *argv[])
 
173
{
 
174
        struct ctdb_context *ctdb;
 
175
        struct ctdb_db_context *ctdb_db;
 
176
 
 
177
        struct poptOption popt_options[] = {
 
178
                POPT_AUTOHELP
 
179
                POPT_CTDB_CMDLINE
 
180
                { "timelimit", 't', POPT_ARG_INT, &timelimit, 0, "timelimit", "integer" },
 
181
                { "num-records", 'r', POPT_ARG_INT, &num_records, 0, "num_records", "integer" },
 
182
                { NULL, 'n', POPT_ARG_INT, &num_nodes, 0, "num_nodes", "integer" },
 
183
                POPT_TABLEEND
 
184
        };
 
185
        int opt;
 
186
        const char **extra_argv;
 
187
        int extra_argc = 0;
 
188
        int ret;
 
189
        poptContext pc;
 
190
        struct event_context *ev;
 
191
        struct ctdb_call call;
 
192
        int cluster_ready=0;
 
193
 
 
194
        pc = poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST);
 
195
 
 
196
        while ((opt = poptGetNextOpt(pc)) != -1) {
 
197
                switch (opt) {
 
198
                default:
 
199
                        fprintf(stderr, "Invalid option %s: %s\n", 
 
200
                                poptBadOption(pc, 0), poptStrerror(opt));
 
201
                        exit(1);
 
202
                }
 
203
        }
 
204
 
 
205
        /* talloc_enable_leak_report_full(); */
 
206
 
 
207
        /* setup the remaining options for the main program to use */
 
208
        extra_argv = poptGetArgs(pc);
 
209
        if (extra_argv) {
 
210
                extra_argv++;
 
211
                while (extra_argv[extra_argc]) extra_argc++;
 
212
        }
 
213
 
 
214
        ev = event_context_init(NULL);
 
215
 
 
216
        ctdb = ctdb_cmdline_client(ev);
 
217
 
 
218
        ctdb_set_message_handler(ctdb, CTDB_SRVID_RECONFIGURE, reconfigure_handler, 
 
219
                                 &cluster_ready);
 
220
 
 
221
        /* attach to a specific database */
 
222
        ctdb_db = ctdb_attach(ctdb, "test.tdb", false);
 
223
        if (!ctdb_db) {
 
224
                printf("ctdb_attach failed - %s\n", ctdb_errstr(ctdb));
 
225
                exit(1);
 
226
        }
 
227
 
 
228
        ret = ctdb_set_call(ctdb_db, fetch_func, FUNC_FETCH);
 
229
 
 
230
        ctdb_set_message_handler(ctdb, 0, message_handler, &msg_count);
 
231
 
 
232
        printf("Waiting for cluster\n");
 
233
        while (1) {
 
234
                uint32_t recmode=1;
 
235
                ctdb_ctrl_getrecmode(ctdb, ctdb, timeval_zero(), CTDB_CURRENT_NODE, &recmode);
 
236
                if (recmode == 0) break;
 
237
                event_loop_once(ev);
 
238
        }
 
239
 
 
240
        bench_fetch(ctdb, ev);
 
241
 
 
242
        ZERO_STRUCT(call);
 
243
        call.key.dptr = discard_const(TESTKEY);
 
244
        call.key.dsize = strlen(TESTKEY);
 
245
 
 
246
        printf("Fetching final record\n");
 
247
 
 
248
        /* fetch the record */
 
249
        call.call_id = FUNC_FETCH;
 
250
        call.call_data.dptr = NULL;
 
251
        call.call_data.dsize = 0;
 
252
 
 
253
        ret = ctdb_call(ctdb_db, &call);
 
254
        if (ret == -1) {
 
255
                printf("ctdb_call FUNC_FETCH failed - %s\n", ctdb_errstr(ctdb));
 
256
                exit(1);
 
257
        }
 
258
 
 
259
        printf("DATA:\n%s\n", (char *)call.reply_data.dptr);
 
260
 
 
261
        return 0;
 
262
}