ca6a5b49b69873ed4533aef310f19e21936212f0
[yaz-moved-to-github.git] / zoom / zoom-benchmark.c
1 /*
2  * $Id: zoom-benchmark.c,v 1.5 2005-09-15 10:38:03 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
34 void init_statics()
35 {
36     /* naming events */
37     zoom_events[ZOOM_EVENT_NONE] = "ZOOM_EVENT_NONE";
38     zoom_events[ZOOM_EVENT_CONNECT] = "ZOOM_EVENT_CONNECT";
39     zoom_events[ZOOM_EVENT_SEND_DATA] = "ZOOM_EVENT_SEND_DATA";
40     zoom_events[ZOOM_EVENT_RECV_DATA] = "ZOOM_EVENT_RECV_DATA";
41     zoom_events[ZOOM_EVENT_TIMEOUT] = "ZOOM_EVENT_TIMEOUT";
42     zoom_events[ZOOM_EVENT_UNKNOWN] = "ZOOM_EVENT_UNKNOWN";
43     zoom_events[ZOOM_EVENT_SEND_APDU] = "ZOOM_EVENT_SEND_APDU";
44     zoom_events[ZOOM_EVENT_RECV_APDU] = "ZOOM_EVENT_RECV_APDU";
45     zoom_events[ZOOM_EVENT_RECV_RECORD] = "ZOOM_EVENT_RECV_RECORD";
46     zoom_events[ZOOM_EVENT_RECV_SEARCH] = "ZOOM_EVENT_RECV_SEARCH";
47
48     /* re-sorting event numbers to progress numbers */
49     zoom_progress[ZOOM_EVENT_NONE] = 0;
50     zoom_progress[ZOOM_EVENT_CONNECT] = 1;
51     zoom_progress[ZOOM_EVENT_SEND_DATA] = 3;
52     zoom_progress[ZOOM_EVENT_RECV_DATA] = 4;
53     zoom_progress[ZOOM_EVENT_TIMEOUT] = 8;
54     zoom_progress[ZOOM_EVENT_UNKNOWN] = 9;
55     zoom_progress[ZOOM_EVENT_SEND_APDU] = 2;
56     zoom_progress[ZOOM_EVENT_RECV_APDU] = 5;
57     zoom_progress[ZOOM_EVENT_RECV_RECORD] = 7;
58     zoom_progress[ZOOM_EVENT_RECV_SEARCH] = 6;
59
60     /* parameters */
61     //parameters.host = "";
62     //parameters.query = "";
63     parameters.concurrent = 1;
64     parameters.timeout = 0;
65
66     /* progress initializing */
67     int i;
68     for (i = 0; i < 4096; i++){
69         parameters.progress[i] = 0;
70     }
71     
72 }
73  
74 struct time_type 
75 {
76     struct timeval now;
77     struct timeval then;
78     long sec;
79     long usec;
80 };
81
82 void time_init(struct time_type *ptime)
83 {
84     gettimeofday(&(ptime->now), 0);
85     gettimeofday(&(ptime->then), 0);
86     ptime->sec = 0;
87     ptime->usec = 0;
88 }
89
90 void time_stamp(struct time_type *ptime)
91 {
92     gettimeofday(&(ptime->now), 0);
93     ptime->sec = ptime->now.tv_sec - ptime->then.tv_sec;
94     ptime->usec = ptime->now.tv_usec - ptime->then.tv_usec;
95     if (ptime->usec < 0){
96         ptime->sec--;
97         ptime->usec += 1000000;
98     }
99 }
100
101 long time_sec(struct time_type *ptime)
102 {
103     return ptime->sec;
104 }
105
106 long time_usec(struct time_type *ptime)
107 {
108     return ptime->usec;
109 }
110
111 void print_option_error()
112 {
113     fprintf(stderr, "zoom-benchmark:  Call error\n");
114     fprintf(stderr, "zoom-benchmark -h host:port -q pqf-query "
115             "[-c no_concurrent] "
116             "[-t timeout] \n");
117     exit(1);
118 }
119
120
121 void read_params(int argc, char **argv, struct parameters_t *p_parameters){    
122     char *arg;
123     int ret;
124     while ((ret = options("h:q:c:t:", argv, argc, &arg)) != -2)
125         {
126             switch (ret)
127                 {
128                 case 'h':
129                     strcpy(p_parameters->host, arg);
130                     break;
131                 case 'q':
132                     strcpy(p_parameters->query, arg);
133                     break;
134                 case 'c':
135                     p_parameters->concurrent = atoi(arg);
136                     break;
137                 case 't':
138                     p_parameters->timeout = atoi(arg);
139                     break;
140                 case 0:
141                     //for (i = 0; i<number; i++)
142                     //    yaz_log(level, "%s", arg);
143                     print_option_error();
144                     break;
145                 default:
146                     print_option_error();
147                 }
148         }
149
150     //printf("zoom-benchmark\n");
151     //printf("   host:       %s \n", p_parameters->host);
152     //printf("   query:      %s \n", p_parameters->query);
153     //printf("   concurrent: %d \n", p_parameters->concurrent);
154     //printf("   timeout:    %d \n\n", p_parameters->timeout);
155
156     if (! strlen(p_parameters->host))
157         print_option_error();
158     if (! strlen(p_parameters->query))
159         print_option_error();
160     if (! (p_parameters->concurrent > 0))
161         print_option_error();
162     if (! (p_parameters->timeout >= 0))
163         print_option_error();
164 }
165
166
167
168 int main(int argc, char **argv)
169 {
170     struct time_type time;
171     ZOOM_connection *z;
172     ZOOM_resultset *r;
173     ZOOM_options o;
174     int i;
175
176     init_statics();
177
178     read_params(argc, argv, &parameters);
179
180     z = xmalloc(sizeof(*z) * parameters.concurrent);
181     r = xmalloc(sizeof(*r) * parameters.concurrent);
182     o = ZOOM_options_create();
183
184     /* async mode */
185     ZOOM_options_set (o, "async", "1");
186
187     /* get first record of result set (using piggyback) */
188     ZOOM_options_set (o, "count", "1");
189
190     /* preferred record syntax */
191     //ZOOM_options_set (o, "preferredRecordSyntax", "usmarc");
192     //ZOOM_options_set (o, "elementSetName", "F");
193
194     /* connect to all concurrent connections*/
195     for ( i = 0; i < parameters.concurrent; i++){
196         /* create connection - pass options (they are the same for all) */
197         z[i] = ZOOM_connection_create(o);
198
199         /* connect and init */
200             ZOOM_connection_connect(z[i], parameters.host, 0);
201     }
202     /* search all */
203     for (i = 0; i < parameters.concurrent; i++)
204         r[i] = ZOOM_connection_search_pqf (z[i], parameters.query);
205
206     // print header of table
207     printf ("second.usec\ttarget\tprogress\tevent\teventname\t");
208     printf("error\terrorname\n");
209     time_init(&time);
210     /* network I/O. pass number of connections and array of connections */
211     while ((i = ZOOM_event (parameters.concurrent, z)))
212     { 
213         int event = ZOOM_connection_last_event(z[i-1]);
214         const char *errmsg;
215         const char *addinfo;
216         int error = 0;
217         int progress = zoom_progress[event];
218
219         if (event == ZOOM_EVENT_SEND_DATA | event == ZOOM_EVENT_RECV_DATA)
220             continue;
221  
222
223         time_stamp(&time);
224  
225         error = ZOOM_connection_error(z[i-1] , &errmsg, &addinfo);
226         if (error)
227             parameters.progress[i] = -progress;
228         else
229             parameters.progress[i] += 1;
230
231         printf ("%ld.%06ld\t%d\t%d\t%d\t%s\t%d\t%s\n",
232                 time_sec(&time), time_usec(&time), 
233                 i-1, parameters.progress[i],
234                 event, zoom_events[event], 
235                 error, errmsg);
236
237     }
238     
239     /* no more to be done. Inspect results */
240     // commented out right now - do nothing
241 /*     for (i = 0; i<parameters.concurrent; i++) */
242 /*     { */
243 /*         int error; */
244 /*         const char *errmsg, *addinfo; */
245 /*         const char *tname = (same_target ? argv[2] : argv[1+i]); */
246 /*         /\* display errors if any *\/ */
247 /*         if ((error = ZOOM_connection_error(z[i], &errmsg, &addinfo))) */
248 /*             fprintf (stderr, "%s error: %s (%d) %s\n", tname, errmsg, */
249 /*                      error, addinfo); */
250 /*         else */
251 /*         { */
252 /*             /\* OK, no major errors. Look at the result count *\/ */
253 /*             int pos; */
254 /*             printf ("%s: %d hits\n", tname, ZOOM_resultset_size(r[i])); */
255 /*             /\* go through all records at target *\/ */
256 /*             for (pos = 0; pos < 10; pos++) */
257 /*             { */
258 /*                 int len; /\* length of buffer rec *\/ */
259 /*                 const char *rec = */
260 /*                     ZOOM_record_get ( */
261 /*                         ZOOM_resultset_record (r[i], pos), "render", &len); */
262 /*                 /\* if rec is non-null, we got a record for display *\/ */
263 /*                 if (rec) */
264 /*                 { */
265 /*                     printf ("%d\n", pos+1); */
266 /*                     if (rec) */
267 /*                         fwrite (rec, 1, len, stdout); */
268 /*                     printf ("\n"); */
269 /*                 } */
270 /*             } */
271 /*         } */
272 /*     } */
273
274     /* destroy and exit */
275     for (i = 0; i<parameters.concurrent; i++)
276     {
277         ZOOM_resultset_destroy (r[i]);
278         ZOOM_connection_destroy (z[i]);
279     }
280     xfree(z);
281     xfree(r);
282     ZOOM_options_destroy(o);
283     exit (0);
284 }
285 /*
286  * Local variables:
287  * c-basic-offset: 4
288  * indent-tabs-mode: nil
289  * End:
290  * vim: shiftwidth=4 tabstop=8 expandtab
291  */
292