]> git.saurik.com Git - redis.git/blame - src/redis-benchmark.c
Change protocol from bulk to inline in redis-benchmark
[redis.git] / src / redis-benchmark.c
CommitLineData
ed9b544e 1/* Redis benchmark utility.
2 *
12d090d2 3 * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
ed9b544e 4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Redis nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without
16 * specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
5f5b9840 31#include "fmacros.h"
32
ed9b544e 33#include <stdio.h>
34#include <string.h>
35#include <stdlib.h>
36#include <unistd.h>
37#include <errno.h>
38#include <sys/time.h>
39#include <signal.h>
40#include <assert.h>
41
42#include "ae.h"
43#include "anet.h"
44#include "sds.h"
45#include "adlist.h"
46#include "zmalloc.h"
47
48#define REPLY_INT 0
49#define REPLY_RETCODE 1
50#define REPLY_BULK 2
6c4e61b3 51#define REPLY_MBULK 3
ed9b544e 52
53#define CLIENT_CONNECTING 0
54#define CLIENT_SENDQUERY 1
55#define CLIENT_READREPLY 2
56
57#define MAX_LATENCY 5000
58
59#define REDIS_NOTUSED(V) ((void) V)
60
61static struct config {
58cd7103 62 int debug;
ed9b544e 63 int numclients;
64 int requests;
65 int liveclients;
66 int donerequests;
67 int keysize;
68 int datasize;
57172ffb 69 int randomkeys;
ecfaf6da 70 int randomkeys_keyspacelen;
ed9b544e 71 aeEventLoop *el;
72 char *hostip;
73 int hostport;
74 int keepalive;
75 long long start;
76 long long totlatency;
77 int *latency;
ed0dd554 78 char *title;
ed9b544e 79 list *clients;
80 int quiet;
81 int loop;
266373b2 82 int idlemode;
ed9b544e 83} config;
84
85typedef struct _client {
86 int state;
87 int fd;
88 sds obuf;
89 sds ibuf;
2fd30952 90 int mbulk; /* Number of elements in an mbulk reply */
ed9b544e 91 int readlen; /* readlen == -1 means read a single line */
58cd7103 92 int totreceived;
ed9b544e 93 unsigned int written; /* bytes of 'obuf' already written */
94 int replytype;
95 long long start; /* start time in milliseconds */
96} *client;
97
98/* Prototypes */
99static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask);
100static void createMissingClients(client c);
101
102/* Implementation */
103static long long mstime(void) {
104 struct timeval tv;
105 long long mst;
106
107 gettimeofday(&tv, NULL);
108 mst = ((long)tv.tv_sec)*1000;
109 mst += tv.tv_usec/1000;
110 return mst;
111}
112
113static void freeClient(client c) {
114 listNode *ln;
115
116 aeDeleteFileEvent(config.el,c->fd,AE_WRITABLE);
117 aeDeleteFileEvent(config.el,c->fd,AE_READABLE);
118 sdsfree(c->ibuf);
119 sdsfree(c->obuf);
120 close(c->fd);
121 zfree(c);
122 config.liveclients--;
123 ln = listSearchKey(config.clients,c);
124 assert(ln != NULL);
125 listDelNode(config.clients,ln);
126}
127
128static void freeAllClients(void) {
129 listNode *ln = config.clients->head, *next;
130
131 while(ln) {
132 next = ln->next;
133 freeClient(ln->value);
134 ln = next;
135 }
136}
137
138static void resetClient(client c) {
139 aeDeleteFileEvent(config.el,c->fd,AE_WRITABLE);
140 aeDeleteFileEvent(config.el,c->fd,AE_READABLE);
266373b2 141 aeCreateFileEvent(config.el,c->fd, AE_WRITABLE,writeHandler,c);
ed9b544e 142 sdsfree(c->ibuf);
143 c->ibuf = sdsempty();
89ee361e 144 c->readlen = (c->replytype == REPLY_BULK ||
145 c->replytype == REPLY_MBULK) ? -1 : 0;
2fd30952 146 c->mbulk = -1;
ed9b544e 147 c->written = 0;
58cd7103 148 c->totreceived = 0;
ed9b544e 149 c->state = CLIENT_SENDQUERY;
150 c->start = mstime();
74077975 151 createMissingClients(c);
ed9b544e 152}
153
ecfaf6da 154static void randomizeClientKey(client c) {
155 char *p;
156 char buf[32];
157 long r;
158
159 p = strstr(c->obuf, "_rand");
160 if (!p) return;
161 p += 5;
162 r = random() % config.randomkeys_keyspacelen;
163 sprintf(buf,"%ld",r);
164 memcpy(p,buf,strlen(buf));
165}
166
2fd30952 167static void prepareClientForReply(client c, int type) {
168 if (type == REPLY_BULK) {
169 c->replytype = REPLY_BULK;
170 c->readlen = -1;
171 } else if (type == REPLY_MBULK) {
172 c->replytype = REPLY_MBULK;
173 c->readlen = -1;
174 c->mbulk = -1;
175 } else {
176 c->replytype = type;
177 c->readlen = 0;
178 }
179}
180
ed9b544e 181static void clientDone(client c) {
58cd7103 182 static int last_tot_received = 1;
183
ed9b544e 184 long long latency;
185 config.donerequests ++;
186 latency = mstime() - c->start;
187 if (latency > MAX_LATENCY) latency = MAX_LATENCY;
188 config.latency[latency]++;
189
58cd7103 190 if (config.debug && last_tot_received != c->totreceived) {
191 printf("Tot bytes received: %d\n", c->totreceived);
192 last_tot_received = c->totreceived;
193 }
ed9b544e 194 if (config.donerequests == config.requests) {
195 freeClient(c);
196 aeStop(config.el);
197 return;
198 }
199 if (config.keepalive) {
200 resetClient(c);
ecfaf6da 201 if (config.randomkeys) randomizeClientKey(c);
ed9b544e 202 } else {
203 config.liveclients--;
204 createMissingClients(c);
205 config.liveclients++;
206 freeClient(c);
207 }
208}
209
36babc1e
PN
210/* Read a length from the buffer pointed to by *p, store the length in *len,
211 * and return the number of bytes that the cursor advanced. */
212static int readLen(char *p, int *len) {
213 char *tail = strstr(p,"\r\n");
214 if (tail == NULL)
215 return 0;
216 *tail = '\0';
217 *len = atoi(p+1);
218 return tail+2-p;
219}
220
ed9b544e 221static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask)
222{
36babc1e
PN
223 char buf[1024], *p;
224 int nread, pos=0, len=0;
ed9b544e 225 client c = privdata;
226 REDIS_NOTUSED(el);
227 REDIS_NOTUSED(fd);
228 REDIS_NOTUSED(mask);
229
36babc1e 230 nread = read(c->fd,buf,sizeof(buf));
ed9b544e 231 if (nread == -1) {
232 fprintf(stderr, "Reading from socket: %s\n", strerror(errno));
233 freeClient(c);
234 return;
235 }
236 if (nread == 0) {
237 fprintf(stderr, "EOF from client\n");
238 freeClient(c);
239 return;
240 }
58cd7103 241 c->totreceived += nread;
ed9b544e 242 c->ibuf = sdscatlen(c->ibuf,buf,nread);
36babc1e 243 len = sdslen(c->ibuf);
ed9b544e 244
245 if (c->replytype == REPLY_INT ||
36babc1e
PN
246 c->replytype == REPLY_RETCODE)
247 {
248 /* Check if the first line is complete. This is everything we need
249 * when waiting for an integer or status code reply.*/
250 if ((p = strstr(c->ibuf,"\r\n")) != NULL)
251 goto done;
252 } else if (c->replytype == REPLY_BULK) {
253 int advance = 0;
254 if (c->readlen < 0) {
255 advance = readLen(c->ibuf+pos,&c->readlen);
256 if (advance) {
257 pos += advance;
258 if (c->readlen == -1) {
259 goto done;
260 } else {
261 /* include the trailing \r\n */
262 c->readlen += 2;
2fd30952 263 }
ed9b544e 264 } else {
36babc1e 265 goto skip;
ed9b544e 266 }
267 }
36babc1e
PN
268
269 int canconsume;
270 if (c->readlen > 0) {
271 canconsume = c->readlen > (len-pos) ? (len-pos) : c->readlen;
272 c->readlen -= canconsume;
273 pos += canconsume;
274 }
275
276 if (c->readlen == 0)
277 goto done;
278 } else if (c->replytype == REPLY_MBULK) {
279 int advance = 0;
280 if (c->mbulk == -1) {
281 advance = readLen(c->ibuf+pos,&c->mbulk);
282 if (advance) {
283 pos += advance;
284 if (c->mbulk == -1)
285 goto done;
286 } else {
287 goto skip;
288 }
289 }
290
291 int canconsume;
292 while(c->mbulk > 0 && pos < len) {
293 if (c->readlen > 0) {
294 canconsume = c->readlen > (len-pos) ? (len-pos) : c->readlen;
295 c->readlen -= canconsume;
296 pos += canconsume;
297 if (c->readlen == 0)
298 c->mbulk--;
2fd30952 299 } else {
36babc1e
PN
300 advance = readLen(c->ibuf+pos,&c->readlen);
301 if (advance) {
302 pos += advance;
303 if (c->readlen == -1) {
304 c->mbulk--;
305 continue;
306 } else {
307 /* include the trailing \r\n */
308 c->readlen += 2;
309 }
310 } else {
311 goto skip;
312 }
2fd30952 313 }
314 }
36babc1e
PN
315
316 if (c->mbulk == 0)
317 goto done;
2fd30952 318 }
36babc1e
PN
319
320skip:
321 c->ibuf = sdsrange(c->ibuf,pos,-1);
322 return;
323done:
324 clientDone(c);
325 return;
ed9b544e 326}
327
328static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask)
329{
330 client c = privdata;
331 REDIS_NOTUSED(el);
332 REDIS_NOTUSED(fd);
333 REDIS_NOTUSED(mask);
334
335 if (c->state == CLIENT_CONNECTING) {
336 c->state = CLIENT_SENDQUERY;
337 c->start = mstime();
338 }
339 if (sdslen(c->obuf) > c->written) {
340 void *ptr = c->obuf+c->written;
341 int len = sdslen(c->obuf) - c->written;
342 int nwritten = write(c->fd, ptr, len);
343 if (nwritten == -1) {
61c47ecd 344 if (errno != EPIPE)
345 fprintf(stderr, "Writing to socket: %s\n", strerror(errno));
ed9b544e 346 freeClient(c);
347 return;
348 }
349 c->written += nwritten;
350 if (sdslen(c->obuf) == c->written) {
351 aeDeleteFileEvent(config.el,c->fd,AE_WRITABLE);
266373b2 352 aeCreateFileEvent(config.el,c->fd,AE_READABLE,readHandler,c);
ed9b544e 353 c->state = CLIENT_READREPLY;
354 }
355 }
356}
357
358static client createClient(void) {
359 client c = zmalloc(sizeof(struct _client));
360 char err[ANET_ERR_LEN];
361
362 c->fd = anetTcpNonBlockConnect(err,config.hostip,config.hostport);
363 if (c->fd == ANET_ERR) {
364 zfree(c);
365 fprintf(stderr,"Connect: %s\n",err);
366 return NULL;
367 }
368 anetTcpNoDelay(NULL,c->fd);
369 c->obuf = sdsempty();
370 c->ibuf = sdsempty();
2fd30952 371 c->mbulk = -1;
ed9b544e 372 c->readlen = 0;
373 c->written = 0;
58cd7103 374 c->totreceived = 0;
ed9b544e 375 c->state = CLIENT_CONNECTING;
266373b2 376 aeCreateFileEvent(config.el, c->fd, AE_WRITABLE, writeHandler, c);
ed9b544e 377 config.liveclients++;
378 listAddNodeTail(config.clients,c);
379 return c;
380}
381
382static void createMissingClients(client c) {
383 while(config.liveclients < config.numclients) {
384 client new = createClient();
385 if (!new) continue;
386 sdsfree(new->obuf);
387 new->obuf = sdsdup(c->obuf);
ecfaf6da 388 if (config.randomkeys) randomizeClientKey(c);
b892cabe 389 prepareClientForReply(new,c->replytype);
ed9b544e 390 }
391}
392
ed0dd554 393static void showLatencyReport(void) {
ed9b544e 394 int j, seen = 0;
395 float perc, reqpersec;
396
397 reqpersec = (float)config.donerequests/((float)config.totlatency/1000);
398 if (!config.quiet) {
ed0dd554 399 printf("====== %s ======\n", config.title);
ed9b544e 400 printf(" %d requests completed in %.2f seconds\n", config.donerequests,
401 (float)config.totlatency/1000);
402 printf(" %d parallel clients\n", config.numclients);
403 printf(" %d bytes payload\n", config.datasize);
404 printf(" keep alive: %d\n", config.keepalive);
405 printf("\n");
406 for (j = 0; j <= MAX_LATENCY; j++) {
407 if (config.latency[j]) {
408 seen += config.latency[j];
409 perc = ((float)seen*100)/config.donerequests;
410 printf("%.2f%% <= %d milliseconds\n", perc, j);
411 }
412 }
413 printf("%.2f requests per second\n\n", reqpersec);
414 } else {
ed0dd554 415 printf("%s: %.2f requests per second\n", config.title, reqpersec);
ed9b544e 416 }
417}
418
ed0dd554 419static void prepareForBenchmark(char *title) {
ed9b544e 420 memset(config.latency,0,sizeof(int)*(MAX_LATENCY+1));
ed0dd554 421 config.title = title;
ed9b544e 422 config.start = mstime();
423 config.donerequests = 0;
424}
425
ed0dd554 426static void endBenchmark(void) {
ed9b544e 427 config.totlatency = mstime()-config.start;
ed0dd554 428 showLatencyReport();
ed9b544e 429 freeAllClients();
430}
431
432void parseOptions(int argc, char **argv) {
433 int i;
434
435 for (i = 1; i < argc; i++) {
436 int lastarg = i==argc-1;
437
438 if (!strcmp(argv[i],"-c") && !lastarg) {
439 config.numclients = atoi(argv[i+1]);
440 i++;
441 } else if (!strcmp(argv[i],"-n") && !lastarg) {
442 config.requests = atoi(argv[i+1]);
443 i++;
444 } else if (!strcmp(argv[i],"-k") && !lastarg) {
445 config.keepalive = atoi(argv[i+1]);
446 i++;
447 } else if (!strcmp(argv[i],"-h") && !lastarg) {
448 char *ip = zmalloc(32);
449 if (anetResolve(NULL,argv[i+1],ip) == ANET_ERR) {
450 printf("Can't resolve %s\n", argv[i]);
451 exit(1);
452 }
453 config.hostip = ip;
454 i++;
455 } else if (!strcmp(argv[i],"-p") && !lastarg) {
456 config.hostport = atoi(argv[i+1]);
457 i++;
458 } else if (!strcmp(argv[i],"-d") && !lastarg) {
459 config.datasize = atoi(argv[i+1]);
460 i++;
461 if (config.datasize < 1) config.datasize=1;
462 if (config.datasize > 1024*1024) config.datasize = 1024*1024;
ecfaf6da 463 } else if (!strcmp(argv[i],"-r") && !lastarg) {
57172ffb 464 config.randomkeys = 1;
ecfaf6da 465 config.randomkeys_keyspacelen = atoi(argv[i+1]);
466 if (config.randomkeys_keyspacelen < 0)
467 config.randomkeys_keyspacelen = 0;
468 i++;
ed9b544e 469 } else if (!strcmp(argv[i],"-q")) {
470 config.quiet = 1;
471 } else if (!strcmp(argv[i],"-l")) {
472 config.loop = 1;
58cd7103 473 } else if (!strcmp(argv[i],"-D")) {
474 config.debug = 1;
266373b2 475 } else if (!strcmp(argv[i],"-I")) {
476 config.idlemode = 1;
ed9b544e 477 } else {
478 printf("Wrong option '%s' or option argument missing\n\n",argv[i]);
479 printf("Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]\n\n");
480 printf(" -h <hostname> Server hostname (default 127.0.0.1)\n");
481 printf(" -p <hostname> Server port (default 6379)\n");
482 printf(" -c <clients> Number of parallel connections (default 50)\n");
483 printf(" -n <requests> Total number of requests (default 10000)\n");
484 printf(" -d <size> Data size of SET/GET value in bytes (default 2)\n");
485 printf(" -k <boolean> 1=keep alive 0=reconnect (default 1)\n");
b1ad58ed 486 printf(" -r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD\n");
ecfaf6da 487 printf(" Using this option the benchmark will get/set keys\n");
488 printf(" in the form mykey_rand000000012456 instead of constant\n");
489 printf(" keys, the <keyspacelen> argument determines the max\n");
490 printf(" number of values for the random number. For instance\n");
491 printf(" if set to 10 only rand000000000000 - rand000000000009\n");
492 printf(" range will be allowed.\n");
ed9b544e 493 printf(" -q Quiet. Just show query/sec values\n");
494 printf(" -l Loop. Run the tests forever\n");
266373b2 495 printf(" -I Idle mode. Just open N idle connections and wait.\n");
58cd7103 496 printf(" -D Debug mode. more verbose.\n");
ed9b544e 497 exit(1);
498 }
499 }
500}
501
ed0dd554
PN
502int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData) {
503 REDIS_NOTUSED(eventLoop);
504 REDIS_NOTUSED(id);
505 REDIS_NOTUSED(clientData);
506
507 float dt = (float)(mstime()-config.start)/1000.0;
508 float rps = (float)config.donerequests/dt;
509 printf("%s: %.2f\r", config.title, rps);
510 fflush(stdout);
511 return 250; /* every 250ms */
512}
513
ed9b544e 514int main(int argc, char **argv) {
515 client c;
516
517 signal(SIGHUP, SIG_IGN);
518 signal(SIGPIPE, SIG_IGN);
519
58cd7103 520 config.debug = 0;
ed9b544e 521 config.numclients = 50;
522 config.requests = 10000;
523 config.liveclients = 0;
524 config.el = aeCreateEventLoop();
ed0dd554 525 aeCreateTimeEvent(config.el,1,showThroughput,NULL,NULL);
ed9b544e 526 config.keepalive = 1;
527 config.donerequests = 0;
528 config.datasize = 3;
57172ffb 529 config.randomkeys = 0;
ecfaf6da 530 config.randomkeys_keyspacelen = 0;
ed9b544e 531 config.quiet = 0;
532 config.loop = 0;
266373b2 533 config.idlemode = 0;
ed9b544e 534 config.latency = NULL;
535 config.clients = listCreate();
536 config.latency = zmalloc(sizeof(int)*(MAX_LATENCY+1));
537
538 config.hostip = "127.0.0.1";
539 config.hostport = 6379;
540
541 parseOptions(argc,argv);
542
543 if (config.keepalive == 0) {
c3251497 544 printf("WARNING: keepalive disabled, you probably need 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse' for Linux and 'sudo sysctl -w net.inet.tcp.msl=1000' for Mac OS X in order to use a lot of clients/requests\n");
ed9b544e 545 }
546
266373b2 547 if (config.idlemode) {
548 printf("Creating %d idle connections and waiting forever (Ctrl+C when done)\n", config.numclients);
ed0dd554 549 prepareForBenchmark("IDLE");
266373b2 550 c = createClient();
551 if (!c) exit(1);
552 c->obuf = sdsempty();
553 prepareClientForReply(c,REPLY_RETCODE); /* will never receive it */
554 createMissingClients(c);
555 aeMain(config.el);
556 /* and will wait for every */
557 }
558
ed9b544e 559 do {
ed0dd554 560 prepareForBenchmark("PING");
6766f45e 561 c = createClient();
562 if (!c) exit(1);
563 c->obuf = sdscat(c->obuf,"PING\r\n");
564 prepareClientForReply(c,REPLY_RETCODE);
565 createMissingClients(c);
566 aeMain(config.el);
ed0dd554 567 endBenchmark();
6766f45e 568
ed0dd554 569 prepareForBenchmark("PING (multi bulk)");
6766f45e 570 c = createClient();
571 if (!c) exit(1);
572 c->obuf = sdscat(c->obuf,"*1\r\n$4\r\nPING\r\n");
573 prepareClientForReply(c,REPLY_RETCODE);
574 createMissingClients(c);
575 aeMain(config.el);
ed0dd554 576 endBenchmark();
6766f45e 577
ed0dd554 578 prepareForBenchmark("SET");
ed9b544e 579 c = createClient();
580 if (!c) exit(1);
1aa608fc 581 c->obuf = sdscat(c->obuf,"SET foo_rand000000000000 ");
ed9b544e 582 {
583 char *data = zmalloc(config.datasize+2);
584 memset(data,'x',config.datasize);
585 data[config.datasize] = '\r';
586 data[config.datasize+1] = '\n';
587 c->obuf = sdscatlen(c->obuf,data,config.datasize+2);
588 }
2fd30952 589 prepareClientForReply(c,REPLY_RETCODE);
ed9b544e 590 createMissingClients(c);
591 aeMain(config.el);
ed0dd554 592 endBenchmark();
ed9b544e 593
ed0dd554 594 prepareForBenchmark("GET");
ed9b544e 595 c = createClient();
596 if (!c) exit(1);
57172ffb 597 c->obuf = sdscat(c->obuf,"GET foo_rand000000000000\r\n");
2fd30952 598 prepareClientForReply(c,REPLY_BULK);
ed9b544e 599 createMissingClients(c);
600 aeMain(config.el);
ed0dd554 601 endBenchmark();
ed9b544e 602
ed0dd554 603 prepareForBenchmark("INCR");
ed9b544e 604 c = createClient();
605 if (!c) exit(1);
57172ffb 606 c->obuf = sdscat(c->obuf,"INCR counter_rand000000000000\r\n");
2fd30952 607 prepareClientForReply(c,REPLY_INT);
ed9b544e 608 createMissingClients(c);
609 aeMain(config.el);
ed0dd554 610 endBenchmark();
ed9b544e 611
ed0dd554 612 prepareForBenchmark("LPUSH");
ed9b544e 613 c = createClient();
614 if (!c) exit(1);
1aa608fc 615 c->obuf = sdscat(c->obuf,"LPUSH mylist bar\r\n");
2fd30952 616 prepareClientForReply(c,REPLY_INT);
ed9b544e 617 createMissingClients(c);
618 aeMain(config.el);
ed0dd554 619 endBenchmark();
ed9b544e 620
ed0dd554 621 prepareForBenchmark("LPOP");
ed9b544e 622 c = createClient();
623 if (!c) exit(1);
624 c->obuf = sdscat(c->obuf,"LPOP mylist\r\n");
2fd30952 625 prepareClientForReply(c,REPLY_BULK);
ed9b544e 626 createMissingClients(c);
627 aeMain(config.el);
ed0dd554 628 endBenchmark();
ed9b544e 629
ed0dd554 630 prepareForBenchmark("SADD");
b1ad58ed 631 c = createClient();
632 if (!c) exit(1);
1aa608fc 633 c->obuf = sdscat(c->obuf,"SADD myset counter_rand000000000000\r\n");
b1ad58ed 634 prepareClientForReply(c,REPLY_RETCODE);
635 createMissingClients(c);
636 aeMain(config.el);
ed0dd554 637 endBenchmark();
b1ad58ed 638
ed0dd554 639 prepareForBenchmark("SPOP");
b1ad58ed 640 c = createClient();
641 if (!c) exit(1);
642 c->obuf = sdscat(c->obuf,"SPOP myset\r\n");
643 prepareClientForReply(c,REPLY_BULK);
644 createMissingClients(c);
645 aeMain(config.el);
ed0dd554 646 endBenchmark();
b1ad58ed 647
ed0dd554 648 prepareForBenchmark("LPUSH (again, in order to bench LRANGE)");
2fd30952 649 c = createClient();
650 if (!c) exit(1);
1aa608fc 651 c->obuf = sdscat(c->obuf,"LPUSH mylist bar\r\n");
2fd30952 652 prepareClientForReply(c,REPLY_RETCODE);
653 createMissingClients(c);
654 aeMain(config.el);
ed0dd554 655 endBenchmark();
2fd30952 656
ed0dd554 657 prepareForBenchmark("LRANGE (first 100 elements)");
2fd30952 658 c = createClient();
659 if (!c) exit(1);
660 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 99\r\n");
661 prepareClientForReply(c,REPLY_MBULK);
662 createMissingClients(c);
663 aeMain(config.el);
ed0dd554 664 endBenchmark();
2fd30952 665
ed0dd554 666 prepareForBenchmark("LRANGE (first 300 elements)");
ccb5332c 667 c = createClient();
668 if (!c) exit(1);
669 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 299\r\n");
670 prepareClientForReply(c,REPLY_MBULK);
671 createMissingClients(c);
672 aeMain(config.el);
ed0dd554 673 endBenchmark();
ccb5332c 674
ed0dd554 675 prepareForBenchmark("LRANGE (first 450 elements)");
cc30e368 676 c = createClient();
677 if (!c) exit(1);
678 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 449\r\n");
679 prepareClientForReply(c,REPLY_MBULK);
680 createMissingClients(c);
681 aeMain(config.el);
ed0dd554 682 endBenchmark();
cc30e368 683
ed0dd554 684 prepareForBenchmark("LRANGE (first 600 elements)");
cc30e368 685 c = createClient();
686 if (!c) exit(1);
687 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 599\r\n");
688 prepareClientForReply(c,REPLY_MBULK);
689 createMissingClients(c);
690 aeMain(config.el);
ed0dd554 691 endBenchmark();
cc30e368 692
ed9b544e 693 printf("\n");
694 } while(config.loop);
695
696 return 0;
697}