better 3D graphics made possible by ordering events into groups of same connections
[yaz-moved-to-github.git] / zoom / zoom-benchmark.c
1 /*
2  * $Id: zoom-benchmark.c,v 1.9 2005-09-19 14:14:01 marc Exp $
3  *
4  * Asynchronous multi-target client doing search and piggyback retrieval
5  */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <sys/time.h>
12
13 #include <yaz/xmalloc.h>
14 #include <yaz/options.h>
15 #include <yaz/zoom.h>
16
17
18 /* naming events */
19 static char* zoom_events[10];
20
21 /* re-sorting event numbers to progress numbers */
22 static int zoom_progress[10];
23
24 /* commando line parameters */
25 static struct parameters_t { 
26     char host[4096];
27     char query[4096];
28     char progress[4096];
29     int concurrent;
30     int timeout;
31 } parameters;
32
33 struct  event_line_t 
34 {
35     int connection;
36     long time_sec;
37     long time_usec;
38     int progress;
39     int event;
40     char zoom_event[128];
41     int error;
42     char errmsg[128];
43 };
44
45
46 void print_event_line(struct event_line_t *pel)
47 {
48     printf ("%d\t%ld.%06ld\t%d\t%d\t%s\t%d\t%s\n",
49             pel->connection, pel->time_sec, pel->time_usec, 
50             pel->progress,
51             pel->event, pel->zoom_event, 
52             pel->error, pel->errmsg);
53 }
54
55 //void update_event_line(struct event_line_t *pel,
56 //                       int conn,
57 //                       long sec,
58 //                       long usec,
59 //                       int prog,
60 //                       int event,
61 //                       const char * eventmsg,
62 //                       int error,
63 //                       const char * errmsg)
64 //{
65 //    pel->connection = conn;
66 //    pel->time_sec = sec;
67 //    pel->time_usec = usec;
68 //    pel->progress = prog;
69 //    pel->event = event;
70 //    strcpy(pel->zoom_event, eventmsg);
71 //    pel->error = error;
72 //    strcpy(pel->errmsg, errmsg);
73 //}
74
75 void  update_events(int *elc, struct event_line_t *els,
76                     int conn,
77                     long sec,
78                     long usec,
79                     int prog,
80                     int event,
81                     const char * eventmsg,
82                     int error,
83                     const char * errmsg){
84     
85     els[conn * 10 + elc[conn]].connection = conn;
86     els[conn * 10 + elc[conn]].time_sec = sec;
87     els[conn * 10 + elc[conn]].time_usec = usec;
88     els[conn * 10 + elc[conn]].progress = prog;
89     els[conn * 10 + elc[conn]].event = event;
90     strcpy(els[conn * 10 + elc[conn]].zoom_event, eventmsg);
91     els[conn * 10 + elc[conn]].error = error;
92     strcpy(els[conn * 10 + elc[conn]].errmsg, errmsg);
93
94     //print_event_line(&els[conn*10 + elc[conn]]);
95
96     elc[conn] += 1;
97 }
98
99 void  print_events(int *elc,  struct event_line_t *els, 
100                    int connections){
101     int i;
102     int j;
103     for (i=0; i < connections; i++){
104         for (j=0; j < elc[i]; j++){
105             print_event_line(&els[i*10 + j]);
106         }
107         printf("\n");
108     }
109 }
110
111
112
113 void init_statics()
114 {
115     /* naming events */
116     zoom_events[ZOOM_EVENT_NONE] = "ZOOM_EVENT_NONE";
117     zoom_events[ZOOM_EVENT_CONNECT] = "ZOOM_EVENT_CONNECT";
118     zoom_events[ZOOM_EVENT_SEND_DATA] = "ZOOM_EVENT_SEND_DATA";
119     zoom_events[ZOOM_EVENT_RECV_DATA] = "ZOOM_EVENT_RECV_DATA";
120     zoom_events[ZOOM_EVENT_TIMEOUT] = "ZOOM_EVENT_TIMEOUT";
121     zoom_events[ZOOM_EVENT_UNKNOWN] = "ZOOM_EVENT_UNKNOWN";
122     zoom_events[ZOOM_EVENT_SEND_APDU] = "ZOOM_EVENT_SEND_APDU";
123     zoom_events[ZOOM_EVENT_RECV_APDU] = "ZOOM_EVENT_RECV_APDU";
124     zoom_events[ZOOM_EVENT_RECV_RECORD] = "ZOOM_EVENT_RECV_RECORD";
125     zoom_events[ZOOM_EVENT_RECV_SEARCH] = "ZOOM_EVENT_RECV_SEARCH";
126
127     /* re-sorting event numbers to progress numbers */
128     zoom_progress[ZOOM_EVENT_NONE] = 0;
129     zoom_progress[ZOOM_EVENT_CONNECT] = 1;
130     zoom_progress[ZOOM_EVENT_SEND_DATA] = 3;
131     zoom_progress[ZOOM_EVENT_RECV_DATA] = 4;
132     zoom_progress[ZOOM_EVENT_TIMEOUT] = 8;
133     zoom_progress[ZOOM_EVENT_UNKNOWN] = 9;
134     zoom_progress[ZOOM_EVENT_SEND_APDU] = 2;
135     zoom_progress[ZOOM_EVENT_RECV_APDU] = 5;
136     zoom_progress[ZOOM_EVENT_RECV_RECORD] = 7;
137     zoom_progress[ZOOM_EVENT_RECV_SEARCH] = 6;
138
139     /* parameters */
140     parameters.concurrent = 1;
141     parameters.timeout = 0;
142
143     /* progress initializing */
144     int i;
145     for (i = 0; i < 4096; i++){
146         parameters.progress[i] = 0;
147     }
148     
149 }
150  
151 struct time_type 
152 {
153     struct timeval now;
154     struct timeval then;
155     long sec;
156     long usec;
157 };
158
159 void time_init(struct time_type *ptime)
160 {
161     gettimeofday(&(ptime->now), 0);
162     gettimeofday(&(ptime->then), 0);
163     ptime->sec = 0;
164     ptime->usec = 0;
165 }
166
167 void time_stamp(struct time_type *ptime)
168 {
169     gettimeofday(&(ptime->now), 0);
170     ptime->sec = ptime->now.tv_sec - ptime->then.tv_sec;
171     ptime->usec = ptime->now.tv_usec - ptime->then.tv_usec;
172     if (ptime->usec < 0){
173         ptime->sec--;
174         ptime->usec += 1000000;
175     }
176 }
177
178 long time_sec(struct time_type *ptime)
179 {
180     return ptime->sec;
181 }
182
183 long time_usec(struct time_type *ptime)
184 {
185     return ptime->usec;
186 }
187
188 void print_option_error()
189 {
190     fprintf(stderr, "zoom-benchmark:  Call error\n");
191     fprintf(stderr, "zoom-benchmark -h host:port -q pqf-query "
192             "[-c no_concurrent] "
193             "[-t timeout] \n");
194     exit(1);
195 }
196
197
198 void read_params(int argc, char **argv, struct parameters_t *p_parameters){    
199     char *arg;
200     int ret;
201     while ((ret = options("h:q:c:t:", argv, argc, &arg)) != -2)
202     {
203         switch (ret)
204         {
205         case 'h':
206             strcpy(p_parameters->host, arg);
207             break;
208         case 'q':
209             strcpy(p_parameters->query, arg);
210             break;
211         case 'c':
212             p_parameters->concurrent = atoi(arg);
213             break;
214         case 't':
215             p_parameters->timeout = atoi(arg);
216                     break;
217         case 0:
218             print_option_error();
219             break;
220         default:
221             print_option_error();
222         }
223     }
224     
225     if(0){
226         printf("zoom-benchmark\n");
227         printf("   host:       %s \n", p_parameters->host);
228         printf("   query:      %s \n", p_parameters->query);
229         printf("   concurrent: %d \n", p_parameters->concurrent);
230         printf("   timeout:    %d \n\n", p_parameters->timeout);
231     }
232
233     if (! strlen(p_parameters->host))
234         print_option_error();
235     if (! strlen(p_parameters->query))
236         print_option_error();
237     if (! (p_parameters->concurrent > 0))
238         print_option_error();
239     if (! (p_parameters->timeout >= 0))
240         print_option_error();
241 }
242
243 void print_table_header()
244 {
245     printf ("target\tsecond.usec\tprogress\tevent\teventname\t");
246     printf("error\terrorname\n");
247 }
248
249
250 int main(int argc, char **argv)
251 {
252     struct time_type time;
253     ZOOM_connection *z;
254     ZOOM_resultset *r;
255     int *elc;
256     struct event_line_t *els;
257     ZOOM_options o;
258     int i;
259
260     init_statics();
261
262     read_params(argc, argv, &parameters);
263
264     z = xmalloc(sizeof(*z) * parameters.concurrent);
265     r = xmalloc(sizeof(*r) * parameters.concurrent);
266     elc = xmalloc(sizeof(*elc) * parameters.concurrent);
267     els = xmalloc(sizeof(*els) * parameters.concurrent * 10);
268     o = ZOOM_options_create();
269
270     /* async mode */
271     ZOOM_options_set (o, "async", "1");
272
273     /* get first record of result set (using piggyback) */
274     ZOOM_options_set (o, "count", "1");
275
276     /* preferred record syntax */
277     if (0){
278         ZOOM_options_set (o, "preferredRecordSyntax", "usmarc");
279         ZOOM_options_set (o, "elementSetName", "F");
280     }
281     
282
283     /* connect to all concurrent connections*/
284     for ( i = 0; i < parameters.concurrent; i++){
285         /* set event count to zero */
286         elc[i] = 0;
287
288         /* create connection - pass options (they are the same for all) */
289         z[i] = ZOOM_connection_create(o);
290
291         /* connect and init */
292         ZOOM_connection_connect(z[i], parameters.host, 0);
293     }
294     /* search all */
295     for (i = 0; i < parameters.concurrent; i++)
296         r[i] = ZOOM_connection_search_pqf (z[i], parameters.query);
297
298     time_init(&time);
299     /* network I/O. pass number of connections and array of connections */
300     while ((i = ZOOM_event (parameters.concurrent, z)))
301     { 
302         int event = ZOOM_connection_last_event(z[i-1]);
303         const char *errmsg;
304         const char *addinfo;
305         int error = 0;
306         int progress = zoom_progress[event];
307         struct event_line_t el;
308         
309         if (event == ZOOM_EVENT_SEND_DATA || event == ZOOM_EVENT_RECV_DATA)
310             continue;
311
312         time_stamp(&time);
313
314         /* updating events and event list */
315         error = ZOOM_connection_error(z[i-1] , &errmsg, &addinfo);
316         if (error)
317             parameters.progress[i] = -progress;
318         else
319             parameters.progress[i] += 1;
320
321
322         //if (0){
323         // printf ("%d\t%ld.%06ld\t%d\t%d\t%s\t%d\t%s\n",
324         //update_event_line(& el,
325         //                  i-1, time_sec(&time), time_usec(&time), 
326         //                  parameters.progress[i],
327         //                  event, zoom_events[event], 
328         //                  error, errmsg);
329         //print_event_line(&el);
330         //}
331         
332         update_events(elc, els,
333                       i-1, time_sec(&time), time_usec(&time), 
334                       parameters.progress[i],
335                       event, zoom_events[event], 
336                       error, errmsg);
337         
338         
339     }
340
341
342     /* output */
343     print_table_header();    
344     print_events(elc,  els, parameters.concurrent);
345     
346     /* destroy and exit */
347     for (i = 0; i<parameters.concurrent; i++)
348     {
349         ZOOM_resultset_destroy (r[i]);
350         ZOOM_connection_destroy (z[i]);
351     }
352     xfree(z);
353     xfree(r);
354     xfree(elc);
355     xfree(els);
356     ZOOM_options_destroy(o);
357     exit (0);
358 }
359 /*
360  * Local variables:
361  * c-basic-offset: 4
362  * indent-tabs-mode: nil
363  * End:
364  * vim: shiftwidth=4 tabstop=8 expandtab
365  */
366