mas01cr@239
|
1 #include "audioDB.h"
|
mas01cr@239
|
2 #include "adb.nsmap"
|
mas01cr@239
|
3
|
mas01cr@239
|
4 /* Command-line client definitions */
|
mas01cr@239
|
5
|
mas01cr@239
|
6 // FIXME: this can't propagate the sequence length argument (used for
|
mas01cr@239
|
7 // dudCount). See adb__status() definition for the other half of
|
mas01cr@239
|
8 // this. -- CSR, 2007-10-01
|
mas01cr@239
|
9 void audioDB::ws_status(const char*dbName, char* hostport){
|
mas01cr@239
|
10 struct soap soap;
|
mas01cr@239
|
11 adb__statusResponse adbStatusResponse;
|
mas01cr@239
|
12
|
mas01cr@239
|
13 // Query an existing adb database
|
mas01cr@239
|
14 soap_init(&soap);
|
mas01cr@239
|
15 if(soap_call_adb__status(&soap,hostport,NULL,(char*)dbName,adbStatusResponse)==SOAP_OK) {
|
mas01cr@239
|
16 std::cout << "numFiles = " << adbStatusResponse.result.numFiles << std::endl;
|
mas01cr@239
|
17 std::cout << "dim = " << adbStatusResponse.result.dim << std::endl;
|
mas01cr@239
|
18 std::cout << "length = " << adbStatusResponse.result.length << std::endl;
|
mas01cr@239
|
19 std::cout << "dudCount = " << adbStatusResponse.result.dudCount << std::endl;
|
mas01cr@239
|
20 std::cout << "nullCount = " << adbStatusResponse.result.nullCount << std::endl;
|
mas01mc@324
|
21 std::cout << "flags = " << (adbStatusResponse.result.flags & 0x00FFFFFF) << std::endl;
|
mas01cr@239
|
22 } else {
|
mas01cr@239
|
23 soap_print_fault(&soap,stderr);
|
mas01cr@239
|
24 }
|
mas01cr@239
|
25
|
mas01cr@239
|
26 soap_destroy(&soap);
|
mas01cr@239
|
27 soap_end(&soap);
|
mas01cr@239
|
28 soap_done(&soap);
|
mas01cr@239
|
29 }
|
mas01cr@239
|
30
|
mas01mc@308
|
31 // WS_QUERY (CLIENT SIDE)
|
mas01mc@307
|
32 void audioDB::ws_query(const char*dbName, const char *featureFileName, const char* hostport){
|
mas01cr@239
|
33 struct soap soap;
|
mas01cr@239
|
34 adb__queryResponse adbQueryResponse;
|
mas01cr@239
|
35
|
mas01cr@239
|
36 soap_init(&soap);
|
mas01cr@239
|
37 if(soap_call_adb__query(&soap,hostport,NULL,
|
mas01mc@307
|
38 (char*)dbName,(char*)featureFileName,(char*)trackFileName,(char*)timesFileName,
|
mas01cr@239
|
39 queryType, queryPoint, pointNN, trackNN, sequenceLength, adbQueryResponse)==SOAP_OK){
|
mas01cr@239
|
40 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
|
mas01cr@239
|
41 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
|
mas01cr@239
|
42 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
|
mas01cr@239
|
43 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
|
mas01cr@239
|
44 }
|
mas01cr@239
|
45 else
|
mas01cr@239
|
46 soap_print_fault(&soap,stderr);
|
mas01cr@239
|
47
|
mas01cr@239
|
48 soap_destroy(&soap);
|
mas01cr@239
|
49 soap_end(&soap);
|
mas01cr@239
|
50 soap_done(&soap);
|
mas01cr@239
|
51 }
|
mas01mc@307
|
52
|
mas01mc@308
|
53 // WS_QUERY_BY_KEY (CLIENT SIDE)
|
mas01mc@328
|
54 void audioDB::ws_query_by_key(const char*dbName, const char *trackKey, const char* featureFileName, const char* hostport){
|
mas01mc@307
|
55 struct soap soap;
|
mas01mc@307
|
56 adb__queryResponse adbQueryResponse;
|
mas01mc@314
|
57 /* JUST TRY TO USE A DATA STRUCTURE WITH PHP
|
mas01mc@314
|
58 adb__sequenceQueryParms asqp;
|
mas01mc@314
|
59 asqp.keyList = (char*)trackFileName;
|
mas01mc@314
|
60 asqp.timesFileName = (char*)timesFileName;
|
mas01mc@314
|
61 asqp.queryPoint = queryPoint;
|
mas01mc@314
|
62 asqp.pointNN = pointNN;
|
mas01mc@314
|
63 asqp.trackNN = trackNN;
|
mas01mc@314
|
64 asqp.sequenceLength = sequenceLength;
|
mas01mc@314
|
65 asqp.radius = radius;
|
mas01mc@314
|
66 asqp.relative_threshold = relative_threshold;
|
mas01mc@314
|
67 asqp.absolute_threshold = absolute_threshold;
|
mas01mc@314
|
68 asqp.usingQueryPoint = usingQueryPoint;
|
mas01mc@314
|
69 asqp.lsh_exact = lsh_exact;
|
mas01mc@314
|
70 */
|
mas01mc@307
|
71
|
mas01mc@307
|
72 soap_init(&soap);
|
mas01mc@307
|
73 if(queryType==O2_SEQUENCE_QUERY || queryType==O2_N_SEQUENCE_QUERY){
|
mas01mc@314
|
74 if(soap_call_adb__sequenceQueryByKey(&soap,hostport,NULL,
|
mas01mc@328
|
75 (char*)dbName,
|
mas01mc@328
|
76 (char*)trackKey,
|
mas01mc@328
|
77 (char*)featureFileName,
|
mas01mc@328
|
78 queryType,
|
mas01mc@328
|
79 (char*)trackFileName, // this means keyFileName
|
mas01mc@328
|
80 (char*)timesFileName,
|
mas01mc@314
|
81 queryPoint,
|
mas01mc@328
|
82 pointNN,
|
mas01mc@328
|
83 trackNN,
|
mas01mc@328
|
84 sequenceLength,
|
mas01mc@328
|
85 radius,
|
mas01mc@328
|
86 absolute_threshold,
|
mas01mc@328
|
87 usingQueryPoint,
|
mas01mc@314
|
88 lsh_exact,
|
mas01mc@314
|
89 adbQueryResponse)==SOAP_OK){
|
mas01mc@307
|
90 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
|
mas01mc@307
|
91 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
|
mas01mc@307
|
92 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
|
mas01mc@307
|
93 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
|
mas01mc@307
|
94 }
|
mas01mc@307
|
95 else
|
mas01mc@307
|
96 soap_print_fault(&soap,stderr);
|
mas01mc@307
|
97 }else
|
mas01mc@307
|
98 ;// FIX ME: WRITE NON-SEQUENCE QUERY BY KEY ?
|
mas01mc@307
|
99
|
mas01mc@307
|
100 soap_destroy(&soap);
|
mas01mc@307
|
101 soap_end(&soap);
|
mas01mc@307
|
102 soap_done(&soap);
|
mas01mc@307
|
103 }
|
mas01mc@307
|
104
|
mas01cr@239
|
105
|
mas01cr@239
|
106 /* Server definitions */
|
mas01cr@239
|
107 int adb__status(struct soap* soap, xsd__string dbName, adb__statusResponse &adbStatusResponse){
|
mas01mc@307
|
108 char* const argv[]={"./audioDB",COM_STATUS,"-d",dbName};
|
mas01cr@239
|
109 const unsigned argc = 4;
|
mas01cr@239
|
110 try {
|
mas01cr@239
|
111 audioDB(argc, argv, &adbStatusResponse);
|
mas01cr@239
|
112 return SOAP_OK;
|
mas01cr@239
|
113 } catch(char *err) {
|
mas01cr@239
|
114 soap_receiver_fault(soap, err, "");
|
mas01cr@239
|
115 return SOAP_FAULT;
|
mas01cr@239
|
116 }
|
mas01cr@239
|
117 }
|
mas01mc@308
|
118
|
mas01cr@239
|
119 // Literal translation of command line to web service
|
mas01cr@239
|
120 int adb__query(struct soap* soap, xsd__string dbName, xsd__string qKey, xsd__string keyList, xsd__string timesFileName, xsd__int qType, xsd__int qPos, xsd__int pointNN, xsd__int trackNN, xsd__int seqLen, adb__queryResponse &adbQueryResponse){
|
mas01cr@239
|
121 char queryType[256];
|
mas01cr@239
|
122 for(int k=0; k<256; k++)
|
mas01cr@239
|
123 queryType[k]='\0';
|
mas01cr@239
|
124 if(qType == O2_POINT_QUERY)
|
mas01cr@239
|
125 strncpy(queryType, "point", strlen("point"));
|
mas01cr@239
|
126 else if (qType == O2_SEQUENCE_QUERY)
|
mas01cr@239
|
127 strncpy(queryType, "sequence", strlen("sequence"));
|
mas01cr@239
|
128 else if(qType == O2_TRACK_QUERY)
|
mas01cr@239
|
129 strncpy(queryType,"track", strlen("track"));
|
mas01mc@324
|
130 else if(qType == O2_N_SEQUENCE_QUERY)
|
mas01mc@324
|
131 strncpy(queryType,"nsequence", strlen("nsequence"));
|
mas01cr@239
|
132
|
mas01cr@239
|
133 if(pointNN==0)
|
mas01cr@239
|
134 pointNN=10;
|
mas01cr@239
|
135 if(trackNN==0)
|
mas01cr@239
|
136 trackNN=10;
|
mas01cr@239
|
137 if(seqLen==0)
|
mas01cr@239
|
138 seqLen=16;
|
mas01cr@239
|
139
|
mas01cr@239
|
140 char qPosStr[256];
|
mas01cr@239
|
141 sprintf(qPosStr, "%d", qPos);
|
mas01cr@239
|
142 char pointNNStr[256];
|
mas01cr@239
|
143 sprintf(pointNNStr,"%d",pointNN);
|
mas01cr@239
|
144 char trackNNStr[256];
|
mas01cr@239
|
145 sprintf(trackNNStr,"%d",trackNN);
|
mas01cr@239
|
146 char seqLenStr[256];
|
mas01cr@239
|
147 sprintf(seqLenStr,"%d",seqLen);
|
mas01cr@239
|
148
|
mas01cr@239
|
149 const char* argv[] ={
|
mas01cr@239
|
150 "./audioDB",
|
mas01cr@239
|
151 COM_QUERY,
|
mas01cr@239
|
152 queryType, // Need to pass a parameter
|
mas01cr@239
|
153 COM_DATABASE,
|
mas01cr@239
|
154 ENSURE_STRING(dbName),
|
mas01cr@239
|
155 COM_FEATURES,
|
mas01cr@239
|
156 ENSURE_STRING(qKey),
|
mas01cr@239
|
157 COM_KEYLIST,
|
mas01cr@239
|
158 ENSURE_STRING(keyList),
|
mas01cr@239
|
159 COM_TIMES,
|
mas01cr@239
|
160 ENSURE_STRING(timesFileName),
|
mas01cr@239
|
161 COM_QPOINT,
|
mas01cr@239
|
162 qPosStr,
|
mas01cr@239
|
163 COM_POINTNN,
|
mas01cr@239
|
164 pointNNStr,
|
mas01cr@239
|
165 COM_TRACKNN,
|
mas01cr@239
|
166 trackNNStr, // Need to pass a parameter
|
mas01cr@239
|
167 COM_SEQLEN,
|
mas01cr@239
|
168 seqLenStr
|
mas01cr@239
|
169 };
|
mas01cr@239
|
170
|
mas01cr@239
|
171 const unsigned argc = 19;
|
mas01cr@239
|
172 try {
|
mas01cr@239
|
173 audioDB(argc, (char* const*)argv, &adbQueryResponse);
|
mas01cr@239
|
174 return SOAP_OK;
|
mas01cr@239
|
175 } catch (char *err) {
|
mas01cr@239
|
176 soap_receiver_fault(soap, err, "");
|
mas01cr@239
|
177 return SOAP_FAULT;
|
mas01cr@239
|
178 }
|
mas01cr@239
|
179 }
|
mas01cr@239
|
180
|
mas01mc@314
|
181 int adb__sequenceQueryByKey(struct soap* soap,xsd__string dbName,
|
mas01mc@314
|
182 xsd__string trackKey,
|
mas01mc@328
|
183 xsd__string featureFileName,
|
mas01mc@314
|
184 xsd__int queryType,
|
mas01mc@328
|
185 xsd__string keyFileName,
|
mas01mc@314
|
186 xsd__string timesFileName,
|
mas01mc@314
|
187 xsd__int queryPoint,
|
mas01mc@314
|
188 xsd__int pointNN,
|
mas01mc@314
|
189 xsd__int trackNN,
|
mas01mc@314
|
190 xsd__int sequenceLength,
|
mas01mc@314
|
191 xsd__double radius,
|
mas01mc@314
|
192 xsd__double absolute_threshold,
|
mas01mc@314
|
193 xsd__int usingQueryPoint,
|
mas01mc@314
|
194 xsd__int lsh_exact,
|
mas01mc@314
|
195 struct adb__queryResponse& adbQueryResponse){
|
mas01mc@307
|
196 char radiusStr[256];
|
mas01cr@239
|
197 char qPosStr[256];
|
mas01cr@239
|
198 char pointNNStr[256];
|
mas01cr@239
|
199 char trackNNStr[256];
|
mas01cr@239
|
200 char seqLenStr[256];
|
mas01cr@239
|
201 char absolute_thresholdStr[256];
|
mas01mc@307
|
202 char qtypeStr[256];
|
mas01cr@239
|
203
|
mas01cr@239
|
204 /* When the branch is merged, move this to a header and use it
|
mas01cr@239
|
205 elsewhere */
|
mas01cr@239
|
206 #define INTSTRINGIFY(val, str) \
|
mas01cr@239
|
207 snprintf(str, 256, "%d", val);
|
mas01cr@239
|
208 #define DOUBLESTRINGIFY(val, str) \
|
mas01cr@239
|
209 snprintf(str, 256, "%f", val);
|
mas01cr@239
|
210
|
mas01mc@314
|
211 INTSTRINGIFY(queryPoint, qPosStr);
|
mas01mc@314
|
212 INTSTRINGIFY(pointNN, pointNNStr);
|
mas01mc@314
|
213 INTSTRINGIFY(trackNN, trackNNStr);
|
mas01mc@314
|
214 INTSTRINGIFY(sequenceLength, seqLenStr);
|
mas01mc@314
|
215 DOUBLESTRINGIFY(absolute_threshold, absolute_thresholdStr);
|
mas01mc@314
|
216 DOUBLESTRINGIFY(radius, radiusStr);
|
mas01mc@307
|
217
|
mas01mc@307
|
218 // WS queries only support 1-nearest neighbour point reporting
|
mas01mc@307
|
219 // at the moment, until we figure out how to better serve results
|
mas01mc@307
|
220 snprintf(qtypeStr, 256, "nsequence");
|
mas01mc@310
|
221 const char *argv[]={
|
mas01cr@239
|
222 "./audioDB",
|
mas01cr@239
|
223 COM_QUERY,
|
mas01mc@307
|
224 qtypeStr,
|
mas01cr@239
|
225 COM_DATABASE,
|
mas01cr@239
|
226 dbName,
|
mas01mc@328
|
227 strlen(trackKey)?COM_QUERYKEY:COM_FEATURES,
|
mas01mc@328
|
228 strlen(trackKey)?ENSURE_STRING(trackKey):ENSURE_STRING(featureFileName),
|
mas01cr@239
|
229 COM_KEYLIST,
|
mas01mc@328
|
230 ENSURE_STRING(keyFileName),
|
mas01mc@314
|
231 usingQueryPoint?COM_QPOINT:COM_EXHAUSTIVE,
|
mas01mc@314
|
232 usingQueryPoint?qPosStr:"",
|
mas01cr@239
|
233 COM_POINTNN,
|
mas01cr@239
|
234 pointNNStr,
|
mas01cr@239
|
235 COM_TRACKNN,
|
mas01cr@239
|
236 trackNNStr,
|
mas01mc@307
|
237 COM_RADIUS,
|
mas01mc@307
|
238 radiusStr,
|
mas01cr@239
|
239 COM_SEQLEN,
|
mas01cr@239
|
240 seqLenStr,
|
mas01cr@239
|
241 COM_ABSOLUTE_THRESH,
|
mas01mc@310
|
242 absolute_thresholdStr,
|
mas01mc@314
|
243 lsh_exact?COM_LSH_EXACT:""
|
mas01cr@239
|
244 };
|
mas01cr@239
|
245
|
mas01mc@310
|
246 const unsigned argc = 22;
|
mas01mc@310
|
247
|
mas01mc@310
|
248
|
mas01cr@239
|
249 try {
|
mas01cr@239
|
250 audioDB(argc, (char* const*)argv, &adbQueryResponse);
|
mas01cr@239
|
251 return SOAP_OK;
|
mas01cr@239
|
252 } catch (char *err) {
|
mas01cr@239
|
253 soap_receiver_fault(soap, err, "");
|
mas01cr@239
|
254 return SOAP_FAULT;
|
mas01cr@239
|
255 }
|
mas01cr@239
|
256 }
|
mas01cr@239
|
257
|
mas01cr@239
|
258 /* Server loop */
|
mas01cr@239
|
259 void audioDB::startServer(){
|
mas01cr@239
|
260 struct soap soap;
|
mas01cr@239
|
261 int m, s; // master and slave sockets
|
mas01cr@239
|
262 soap_init(&soap);
|
mas01cr@239
|
263 // FIXME: largely this use of SO_REUSEADDR is to make writing (and
|
mas01cr@239
|
264 // running) test cases more convenient, so that multiple test runs
|
mas01cr@239
|
265 // in close succession don't fail because of a bin() error.
|
mas01cr@239
|
266 // Investigate whether there are any potential drawbacks in this,
|
mas01cr@239
|
267 // and also whether there's a better way to write the tests. --
|
mas01cr@239
|
268 // CSR, 2007-10-03
|
mas01cr@239
|
269 soap.bind_flags |= SO_REUSEADDR;
|
mas01cr@239
|
270 m = soap_bind(&soap, NULL, port, 100);
|
mas01cr@239
|
271 if (m < 0)
|
mas01cr@239
|
272 soap_print_fault(&soap, stderr);
|
mas01cr@239
|
273 else
|
mas01cr@239
|
274 {
|
mas01cr@239
|
275 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
|
mas01mc@308
|
276 // Make a global Web Services LSH Index (SINGLETON)
|
mas01mc@313
|
277 if(WS_load_index && dbName && !index_exists(dbName, radius, sequenceLength)){
|
mas01mc@313
|
278 error("Can't find requested index file:", index_get_name(dbName,radius,sequenceLength));
|
mas01mc@313
|
279 }
|
mas01mc@308
|
280 if(WS_load_index && dbName && index_exists(dbName, radius, sequenceLength)){
|
mas01mc@308
|
281 char* indexName = index_get_name(dbName, radius, sequenceLength);
|
mas01mc@308
|
282 fprintf(stderr, "Loading LSH hashtables: %s...\n", indexName);
|
mas01mc@308
|
283 lsh = new LSH(indexName, true);
|
mas01mc@308
|
284 assert(lsh);
|
mas01mc@308
|
285 SERVER_LSH_INDEX_SINGLETON = lsh;
|
mas01mc@308
|
286 fprintf(stderr, "LSH INDEX READY\n");
|
mas01mc@308
|
287 fflush(stderr);
|
mas01mc@308
|
288 delete[] indexName;
|
mas01mc@308
|
289 }
|
mas01mc@324
|
290
|
mas01mc@324
|
291 // Server-side path prefix to databases and features
|
mas01mc@324
|
292 if(adb_root)
|
mas01mc@324
|
293 SERVER_ADB_ROOT = (char*)adb_root; // Server-side database root
|
mas01mc@324
|
294 if(adb_feature_root)
|
mas01mc@324
|
295 SERVER_ADB_FEATURE_ROOT = (char*)adb_feature_root; // Server-side features root
|
mas01mc@308
|
296
|
mas01cr@239
|
297 for (int i = 1; ; i++)
|
mas01cr@239
|
298 {
|
mas01cr@239
|
299 s = soap_accept(&soap);
|
mas01cr@239
|
300 if (s < 0)
|
mas01cr@239
|
301 {
|
mas01cr@239
|
302 soap_print_fault(&soap, stderr);
|
mas01cr@239
|
303 break;
|
mas01cr@239
|
304 }
|
mas01cr@239
|
305 /* FIXME: find a way to play nice with logging when run from
|
mas01cr@239
|
306 /etc/init.d scripts: at present this just goes nowhere */
|
mas01cr@239
|
307 fprintf(stderr, "%d: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d\n", i,
|
mas01cr@239
|
308 (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s);
|
mas01cr@239
|
309 if (soap_serve(&soap) != SOAP_OK) // process RPC request
|
mas01cr@239
|
310 soap_print_fault(&soap, stderr); // print error
|
mas01cr@239
|
311 fprintf(stderr, "request served\n");
|
mas01cr@239
|
312 soap_destroy(&soap); // clean up class instances
|
mas01cr@239
|
313 soap_end(&soap); // clean up everything and close socket
|
mas01cr@239
|
314 }
|
mas01cr@239
|
315 }
|
mas01cr@239
|
316 soap_done(&soap); // close master socket and detach environment
|
mas01cr@239
|
317 }
|