307b6ab8d79260eb3d82257cb2780ffd71fdf84f
[yaz-moved-to-github.git] / zoom / zoom-benchmark.c
1 /*
2  * $Id: zoom-benchmark.c,v 1.8 2005-09-16 10:51:05 adam 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 #if 0
62     parameters.host = "";
63     parameters.query = "";
64 #endif
65     parameters.concurrent = 1;
66     parameters.timeout = 0;
67
68     /* progress initializing */
69     if (1)
70     {
71         int i;
72         for (i = 0; i < 4096; i++){
73             parameters.progress[i] = 0;
74         }
75     }
76     
77 }
78  
79 struct time_type 
80 {
81     struct timeval now;
82     struct timeval then;
83     long sec;
84     long usec;
85 };
86
87 void time_init(struct time_type *ptime)
88 {
89     gettimeofday(&(ptime->now), 0);
90     gettimeofday(&(ptime->then), 0);
91     ptime->sec = 0;
92     ptime->usec = 0;
93 }
94
95 void time_stamp(struct time_type *ptime)
96 {
97     gettimeofday(&(ptime->now), 0);
98     ptime->sec = ptime->now.tv_sec - ptime->then.tv_sec;
99     ptime->usec = ptime->now.tv_usec - ptime->then.tv_usec;
100     if (ptime->usec < 0){
101         ptime->sec--;
102         ptime->usec += 1000000;
103     }
104 }
105
106 long time_sec(struct time_type *ptime)
107 {
108     return ptime->sec;
109 }
110
111 long time_usec(struct time_type *ptime)
112 {
113     return ptime->usec;
114 }
115
116 void print_option_error()
117 {
118     fprintf(stderr, "zoom-benchmark:  Call error\n");
119     fprintf(stderr, "zoom-benchmark -h host:port -q pqf-query "
120             "[-c no_concurrent] "
121             "[-t timeout] \n");
122     exit(1);
123 }
124
125
126 void read_params(int argc, char **argv, struct parameters_t *p_parameters){    
127     char *arg;
128     int ret;
129     while ((ret = options("h:q:c:t:", argv, argc, &arg)) != -2)
130     {
131         switch (ret)
132         {
133         case 'h':
134             strcpy(p_parameters->host, arg);
135             break;
136         case 'q':
137             strcpy(p_parameters->query, arg);
138             break;
139         case 'c':
140             p_parameters->concurrent = atoi(arg);
141             break;
142         case 't':
143             p_parameters->timeout = atoi(arg);
144                     break;
145         case 0:
146             print_option_error();
147             break;
148         default:
149             print_option_error();
150         }
151     }
152     
153 #if 0
154     printf("zoom-benchmark\n");
155     printf("   host:       %s \n", p_parameters->host);
156     printf("   query:      %s \n", p_parameters->query);
157     printf("   concurrent: %d \n", p_parameters->concurrent);
158     printf("   timeout:    %d \n\n", p_parameters->timeout);
159 #endif
160
161     if (! strlen(p_parameters->host))
162         print_option_error();
163     if (! strlen(p_parameters->query))
164         print_option_error();
165     if (! (p_parameters->concurrent > 0))
166         print_option_error();
167     if (! (p_parameters->timeout >= 0))
168         print_option_error();
169 }
170
171
172
173 int main(int argc, char **argv)
174 {
175     struct time_type time;
176     ZOOM_connection *z;
177     ZOOM_resultset *r;
178     ZOOM_options o;
179     int i;
180
181     init_statics();
182
183     read_params(argc, argv, &parameters);
184
185     z = xmalloc(sizeof(*z) * parameters.concurrent);
186     r = xmalloc(sizeof(*r) * parameters.concurrent);
187     o = ZOOM_options_create();
188
189     /* async mode */
190     ZOOM_options_set (o, "async", "1");
191
192     /* get first record of result set (using piggyback) */
193     ZOOM_options_set (o, "count", "1");
194
195     /* preferred record syntax */
196 #if 0
197     ZOOM_options_set (o, "preferredRecordSyntax", "usmarc");
198     ZOOM_options_set (o, "elementSetName", "F");
199 #endif
200
201     /* connect to all concurrent connections*/
202     for ( i = 0; i < parameters.concurrent; i++){
203         /* create connection - pass options (they are the same for all) */
204         z[i] = ZOOM_connection_create(o);
205
206         /* connect and init */
207         ZOOM_connection_connect(z[i], parameters.host, 0);
208     }
209     /* search all */
210     for (i = 0; i < parameters.concurrent; i++)
211         r[i] = ZOOM_connection_search_pqf (z[i], parameters.query);
212
213     /* print header of table */
214     printf ("target\tsecond.usec\tprogress\tevent\teventname\t");
215     printf("error\terrorname\n");
216     time_init(&time);
217     /* network I/O. pass number of connections and array of connections */
218     while ((i = ZOOM_event (parameters.concurrent, z)))
219     { 
220         int event = ZOOM_connection_last_event(z[i-1]);
221         const char *errmsg;
222         const char *addinfo;
223         int error = 0;
224         int progress = zoom_progress[event];
225
226         if (event == ZOOM_EVENT_SEND_DATA || event == ZOOM_EVENT_RECV_DATA)
227             continue;
228  
229
230         time_stamp(&time);
231  
232         error = ZOOM_connection_error(z[i-1] , &errmsg, &addinfo);
233         if (error)
234             parameters.progress[i] = -progress;
235         else
236             parameters.progress[i] += 1;
237
238         printf ("%d\t%ld.%06ld\t%d\t%d\t%s\t%d\t%s\n",
239                 i-1, time_sec(&time), time_usec(&time), 
240                 parameters.progress[i],
241                 event, zoom_events[event], 
242                 error, errmsg);
243
244     }
245     
246     /* destroy and exit */
247     for (i = 0; i<parameters.concurrent; i++)
248     {
249         ZOOM_resultset_destroy (r[i]);
250         ZOOM_connection_destroy (z[i]);
251     }
252     xfree(z);
253     xfree(r);
254     ZOOM_options_destroy(o);
255     exit (0);
256 }
257 /*
258  * Local variables:
259  * c-basic-offset: 4
260  * indent-tabs-mode: nil
261  * End:
262  * vim: shiftwidth=4 tabstop=8 expandtab
263  */
264