annotate soap.cpp @ 507:e7fd50483311

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