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@550
|
23 char fault[MAXSTR];
|
mas01cr@550
|
24 soap_sprint_fault(&soap, fault, MAXSTR);
|
mas01cr@550
|
25 error(fault);
|
mas01cr@239
|
26 }
|
mas01cr@239
|
27
|
mas01cr@239
|
28 soap_destroy(&soap);
|
mas01cr@239
|
29 soap_end(&soap);
|
mas01cr@239
|
30 soap_done(&soap);
|
mas01cr@239
|
31 }
|
mas01cr@239
|
32
|
mas01mc@334
|
33 void audioDB::ws_liszt(const char* dbName, char* Hostport){
|
mas01mc@334
|
34 struct soap soap;
|
mas01mc@334
|
35 adb__lisztResponse adbLisztResponse;
|
mas01mc@334
|
36
|
mas01mc@334
|
37 soap_init(&soap);
|
mas01mc@334
|
38 if(soap_call_adb__liszt(&soap, hostport, NULL, (char*)dbName, lisztOffset, lisztLength, adbLisztResponse)==SOAP_OK){
|
mas01mc@334
|
39 for(int i = 0; i < adbLisztResponse.result.__sizeRkey; i++) {
|
mas01mc@334
|
40 std::cout << "[" << i+lisztOffset << "] " << adbLisztResponse.result.Rkey[i] << " ("
|
mas01mc@334
|
41 << adbLisztResponse.result.Rlen[i] << ")" << std::endl;
|
mas01mc@334
|
42 }
|
mas01mc@334
|
43 } else {
|
mas01cr@550
|
44 char fault[MAXSTR];
|
mas01cr@550
|
45 soap_sprint_fault(&soap, fault, MAXSTR);
|
mas01cr@550
|
46 error(fault);
|
mas01mc@334
|
47 }
|
mas01cr@550
|
48 soap_destroy(&soap);
|
mas01cr@550
|
49 soap_end(&soap);
|
mas01cr@550
|
50 soap_done(&soap);
|
mas01mc@334
|
51 }
|
mas01mc@334
|
52
|
mas01mc@308
|
53 // WS_QUERY (CLIENT SIDE)
|
mas01mc@307
|
54 void audioDB::ws_query(const char*dbName, const char *featureFileName, const char* hostport){
|
mas01cr@239
|
55 struct soap soap;
|
mas01cr@239
|
56 adb__queryResponse adbQueryResponse;
|
mas01mc@329
|
57 VERB_LOG(1, "Calling fileName query on database %s with featureFile=%s\n", dbName, featureFileName);
|
mas01cr@333
|
58 soap_init(&soap);
|
mas01cr@333
|
59 if(soap_call_adb__query(&soap, hostport, NULL, (char *) dbName,
|
mas01cr@333
|
60 (char *)featureFileName, (char *)trackFileName,
|
mas01cr@333
|
61 (char *)timesFileName, (char *) powerFileName,
|
mas01cr@333
|
62 queryType, queryPoint,
|
mas01cr@333
|
63 pointNN, trackNN, sequenceLength,
|
mas01cr@333
|
64 radius, absolute_threshold, relative_threshold,
|
mas01mc@471
|
65 !usingQueryPoint, lsh_exact, no_unit_norming,
|
mas01cr@333
|
66 adbQueryResponse)
|
mas01cr@333
|
67 == SOAP_OK) {
|
mas01cr@333
|
68 if(radius == 0) {
|
mas01cr@333
|
69 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++) {
|
mas01cr@333
|
70 std::cout << adbQueryResponse.result.Rlist[i] << " "
|
mas01cr@333
|
71 << adbQueryResponse.result.Dist[i] << " "
|
mas01cr@333
|
72 << adbQueryResponse.result.Qpos[i] << " "
|
mas01cr@333
|
73 << adbQueryResponse.result.Spos[i] << std::endl;
|
mas01cr@333
|
74 }
|
mas01cr@333
|
75 } else {
|
mas01cr@333
|
76 for(int i = 0; i < adbQueryResponse.result.__sizeRlist; i++) {
|
mas01cr@333
|
77 std::cout << adbQueryResponse.result.Rlist[i] << " "
|
mas01cr@333
|
78 << adbQueryResponse.result.Spos[i] << std::endl;
|
mas01cr@333
|
79 }
|
mas01cr@333
|
80 }
|
mas01cr@333
|
81 } else {
|
mas01cr@550
|
82 char fault[MAXSTR];
|
mas01cr@550
|
83 soap_sprint_fault(&soap, fault, MAXSTR);
|
mas01cr@550
|
84 error(fault);
|
mas01cr@239
|
85 }
|
mas01cr@333
|
86
|
mas01cr@239
|
87 soap_destroy(&soap);
|
mas01cr@239
|
88 soap_end(&soap);
|
mas01cr@239
|
89 soap_done(&soap);
|
mas01cr@239
|
90 }
|
mas01mc@307
|
91
|
mas01mc@308
|
92 // WS_QUERY_BY_KEY (CLIENT SIDE)
|
mas01mc@328
|
93 void audioDB::ws_query_by_key(const char*dbName, const char *trackKey, const char* featureFileName, const char* hostport){
|
mas01mc@307
|
94 struct soap soap;
|
mas01mc@307
|
95 adb__queryResponse adbQueryResponse;
|
mas01mc@314
|
96 /* JUST TRY TO USE A DATA STRUCTURE WITH PHP
|
mas01mc@314
|
97 adb__sequenceQueryParms asqp;
|
mas01mc@314
|
98 asqp.keyList = (char*)trackFileName;
|
mas01mc@314
|
99 asqp.timesFileName = (char*)timesFileName;
|
mas01mc@314
|
100 asqp.queryPoint = queryPoint;
|
mas01mc@314
|
101 asqp.pointNN = pointNN;
|
mas01mc@314
|
102 asqp.trackNN = trackNN;
|
mas01mc@314
|
103 asqp.sequenceLength = sequenceLength;
|
mas01mc@314
|
104 asqp.radius = radius;
|
mas01mc@314
|
105 asqp.relative_threshold = relative_threshold;
|
mas01mc@314
|
106 asqp.absolute_threshold = absolute_threshold;
|
mas01mc@314
|
107 asqp.usingQueryPoint = usingQueryPoint;
|
mas01mc@314
|
108 asqp.lsh_exact = lsh_exact;
|
mas01mc@314
|
109 */
|
mas01mc@331
|
110 VERB_LOG(1, "Calling %s query on database %s with %s=%s\n", (trackKey&&strlen(trackKey))?"KEY":"FILENAME", dbName, (trackKey&&strlen(trackKey))?"KEY":"FILENAME",(trackKey&&strlen(trackKey))?trackKey:featureFileName);
|
mas01mc@307
|
111 soap_init(&soap);
|
mas01mc@307
|
112 if(queryType==O2_SEQUENCE_QUERY || queryType==O2_N_SEQUENCE_QUERY){
|
mas01mc@314
|
113 if(soap_call_adb__sequenceQueryByKey(&soap,hostport,NULL,
|
mas01mc@328
|
114 (char*)dbName,
|
mas01mc@328
|
115 (char*)trackKey,
|
mas01mc@328
|
116 (char*)featureFileName,
|
mas01mc@328
|
117 queryType,
|
mas01mc@328
|
118 (char*)trackFileName, // this means keyFileName
|
mas01mc@328
|
119 (char*)timesFileName,
|
mas01mc@314
|
120 queryPoint,
|
mas01mc@328
|
121 pointNN,
|
mas01mc@328
|
122 trackNN,
|
mas01mc@328
|
123 sequenceLength,
|
mas01mc@328
|
124 radius,
|
mas01mc@328
|
125 absolute_threshold,
|
mas01mc@328
|
126 usingQueryPoint,
|
mas01mc@471
|
127 lsh_exact,
|
mas01mc@471
|
128 no_unit_norming,
|
mas01mc@314
|
129 adbQueryResponse)==SOAP_OK){
|
mas01mc@307
|
130 //std::std::cerr << "result list length:" << adbQueryResponse.result.__sizeRlist << std::std::endl;
|
mas01mc@307
|
131 for(int i=0; i<adbQueryResponse.result.__sizeRlist; i++)
|
mas01mc@307
|
132 std::cout << adbQueryResponse.result.Rlist[i] << " " << adbQueryResponse.result.Dist[i]
|
mas01mc@307
|
133 << " " << adbQueryResponse.result.Qpos[i] << " " << adbQueryResponse.result.Spos[i] << std::endl;
|
mas01cr@550
|
134 } else {
|
mas01cr@550
|
135 char fault[MAXSTR];
|
mas01cr@550
|
136 soap_sprint_fault(&soap, fault, MAXSTR);
|
mas01cr@550
|
137 error(fault);
|
mas01mc@307
|
138 }
|
mas01cr@550
|
139 } else
|
mas01mc@307
|
140 ;// FIX ME: WRITE NON-SEQUENCE QUERY BY KEY ?
|
mas01mc@307
|
141
|
mas01mc@307
|
142 soap_destroy(&soap);
|
mas01mc@307
|
143 soap_end(&soap);
|
mas01mc@307
|
144 soap_done(&soap);
|
mas01mc@307
|
145 }
|
mas01mc@307
|
146
|
mas01cr@239
|
147
|
mas01cr@333
|
148 /* handy macros */
|
mas01cr@333
|
149 #define INTSTRINGIFY(val, str) \
|
mas01cr@333
|
150 char str[256]; \
|
mas01cr@333
|
151 snprintf(str, 256, "%d", val);
|
mas01cr@333
|
152 #define DOUBLESTRINGIFY(val, str) \
|
mas01cr@333
|
153 char str[256]; \
|
mas01cr@333
|
154 snprintf(str, 256, "%f", val);
|
mas01cr@333
|
155
|
mas01cr@239
|
156 /* Server definitions */
|
mas01cr@239
|
157 int adb__status(struct soap* soap, xsd__string dbName, adb__statusResponse &adbStatusResponse){
|
mas01cr@370
|
158 const char *argv[]={"./audioDB",COM_STATUS,"-d",dbName};
|
mas01cr@239
|
159 const unsigned argc = 4;
|
mas01cr@239
|
160 try {
|
mas01cr@239
|
161 audioDB(argc, argv, &adbStatusResponse);
|
mas01cr@239
|
162 return SOAP_OK;
|
mas01cr@239
|
163 } catch(char *err) {
|
mas01cr@239
|
164 soap_receiver_fault(soap, err, "");
|
mas01cr@239
|
165 return SOAP_FAULT;
|
mas01cr@239
|
166 }
|
mas01cr@239
|
167 }
|
mas01mc@334
|
168
|
mas01mc@334
|
169 int adb__liszt(struct soap* soap, xsd__string dbName, xsd__int lisztOffset, xsd__int lisztLength,
|
mas01mc@334
|
170 adb__lisztResponse& adbLisztResponse){
|
mas01mc@334
|
171
|
mas01mc@334
|
172 INTSTRINGIFY(lisztOffset, lisztOffsetStr);
|
mas01mc@334
|
173 INTSTRINGIFY(lisztLength, lisztLengthStr);
|
mas01mc@334
|
174
|
mas01cr@370
|
175 const char *argv[] = {"./audioDB", COM_LISZT, "-d",dbName, "--lisztOffset", lisztOffsetStr, "--lisztLength", lisztLengthStr};
|
mas01mc@334
|
176 const unsigned argc = 8;
|
mas01mc@334
|
177 try{
|
mas01cr@548
|
178 audioDB(argc, argv, soap, &adbLisztResponse);
|
mas01mc@334
|
179 return SOAP_OK;
|
mas01mc@334
|
180 } catch(char *err) {
|
mas01mc@334
|
181 soap_receiver_fault(soap, err, "");
|
mas01mc@334
|
182 return SOAP_FAULT;
|
mas01mc@334
|
183 }
|
mas01mc@334
|
184 }
|
mas01mc@334
|
185
|
mas01cr@239
|
186 // Literal translation of command line to web service
|
mas01cr@333
|
187 int adb__query(struct soap* soap, xsd__string dbName,
|
mas01cr@333
|
188 xsd__string qKey, xsd__string keyList,
|
mas01cr@333
|
189 xsd__string timesFileName, xsd__string powerFileName,
|
mas01cr@333
|
190 xsd__int qType,
|
mas01cr@333
|
191 xsd__int qPos, xsd__int pointNN, xsd__int trackNN,
|
mas01cr@333
|
192 xsd__int seqLen,
|
mas01cr@333
|
193 xsd__double radius,
|
mas01cr@333
|
194 xsd__double absolute_threshold, xsd__double relative_threshold,
|
mas01mc@471
|
195 xsd__int exhaustive, xsd__int lsh_exact, xsd__int no_unit_norming,
|
mas01cr@333
|
196 adb__queryResponse &adbQueryResponse){
|
mas01cr@239
|
197 char queryType[256];
|
mas01mc@329
|
198
|
mas01mc@329
|
199 fprintf(stderr,"Calling fileName query on database %s with featureFile=%s\n", dbName, qKey);
|
mas01mc@329
|
200
|
mas01cr@239
|
201 for(int k=0; k<256; k++)
|
mas01cr@239
|
202 queryType[k]='\0';
|
mas01cr@239
|
203 if(qType == O2_POINT_QUERY)
|
mas01cr@239
|
204 strncpy(queryType, "point", strlen("point"));
|
mas01cr@239
|
205 else if (qType == O2_SEQUENCE_QUERY)
|
mas01cr@239
|
206 strncpy(queryType, "sequence", strlen("sequence"));
|
mas01cr@239
|
207 else if(qType == O2_TRACK_QUERY)
|
mas01cr@239
|
208 strncpy(queryType,"track", strlen("track"));
|
mas01mc@324
|
209 else if(qType == O2_N_SEQUENCE_QUERY)
|
mas01mc@324
|
210 strncpy(queryType,"nsequence", strlen("nsequence"));
|
mas01cr@239
|
211
|
mas01cr@239
|
212 if(pointNN==0)
|
mas01cr@239
|
213 pointNN=10;
|
mas01cr@239
|
214 if(trackNN==0)
|
mas01cr@239
|
215 trackNN=10;
|
mas01cr@239
|
216 if(seqLen==0)
|
mas01cr@239
|
217 seqLen=16;
|
mas01cr@239
|
218
|
mas01cr@333
|
219 INTSTRINGIFY(qPos, qPosStr);
|
mas01cr@333
|
220 INTSTRINGIFY(pointNN, pointNNStr);
|
mas01cr@333
|
221 INTSTRINGIFY(trackNN, trackNNStr);
|
mas01cr@333
|
222 INTSTRINGIFY(seqLen, seqLenStr);
|
mas01cr@239
|
223
|
mas01cr@333
|
224 /* We don't necessarily use these, but because of scope we do this
|
mas01cr@333
|
225 anyway. We waste 756 bytes of stack this way. */
|
mas01cr@333
|
226 DOUBLESTRINGIFY(radius, radiusStr);
|
mas01cr@333
|
227 DOUBLESTRINGIFY(absolute_threshold, absolute_thresholdStr);
|
mas01cr@333
|
228 DOUBLESTRINGIFY(relative_threshold, relative_thresholdStr);
|
mas01cr@333
|
229
|
mas01cr@333
|
230 unsigned int argc = 19;
|
mas01cr@333
|
231 if (powerFileName) {
|
mas01cr@333
|
232 argc += 2;
|
mas01cr@333
|
233 }
|
mas01cr@333
|
234 if (radius != 0) {
|
mas01cr@333
|
235 argc += 2;
|
mas01cr@333
|
236 }
|
mas01cr@333
|
237 /* we can't use use_absolute_threshold and friends because we're not
|
mas01cr@333
|
238 in the audioDB class here. */
|
mas01cr@333
|
239 if (absolute_threshold != 0) {
|
mas01cr@333
|
240 argc += 2;
|
mas01cr@333
|
241 }
|
mas01cr@333
|
242 if (relative_threshold != 0) {
|
mas01cr@333
|
243 argc += 2;
|
mas01cr@333
|
244 }
|
mas01cr@333
|
245 if (exhaustive) {
|
mas01cr@333
|
246 argc++;
|
mas01cr@333
|
247 }
|
mas01cr@333
|
248 if (lsh_exact) {
|
mas01cr@333
|
249 argc++;
|
mas01cr@333
|
250 }
|
mas01cr@333
|
251
|
mas01mc@471
|
252 if(no_unit_norming){
|
mas01mc@471
|
253 argc++;
|
mas01mc@471
|
254 }
|
mas01mc@471
|
255
|
mas01cr@345
|
256 const char **argv = new const char*[argc+1];
|
mas01cr@333
|
257 argv[0] = "./audioDB";
|
mas01cr@333
|
258 argv[1] = COM_QUERY;
|
mas01cr@333
|
259 argv[2] = queryType;
|
mas01cr@333
|
260 argv[3] = COM_DATABASE;
|
mas01cr@333
|
261 argv[4] = (char *) (ENSURE_STRING(dbName));
|
mas01cr@333
|
262 argv[5] = COM_FEATURES;
|
mas01cr@333
|
263 argv[6] = (char *) (ENSURE_STRING(qKey));
|
mas01cr@333
|
264 argv[7] = COM_KEYLIST;
|
mas01cr@333
|
265 argv[8] = (char *) (ENSURE_STRING(keyList));
|
mas01cr@333
|
266 argv[9] = COM_TIMES;
|
mas01cr@333
|
267 argv[10] = (char *) (ENSURE_STRING(timesFileName));
|
mas01cr@333
|
268 argv[11] = COM_QPOINT;
|
mas01cr@333
|
269 argv[12] = qPosStr;
|
mas01cr@333
|
270 argv[13] = COM_POINTNN;
|
mas01cr@333
|
271 argv[14] = pointNNStr;
|
mas01cr@333
|
272 argv[15] = COM_TRACKNN;
|
mas01cr@333
|
273 argv[16] = trackNNStr;
|
mas01cr@333
|
274 argv[17] = COM_SEQLEN;
|
mas01cr@333
|
275 argv[18] = seqLenStr;
|
mas01cr@333
|
276 int argv_counter = 19;
|
mas01cr@333
|
277 if (powerFileName) {
|
mas01cr@333
|
278 argv[argv_counter++] = COM_QUERYPOWER;
|
mas01cr@333
|
279 argv[argv_counter++] = powerFileName;
|
mas01cr@333
|
280 }
|
mas01cr@333
|
281 if (radius != 0) {
|
mas01cr@333
|
282 argv[argv_counter++] = COM_RADIUS;
|
mas01cr@333
|
283 argv[argv_counter++] = radiusStr;
|
mas01cr@333
|
284 }
|
mas01cr@333
|
285 if (absolute_threshold != 0) {
|
mas01cr@333
|
286 argv[argv_counter++] = COM_ABSOLUTE_THRESH;
|
mas01cr@333
|
287 argv[argv_counter++] = absolute_thresholdStr;
|
mas01cr@333
|
288 }
|
mas01cr@333
|
289 if (relative_threshold != 0) {
|
mas01cr@333
|
290 argv[argv_counter++] = COM_RELATIVE_THRESH;
|
mas01cr@333
|
291 argv[argv_counter++] = relative_thresholdStr;
|
mas01cr@333
|
292 }
|
mas01cr@333
|
293 if (exhaustive) {
|
mas01cr@333
|
294 argv[argv_counter++] = COM_EXHAUSTIVE;
|
mas01cr@333
|
295 }
|
mas01cr@333
|
296 if (lsh_exact) {
|
mas01cr@333
|
297 argv[argv_counter++] = COM_LSH_EXACT;
|
mas01cr@333
|
298 }
|
mas01mc@471
|
299
|
mas01mc@471
|
300 if (no_unit_norming) {
|
mas01mc@471
|
301 argv[argv_counter++] = COM_NO_UNIT_NORMING;
|
mas01mc@471
|
302 }
|
mas01mc@471
|
303
|
mas01cr@333
|
304 argv[argv_counter] = NULL;
|
mas01cr@333
|
305
|
mas01cr@239
|
306 try {
|
mas01cr@508
|
307 audioDB(argc, argv, soap, &adbQueryResponse);
|
mas01cr@333
|
308 delete [] argv;
|
mas01cr@239
|
309 return SOAP_OK;
|
mas01cr@239
|
310 } catch (char *err) {
|
mas01cr@239
|
311 soap_receiver_fault(soap, err, "");
|
mas01cr@333
|
312 delete [] argv;
|
mas01cr@239
|
313 return SOAP_FAULT;
|
mas01cr@239
|
314 }
|
mas01cr@239
|
315 }
|
mas01cr@239
|
316
|
mas01mc@314
|
317 int adb__sequenceQueryByKey(struct soap* soap,xsd__string dbName,
|
mas01mc@314
|
318 xsd__string trackKey,
|
mas01mc@328
|
319 xsd__string featureFileName,
|
mas01mc@314
|
320 xsd__int queryType,
|
mas01mc@328
|
321 xsd__string keyFileName,
|
mas01mc@314
|
322 xsd__string timesFileName,
|
mas01mc@314
|
323 xsd__int queryPoint,
|
mas01mc@314
|
324 xsd__int pointNN,
|
mas01mc@314
|
325 xsd__int trackNN,
|
mas01mc@314
|
326 xsd__int sequenceLength,
|
mas01mc@314
|
327 xsd__double radius,
|
mas01mc@314
|
328 xsd__double absolute_threshold,
|
mas01mc@314
|
329 xsd__int usingQueryPoint,
|
mas01mc@471
|
330 xsd__int lsh_exact, xsd__int no_unit_norming,
|
mas01mc@314
|
331 struct adb__queryResponse& adbQueryResponse){
|
mas01mc@307
|
332 char qtypeStr[256];
|
mas01cr@239
|
333
|
mas01mc@471
|
334 fprintf(stderr, "Calling %s query on database %s with %s=%s, distFun:%s\n", (trackKey&&strlen(trackKey))?"KEY":"FILENAME", dbName, (trackKey&&strlen(trackKey))?"KEY":"FILENAME",(trackKey&&strlen(trackKey))?trackKey:featureFileName, no_unit_norming?"Euclidean":"Normed Euclidean");
|
mas01mc@329
|
335
|
mas01mc@314
|
336 INTSTRINGIFY(queryPoint, qPosStr);
|
mas01mc@314
|
337 INTSTRINGIFY(pointNN, pointNNStr);
|
mas01mc@314
|
338 INTSTRINGIFY(trackNN, trackNNStr);
|
mas01mc@314
|
339 INTSTRINGIFY(sequenceLength, seqLenStr);
|
mas01mc@314
|
340 DOUBLESTRINGIFY(absolute_threshold, absolute_thresholdStr);
|
mas01mc@314
|
341 DOUBLESTRINGIFY(radius, radiusStr);
|
mas01mc@307
|
342
|
mas01mc@307
|
343 snprintf(qtypeStr, 256, "nsequence");
|
mas01mc@310
|
344 const char *argv[]={
|
mas01cr@239
|
345 "./audioDB",
|
mas01cr@239
|
346 COM_QUERY,
|
mas01mc@307
|
347 qtypeStr,
|
mas01cr@239
|
348 COM_DATABASE,
|
mas01cr@239
|
349 dbName,
|
mas01mc@330
|
350 (trackKey&&strlen(trackKey))?COM_QUERYKEY:COM_FEATURES,
|
mas01mc@330
|
351 (trackKey&&strlen(trackKey))?ENSURE_STRING(trackKey):ENSURE_STRING(featureFileName),
|
mas01cr@239
|
352 COM_KEYLIST,
|
mas01mc@328
|
353 ENSURE_STRING(keyFileName),
|
mas01mc@314
|
354 usingQueryPoint?COM_QPOINT:COM_EXHAUSTIVE,
|
mas01mc@314
|
355 usingQueryPoint?qPosStr:"",
|
mas01cr@239
|
356 COM_POINTNN,
|
mas01cr@239
|
357 pointNNStr,
|
mas01cr@239
|
358 COM_TRACKNN,
|
mas01cr@239
|
359 trackNNStr,
|
mas01mc@307
|
360 COM_RADIUS,
|
mas01mc@307
|
361 radiusStr,
|
mas01cr@239
|
362 COM_SEQLEN,
|
mas01cr@239
|
363 seqLenStr,
|
mas01cr@239
|
364 COM_ABSOLUTE_THRESH,
|
mas01mc@310
|
365 absolute_thresholdStr,
|
mas01mc@471
|
366 lsh_exact?COM_LSH_EXACT:"",
|
mas01mc@471
|
367 no_unit_norming?COM_NO_UNIT_NORMING:"",
|
mas01cr@239
|
368 };
|
mas01cr@239
|
369
|
mas01mc@471
|
370 const unsigned argc = 23;
|
mas01mc@310
|
371
|
mas01mc@310
|
372
|
mas01cr@239
|
373 try {
|
mas01cr@508
|
374 audioDB(argc, argv, soap, &adbQueryResponse);
|
mas01cr@239
|
375 return SOAP_OK;
|
mas01cr@239
|
376 } catch (char *err) {
|
mas01cr@239
|
377 soap_receiver_fault(soap, err, "");
|
mas01cr@239
|
378 return SOAP_FAULT;
|
mas01cr@239
|
379 }
|
mas01cr@239
|
380 }
|
mas01mc@354
|
381
|
mas01cr@651
|
382 #if defined(WIN32)
|
mas01cr@651
|
383 int mkstemp(char *tmpFileName) {
|
mas01cr@651
|
384 int fd = -1;
|
mas01cr@651
|
385 mktemp(tmpFileName);
|
mas01cr@651
|
386 fd = open(tmpFileName,O_RDWR|O_BINARY|O_CREAT|O_EXCL, _S_IREAD|_S_IWRITE);
|
mas01cr@651
|
387 return fd;
|
mas01cr@651
|
388 }
|
mas01cr@651
|
389 #endif
|
mas01cr@651
|
390
|
mas01mc@354
|
391 // Query an audioDB database by vector (serialized)
|
mas01mc@471
|
392 int adb__shingleQuery(struct soap* soap, xsd__string dbName, struct adb__queryVector qVector, xsd__string keyList, xsd__string timesFileName, xsd__int queryType, xsd__int queryPos, xsd__int pointNN, xsd__int trackNN, xsd__int sequenceLength, xsd__double radius, xsd__double absolute_threshold, xsd__double relative_threshold, xsd__int exhaustive, xsd__int lsh_exact, xsd__int no_unit_norming, struct adb__queryResponse &adbQueryResponse){
|
mas01mc@354
|
393
|
mas01mc@354
|
394 // open a tmp file on the server, write shingle, query as a file with query point 0
|
mas01mc@354
|
395 // and shingle length l/dim
|
mas01mc@354
|
396 char tmpFileName[] = "/tmp/adb_XXXXXX";
|
mas01mc@354
|
397 int tmpFid = mkstemp(tmpFileName);
|
mas01mc@354
|
398 if(tmpFid==-1){
|
mas01mc@354
|
399 cerr << "Cannot make tmpfile <" << tmpFileName << "> on server" << endl;
|
mas01mc@354
|
400 return SOAP_FAULT;
|
mas01mc@354
|
401 }
|
mas01mc@354
|
402
|
mas01mc@354
|
403 FILE* tmpFile = fdopen(tmpFid, "r+b");
|
mas01mc@354
|
404 if(!tmpFile){
|
mas01mc@354
|
405 cerr << "error opening <" << tmpFileName << "> for write" << endl;
|
mas01mc@354
|
406 return SOAP_FAULT;
|
mas01mc@354
|
407 }
|
mas01mc@354
|
408
|
mas01mc@354
|
409 if(fwrite(&qVector.dim, sizeof(int), 1, tmpFile)!=1){
|
mas01mc@354
|
410 cerr << "error writing tmp file dim <"<< tmpFileName << ">" << endl;
|
mas01mc@354
|
411 return SOAP_FAULT;
|
mas01mc@354
|
412 }
|
mas01mc@354
|
413
|
mas01mc@354
|
414 if(fwrite(qVector.v, sizeof(double), qVector.__sizev, tmpFile)!=(size_t)qVector.__sizev){
|
mas01mc@354
|
415 cerr << "error writing tmp file doubles <" << tmpFileName << ">" << endl;
|
mas01mc@354
|
416 return SOAP_FAULT;
|
mas01mc@354
|
417 }
|
mas01mc@354
|
418
|
mas01mc@354
|
419 // Close the file so that a new FD can be opened
|
mas01mc@354
|
420 fclose(tmpFile);
|
mas01mc@354
|
421
|
mas01mc@354
|
422 char tmpFileName2[] = "/tmp/adbP_XXXXXX";
|
mas01mc@354
|
423 int tmpFid2 = 0;
|
mas01mc@354
|
424 FILE* tmpFile2 = NULL;
|
mas01mc@354
|
425
|
mas01mc@354
|
426 // Check if powers have been passed and write accordingly
|
mas01mc@354
|
427 if(qVector.__sizep){
|
mas01mc@354
|
428 tmpFid2 = mkstemp(tmpFileName2);
|
mas01mc@354
|
429 tmpFile2 = fdopen(tmpFid2, "r+b");
|
mas01mc@354
|
430 if(!tmpFile2){
|
mas01mc@354
|
431 cerr << "error opening power file <" << tmpFileName2 << "> for write" << endl;
|
mas01mc@354
|
432 return SOAP_FAULT;
|
mas01mc@354
|
433 }
|
mas01mc@354
|
434 int pSize=1;
|
mas01mc@354
|
435 if(fwrite(&pSize, sizeof(int), 1, tmpFile2)!=1){
|
mas01mc@354
|
436 cerr << "error writing tmp power file dim <"<< tmpFileName2 << ">" << endl;
|
mas01mc@354
|
437 return SOAP_FAULT;
|
mas01mc@354
|
438 }
|
mas01mc@354
|
439
|
mas01mc@354
|
440 if(fwrite(qVector.p, sizeof(double), qVector.__sizep, tmpFile2)!=(size_t)qVector.__sizep){
|
mas01mc@354
|
441 cerr << "error writing tmp power file doubles <" << tmpFileName2 << ">" << endl;
|
mas01mc@354
|
442 return SOAP_FAULT;
|
mas01mc@354
|
443 }
|
mas01mc@354
|
444 fclose(tmpFile2);
|
mas01mc@354
|
445 }
|
mas01mc@354
|
446
|
mas01mc@354
|
447 // fix up sequenceLength if it isn't provided, we know what the caller wants by the size of the shingle
|
mas01mc@354
|
448 // and the feature dimensionality
|
mas01mc@354
|
449 if(!sequenceLength)
|
mas01mc@354
|
450 sequenceLength = qVector.__sizev/qVector.dim;
|
mas01mc@354
|
451
|
mas01mc@354
|
452 int retVal = adb__query(soap, dbName, tmpFileName, keyList, timesFileName, qVector.__sizep?tmpFileName2:0,
|
mas01mc@354
|
453 queryType, queryPos, pointNN, trackNN, sequenceLength, radius,
|
mas01mc@471
|
454 absolute_threshold, relative_threshold, exhaustive, lsh_exact, no_unit_norming, adbQueryResponse);
|
mas01mc@354
|
455
|
mas01mc@354
|
456 return retVal;
|
mas01mc@354
|
457 }
|
mas01mc@354
|
458
|
mas01cr@239
|
459 /* Server loop */
|
mas01cr@239
|
460 void audioDB::startServer(){
|
mas01cr@239
|
461 struct soap soap;
|
mas01cr@239
|
462 int m, s; // master and slave sockets
|
mas01cr@239
|
463 soap_init(&soap);
|
mas01cr@239
|
464 // FIXME: largely this use of SO_REUSEADDR is to make writing (and
|
mas01cr@239
|
465 // running) test cases more convenient, so that multiple test runs
|
mas01cr@239
|
466 // in close succession don't fail because of a bin() error.
|
mas01cr@239
|
467 // Investigate whether there are any potential drawbacks in this,
|
mas01cr@239
|
468 // and also whether there's a better way to write the tests. --
|
mas01cr@239
|
469 // CSR, 2007-10-03
|
mas01cr@239
|
470 soap.bind_flags |= SO_REUSEADDR;
|
mas01cr@239
|
471 m = soap_bind(&soap, NULL, port, 100);
|
mas01cr@239
|
472 if (m < 0)
|
mas01cr@239
|
473 soap_print_fault(&soap, stderr);
|
mas01cr@239
|
474 else
|
mas01cr@239
|
475 {
|
mas01cr@239
|
476 fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
|
mas01cr@498
|
477 /* FIXME: we used to have a global cache of a single LSH index
|
mas01cr@498
|
478 * here. CSR removed it because it interacted badly with
|
mas01cr@498
|
479 * APIification of querying, replacing it with a per-open-adb
|
mas01cr@498
|
480 * cache; we should try to take advantage of that instead.
|
mas01cr@498
|
481 */
|
mas01cr@498
|
482
|
mas01mc@324
|
483 // Server-side path prefix to databases and features
|
mas01mc@324
|
484 if(adb_root)
|
mas01mc@324
|
485 SERVER_ADB_ROOT = (char*)adb_root; // Server-side database root
|
mas01mc@324
|
486 if(adb_feature_root)
|
mas01mc@324
|
487 SERVER_ADB_FEATURE_ROOT = (char*)adb_feature_root; // Server-side features root
|
mas01mc@338
|
488
|
mas01mc@338
|
489 isServer = 1; // From this point, errors are reported via SOAP to the client
|
mas01cr@239
|
490 for (int i = 1; ; i++)
|
mas01cr@239
|
491 {
|
mas01cr@239
|
492 s = soap_accept(&soap);
|
mas01cr@239
|
493 if (s < 0)
|
mas01cr@239
|
494 {
|
mas01cr@239
|
495 soap_print_fault(&soap, stderr);
|
mas01cr@239
|
496 break;
|
mas01cr@239
|
497 }
|
mas01cr@239
|
498 /* FIXME: find a way to play nice with logging when run from
|
mas01cr@239
|
499 /etc/init.d scripts: at present this just goes nowhere */
|
mas01cr@239
|
500 fprintf(stderr, "%d: accepted connection from IP=%lu.%lu.%lu.%lu socket=%d\n", i,
|
mas01cr@239
|
501 (soap.ip >> 24)&0xFF, (soap.ip >> 16)&0xFF, (soap.ip >> 8)&0xFF, soap.ip&0xFF, s);
|
mas01cr@239
|
502 if (soap_serve(&soap) != SOAP_OK) // process RPC request
|
mas01cr@239
|
503 soap_print_fault(&soap, stderr); // print error
|
mas01cr@239
|
504 fprintf(stderr, "request served\n");
|
mas01cr@239
|
505 soap_destroy(&soap); // clean up class instances
|
mas01cr@239
|
506 soap_end(&soap); // clean up everything and close socket
|
mas01cr@239
|
507 }
|
mas01cr@239
|
508 }
|
mas01cr@239
|
509 soap_done(&soap); // close master socket and detach environment
|
mas01cr@239
|
510 }
|