/* This file is part of the YAZ toolkit. * Copyright (C) Index Data * See the file LICENSE for details. */ #if HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include /* naming events */ static char* zoom_events[ZOOM_EVENT_MAX+1]; /* re-sorting event numbers to progress numbers */ static int zoom_progress[ZOOM_EVENT_MAX+1]; /* commando line parameters */ static struct parameters_t { char host[1024]; char query[1024]; int progress[4096]; int concurrent; int repeat; int timeout; char proxy[1024]; int piggypack; int gnuplot; } parameters; struct event_line_t { int connection; long time_sec; long time_usec; int progress; int event; char zoom_event[128]; int error; char errmsg[128]; }; void print_event_line(struct event_line_t *pel) { printf ("%d\t%ld.%06ld\t%d\t%d\t%s\t%d\t%s\n", pel->connection, pel->time_sec, pel->time_usec, pel->progress, pel->event, pel->zoom_event, pel->error, pel->errmsg); } void update_events(int *elc, struct event_line_t *els, int repeat, int conn, long sec, long usec, int prog, int event, const char * eventmsg, int error, const char * errmsg){ int ielc = repeat*parameters.concurrent + conn; int iels = repeat*parameters.concurrent*10 + conn*10 + elc[ielc]; els[iels].connection = conn; els[iels].time_sec = sec; els[iels].time_usec = usec; els[iels].progress = prog; els[iels].event = event; if (eventmsg) strcpy(els[iels].zoom_event, eventmsg); else strcpy(els[iels].zoom_event, "---"); els[iels].error = error; strcpy(els[iels].errmsg, errmsg); /* print_event_line(&els[iels]); */ elc[ielc] += 1; } void print_events(int *elc, struct event_line_t *els, int connections){ int i; int j; int k; int ielc; int iels; for (k=0; k < parameters.repeat; k++){ for (i=0; i < connections; i++){ ielc = k * parameters.concurrent + i; for (j=0; j < elc[ielc]; j++){ iels = k * parameters.concurrent * 10 + i * 10 + j; print_event_line(&els[iels]); } printf("\n"); } printf("\n"); } } void init_statics(void) { int i; char nullstring[1] = ""; /* naming events */ zoom_events[ZOOM_EVENT_NONE] = "ZOOM_EVENT_NONE"; zoom_events[ZOOM_EVENT_CONNECT] = "ZOOM_EVENT_CONNECT"; zoom_events[ZOOM_EVENT_SEND_DATA] = "ZOOM_EVENT_SEND_DATA"; zoom_events[ZOOM_EVENT_RECV_DATA] = "ZOOM_EVENT_RECV_DATA"; zoom_events[ZOOM_EVENT_TIMEOUT] = "ZOOM_EVENT_TIMEOUT"; zoom_events[ZOOM_EVENT_UNKNOWN] = "ZOOM_EVENT_UNKNOWN"; zoom_events[ZOOM_EVENT_SEND_APDU] = "ZOOM_EVENT_SEND_APDU"; zoom_events[ZOOM_EVENT_RECV_APDU] = "ZOOM_EVENT_RECV_APDU"; zoom_events[ZOOM_EVENT_RECV_RECORD] = "ZOOM_EVENT_RECV_RECORD"; zoom_events[ZOOM_EVENT_RECV_SEARCH] = "ZOOM_EVENT_RECV_SEARCH"; zoom_events[ZOOM_EVENT_END] = "ZOOM_EVENT_END"; /* re-sorting event numbers to progress numbers */ zoom_progress[ZOOM_EVENT_NONE] = 0; zoom_progress[ZOOM_EVENT_CONNECT] = 1; zoom_progress[ZOOM_EVENT_SEND_DATA] = 3; zoom_progress[ZOOM_EVENT_RECV_DATA] = 4; zoom_progress[ZOOM_EVENT_TIMEOUT] = 9; zoom_progress[ZOOM_EVENT_UNKNOWN] = 10; zoom_progress[ZOOM_EVENT_SEND_APDU] = 2; zoom_progress[ZOOM_EVENT_RECV_APDU] = 5; zoom_progress[ZOOM_EVENT_RECV_RECORD] = 7; zoom_progress[ZOOM_EVENT_RECV_SEARCH] = 6; zoom_progress[ZOOM_EVENT_END] = 8; /* parameters */ parameters.concurrent = 1; parameters.timeout = 0; parameters.repeat = 1; strcpy(parameters.proxy, nullstring); parameters.gnuplot = 0; parameters.piggypack = 0; /* progress initializing */ for (i = 0; i < 4096; i++){ parameters.progress[i] = 0; } } struct time_type { struct timeval now; struct timeval then; long sec; long usec; }; void time_init(struct time_type *ptime) { gettimeofday(&(ptime->now), 0); gettimeofday(&(ptime->then), 0); ptime->sec = 0; ptime->usec = 0; } void time_stamp(struct time_type *ptime) { gettimeofday(&(ptime->now), 0); ptime->sec = ptime->now.tv_sec - ptime->then.tv_sec; ptime->usec = ptime->now.tv_usec - ptime->then.tv_usec; if (ptime->usec < 0){ ptime->sec--; ptime->usec += 1000000; } } long time_sec(struct time_type *ptime) { return ptime->sec; } long time_usec(struct time_type *ptime) { return ptime->usec; } void print_option_error(void) { fprintf(stderr, "zoom-benchmark: Call error\n"); fprintf(stderr, "zoom-benchmark -h host:port -q pqf-query " "[-c no_concurrent (max 4096)] " "[-n no_repeat] " "[-b (piggypack)] " "[-g (gnuplot outfile)] " "[-p proxy] \n"); /* "[-t timeout] \n"); */ exit(1); } void read_params(int argc, char **argv, struct parameters_t *p_parameters){ char *arg; int ret; while ((ret = options("h:q:c:t:p:bgn:", argv, argc, &arg)) != -2) { switch (ret) { case 'h': strcpy(p_parameters->host, arg); break; case 'q': strcpy(p_parameters->query, arg); break; case 'p': strcpy(p_parameters->proxy, arg); break; case 'c': p_parameters->concurrent = atoi(arg); break; #if 0 case 't': p_parameters->timeout = atoi(arg); break; #endif case 'b': p_parameters->piggypack = 1; break; case 'g': p_parameters->gnuplot = 1; break; case 'n': p_parameters->repeat = atoi(arg); break; case 0: print_option_error(); break; default: print_option_error(); } } if(0){ printf("zoom-benchmark\n"); printf(" host: %s \n", p_parameters->host); printf(" query: %s \n", p_parameters->query); printf(" concurrent: %d \n", p_parameters->concurrent); printf(" repeat: %d \n", p_parameters->repeat); #if 0 printf(" timeout: %d \n", p_parameters->timeout); #endif printf(" proxy: %s \n", p_parameters->proxy); printf(" piggypack: %d \n\n", p_parameters->piggypack); printf(" gnuplot: %d \n\n", p_parameters->gnuplot); } if (! strlen(p_parameters->host)) print_option_error(); if (! strlen(p_parameters->query)) print_option_error(); if (! (p_parameters->concurrent > 0)) print_option_error(); if (! (p_parameters->repeat > 0)) print_option_error(); if (! (p_parameters->timeout >= 0)) print_option_error(); if (! ( p_parameters->concurrent <= 4096)) print_option_error(); } void print_table_header(void) { if (parameters.gnuplot) printf("#"); printf ("target\tsecond.usec\tprogress\tevent\teventname\t"); printf("error\terrorname\n"); } int main(int argc, char **argv) { struct time_type time; ZOOM_connection *z; ZOOM_resultset *r; int *elc; struct event_line_t *els; ZOOM_options o; int i; int k; init_statics(); read_params(argc, argv, ¶meters); z = (ZOOM_connection *) xmalloc(sizeof(*z) * parameters.concurrent); r = (ZOOM_resultset *) xmalloc(sizeof(*r) * parameters.concurrent); elc = (int *) xmalloc(sizeof(*elc) * parameters.concurrent * parameters.repeat); els = (struct event_line_t *) xmalloc( sizeof(*els) * parameters.concurrent * parameters.repeat * 10); o = ZOOM_options_create(); /* async mode */ ZOOM_options_set (o, "async", "1"); /* get first record of result set (using piggypack) */ if (parameters.piggypack) ZOOM_options_set (o, "count", "1"); /* set proxy */ if (strlen(parameters.proxy)) ZOOM_options_set (o, "proxy", parameters.proxy); /* preferred record syntax */ if (0){ ZOOM_options_set (o, "preferredRecordSyntax", "usmarc"); ZOOM_options_set (o, "elementSetName", "F"); } time_init(&time); /* repeat loop */ for (k = 0; k < parameters.repeat; k++){ /* progress zeroing */ for (i = 0; i < 4096; i++){ parameters.progress[i] = k * 5 -1; } /* connect to all concurrent connections*/ for ( i = 0; i < parameters.concurrent; i++){ /* set event count to zero */ elc[k * parameters.concurrent + i] = 0; /* create connection - pass options (they are the same for all) */ z[i] = ZOOM_connection_create(o); /* connect and init */ ZOOM_connection_connect(z[i], parameters.host, 0); } /* search all */ for (i = 0; i < parameters.concurrent; i++) r[i] = ZOOM_connection_search_pqf (z[i], parameters.query); /* network I/O. pass number of connections and array of connections */ while ((i = ZOOM_event (parameters.concurrent, z))){ int event = ZOOM_connection_last_event(z[i-1]); const char *errmsg; const char *addinfo; int error = 0; //int progress = zoom_progress[event]; if (event == ZOOM_EVENT_SEND_DATA || event == ZOOM_EVENT_RECV_DATA) continue; time_stamp(&time); /* updating events and event list */ error = ZOOM_connection_error(z[i-1] , &errmsg, &addinfo); if (error) parameters.progress[i] = zoom_progress[ZOOM_EVENT_UNKNOWN]; //parameters.progress[i] = zoom_progress[ZOOM_EVENT_NONE]; else if (event == ZOOM_EVENT_CONNECT) parameters.progress[i] = zoom_progress[event]; else //parameters.progress[i] = zoom_progress[event]; parameters.progress[i] += 1; update_events(elc, els, k, i-1, time_sec(&time), time_usec(&time), parameters.progress[i], event, zoom_events[event], error, errmsg); } /* destroy connections */ for (i = 0; i