annotate audioDB.cpp @ 411:ad2206c24986 api-inversion

Fix a memory corruption bug. When allocating the adb_t in audiodb_open(), zero the memory; then we're not going to try to free() or delete some arbitrary uninitialized thing if the thing that we're opening turns out not to be an audiodb database.
author mas01cr
date Thu, 11 Dec 2008 08:54:06 +0000
parents 99e6cbad7f76
children a7d61291fbda
rev   line source
mas01cr@0 1 #include "audioDB.h"
mas01cr@385 2 extern "C" {
mas01cr@385 3 #include "audioDB_API.h"
mas01cr@402 4 #include "audioDB-internals.h"
mas01cr@385 5 }
mas01cr@0 6
mas01mc@308 7 LSH* SERVER_LSH_INDEX_SINGLETON;
mas01mc@324 8 char* SERVER_ADB_ROOT;
mas01mc@324 9 char* SERVER_ADB_FEATURE_ROOT;
mas01mc@308 10
mas01mc@292 11 PointPair::PointPair(Uns32T a, Uns32T b, Uns32T c):trackID(a),qpos(b),spos(c){};
mas01mc@292 12
mas01mc@292 13 bool operator<(const PointPair& a, const PointPair& b){
mas01mc@324 14 return ( (a.trackID<b.trackID) ||
mas01mc@324 15 ( (a.trackID==b.trackID) &&
mas01mc@324 16 ( (a.spos<b.spos) || ( (a.spos==b.spos) && (a.qpos < b.qpos) )) ) );
mas01mc@292 17 }
mas01mc@292 18
mas01mc@292 19 bool operator>(const PointPair& a, const PointPair& b){
mas01mc@324 20 return ( (a.trackID>b.trackID) ||
mas01mc@324 21 ( (a.trackID==b.trackID) &&
mas01mc@324 22 ( (a.spos>b.spos) || ( (a.spos==b.spos) && (a.qpos > b.qpos) )) ) );
mas01mc@292 23 }
mas01mc@292 24
mas01mc@292 25 bool operator==(const PointPair& a, const PointPair& b){
mas01mc@292 26 return ( (a.trackID==b.trackID) && (a.qpos==b.qpos) && (a.spos==b.spos) );
mas01mc@292 27 }
mas01mc@292 28
mas01cr@370 29 audioDB::audioDB(const unsigned argc, const char *argv[]): O2_AUDIODB_INITIALIZERS
mas01cr@76 30 {
mas01cr@0 31 if(processArgs(argc, argv)<0){
mas01cr@0 32 printf("No command found.\n");
mas01cr@0 33 cmdline_parser_print_version ();
mas01cr@0 34 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 35 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 36 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 37 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 38 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 39 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@151 40 error("No command found");
mas01cr@0 41 }
mas01cr@77 42
mas01mc@324 43 // Perform database prefix substitution
mas01mc@328 44 if(dbName && adb_root)
mas01mc@324 45 prefix_name((char** const)&dbName, adb_root);
mas01mc@324 46
mas01cr@0 47 if(O2_ACTION(COM_SERVER))
mas01cr@371 48 #ifdef LIBRARY
mas01cr@371 49 ;
mas01cr@371 50 #else
mas01cr@0 51 startServer();
mas01cr@371 52 #endif
mas01cr@0 53
mas01cr@0 54 else if(O2_ACTION(COM_CREATE))
mas01cr@0 55 create(dbName);
mas01cr@0 56
mas01cr@0 57 else if(O2_ACTION(COM_INSERT))
mas01cr@0 58 insert(dbName, inFile);
mas01cr@0 59
mas01cr@0 60 else if(O2_ACTION(COM_BATCHINSERT))
mas01cr@0 61 batchinsert(dbName, inFile);
mas01cr@0 62
mas01cr@0 63 else if(O2_ACTION(COM_QUERY))
mas01mc@307 64 if(isClient){
mas01cr@371 65 #ifdef LIBRARY
mas01cr@371 66 ;
mas01cr@371 67 #else
mas01mc@329 68 if(query_from_key){
mas01mc@332 69 VERB_LOG(1, "Calling web services query %s on database %s, query=%s\n", radius>0?"(Radius)":"(NN)", dbName, (key&&strlen(key))?key:inFile);
mas01mc@328 70 ws_query_by_key(dbName, key, inFile, (char*)hostport);
mas01mc@329 71 }
mas01mc@329 72 else{
mas01mc@332 73 VERB_LOG(1, "Calling web services query on database %s, query=%s\n", dbName, (key&&strlen(key))?key:inFile);
mas01mc@307 74 ws_query(dbName, inFile, (char*)hostport);
mas01mc@329 75 }
mas01cr@371 76 #endif
mas01mc@307 77 }
mas01cr@0 78 else
mas01cr@76 79 query(dbName, inFile);
mas01cr@0 80
mas01cr@0 81 else if(O2_ACTION(COM_STATUS))
mas01cr@0 82 if(isClient)
mas01cr@371 83 #ifdef LIBRARY
mas01cr@371 84 ;
mas01cr@371 85 #else
mas01cr@0 86 ws_status(dbName,(char*)hostport);
mas01cr@371 87 #endif
mas01cr@0 88 else
mas01cr@0 89 status(dbName);
mas01cr@280 90
mas01cr@280 91 else if(O2_ACTION(COM_SAMPLE))
mas01cr@280 92 sample(dbName);
mas01cr@0 93
mas01cr@0 94 else if(O2_ACTION(COM_L2NORM))
mas01cr@0 95 l2norm(dbName);
mas01cr@0 96
mas01cr@193 97 else if(O2_ACTION(COM_POWER))
mas01cr@193 98 power_flag(dbName);
mas01cr@193 99
mas01cr@0 100 else if(O2_ACTION(COM_DUMP))
mas01cr@0 101 dump(dbName);
mas01mc@292 102
mas01mc@334 103 else if(O2_ACTION(COM_LISZT))
mas01mc@334 104 if(isClient)
mas01cr@371 105 #ifdef LIBRARY
mas01cr@371 106 ;
mas01cr@371 107 #else
mas01mc@334 108 ws_liszt(dbName, (char*) hostport);
mas01cr@371 109 #endif
mas01mc@334 110 else
mas01mc@334 111 liszt(dbName, lisztOffset, lisztLength);
mas01mc@334 112
mas01mc@292 113 else if(O2_ACTION(COM_INDEX))
mas01mc@292 114 index_index_db(dbName);
mas01cr@0 115
mas01cr@0 116 else
mas01cr@0 117 error("Unrecognized command",command);
mas01cr@0 118 }
mas01cr@0 119
mas01cr@370 120 audioDB::audioDB(const unsigned argc, const char *argv[], adb__queryResponse *adbQueryResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 121 {
mas01cr@97 122 try {
mas01mc@338 123 isServer = 1; // Set to make errors report over SOAP
mas01cr@97 124 processArgs(argc, argv);
mas01mc@324 125 // Perform database prefix substitution
mas01mc@328 126 if(dbName && adb_root)
mas01mc@324 127 prefix_name((char** const)&dbName, adb_root);
mas01cr@97 128 assert(O2_ACTION(COM_QUERY));
mas01cr@133 129 query(dbName, inFile, adbQueryResponse);
mas01cr@97 130 } catch(char *err) {
mas01cr@97 131 cleanup();
mas01cr@97 132 throw(err);
mas01cr@97 133 }
mas01cr@76 134 }
mas01cr@76 135
mas01cr@370 136 audioDB::audioDB(const unsigned argc, const char *argv[], adb__statusResponse *adbStatusResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 137 {
mas01cr@97 138 try {
mas01mc@338 139 isServer = 1; // Set to make errors report over SOAP
mas01cr@97 140 processArgs(argc, argv);
mas01mc@324 141 // Perform database prefix substitution
mas01mc@328 142 if(dbName && adb_root)
mas01mc@324 143 prefix_name((char** const)&dbName, adb_root);
mas01cr@97 144 assert(O2_ACTION(COM_STATUS));
mas01cr@133 145 status(dbName, adbStatusResponse);
mas01cr@97 146 } catch(char *err) {
mas01cr@97 147 cleanup();
mas01cr@97 148 throw(err);
mas01cr@97 149 }
mas01cr@76 150 }
mas01cr@76 151
mas01cr@370 152 audioDB::audioDB(const unsigned argc, const char *argv[], adb__lisztResponse *adbLisztResponse): O2_AUDIODB_INITIALIZERS
mas01mc@334 153 {
mas01mc@334 154 try {
mas01mc@338 155 isServer = 1; // Set to make errors report over SOAP
mas01mc@338 156 processArgs(argc, argv);
mas01mc@334 157 // Perform database prefix substitution
mas01mc@334 158 if(dbName && adb_root)
mas01mc@334 159 prefix_name((char** const)&dbName, adb_root);
mas01mc@334 160 assert(O2_ACTION(COM_LISZT));
mas01mc@334 161 liszt(dbName, lisztOffset, lisztLength, adbLisztResponse);
mas01mc@334 162 } catch(char *err) {
mas01mc@334 163 cleanup();
mas01mc@334 164 throw(err);
mas01mc@334 165 }
mas01mc@334 166 }
mas01mc@334 167
mas01cr@395 168 //for API query
mas01cr@395 169 audioDB::audioDB(const unsigned argc, const char *argv[],adb__queryResponse *adbQueryResponse, int * apierror, adb_t *a): O2_AUDIODB_INITIALIZERS
mas01ik@355 170 {
mas01ik@355 171
mas01ik@355 172 try {
mas01ik@355 173 UseApiError=1;
mas01cr@395 174 adb = a;
mas01ik@355 175
mas01ik@355 176 if(processArgs(argc, argv)<0){
mas01ik@355 177 printf("No command found.\n");
mas01ik@355 178 cmdline_parser_print_version ();
mas01ik@355 179 if (strlen(gengetopt_args_info_purpose) > 0)
mas01ik@355 180 printf("%s\n", gengetopt_args_info_purpose);
mas01ik@355 181 printf("%s\n", gengetopt_args_info_usage);
mas01ik@355 182 printf("%s\n", gengetopt_args_info_help[1]);
mas01ik@355 183 printf("%s\n", gengetopt_args_info_help[2]);
mas01ik@355 184 printf("%s\n", gengetopt_args_info_help[0]);
mas01ik@355 185 error("No command found");
mas01ik@355 186 }
mas01ik@355 187
mas01ik@355 188 query(dbName, inFile, adbQueryResponse);
mas01ik@355 189
mas01ik@355 190 } catch(int a) {
mas01ik@355 191 *apierror=a;
mas01ik@355 192 return;
mas01ik@355 193
mas01ik@355 194 }
mas01ik@355 195 *apierror=apierrortemp;
mas01ik@355 196 return;
mas01ik@355 197
mas01ik@355 198 }
mas01ik@355 199
mas01cr@97 200 void audioDB::cleanup() {
mas01cr@122 201 cmdline_parser_free(&args_info);
mas01cr@0 202 if(indata)
mas01cr@0 203 munmap(indata,statbuf.st_size);
mas01cr@0 204 if(db)
mas01cr@196 205 munmap(db,getpagesize());
mas01cr@196 206 if(fileTable)
mas01cr@196 207 munmap(fileTable, fileTableLength);
mas01cr@196 208 if(trackTable)
mas01cr@196 209 munmap(trackTable, trackTableLength);
mas01cr@196 210 if(dataBuf)
mas01cr@196 211 munmap(dataBuf, dataBufLength);
mas01cr@196 212 if(timesTable)
mas01cr@196 213 munmap(timesTable, timesTableLength);
mas01mc@314 214 if(powerTable)
mas01mc@314 215 munmap(powerTable, powerTableLength);
mas01cr@196 216 if(l2normTable)
mas01cr@196 217 munmap(l2normTable, l2normTableLength);
mas01mc@324 218 if(featureFileNameTable)
mas01mc@324 219 munmap(featureFileNameTable, fileTableLength);
mas01mc@324 220 if(timesFileNameTable)
mas01mc@324 221 munmap(timesFileNameTable, fileTableLength);
mas01mc@324 222 if(powerFileNameTable)
mas01mc@324 223 munmap(powerFileNameTable, fileTableLength);
mas01mc@292 224 if(trackOffsetTable)
mas01ik@355 225 delete [] trackOffsetTable;
mas01mc@292 226 if(reporter)
mas01mc@292 227 delete reporter;
mas01mc@292 228 if(exact_evaluation_queue)
mas01mc@292 229 delete exact_evaluation_queue;
mas01cr@284 230 if(rng)
mas01cr@284 231 gsl_rng_free(rng);
mas01mc@292 232 if(vv)
mas01mc@292 233 delete vv;
mas01cr@0 234 if(infid>0)
mas01cr@0 235 close(infid);
mas01cr@395 236 if(adb && !UseApiError) {
mas01cr@392 237 audiodb_close(adb);
mas01cr@392 238 adb = NULL;
mas01cr@392 239 }
mas01mc@308 240 if(lsh!=SERVER_LSH_INDEX_SINGLETON)
mas01mc@308 241 delete lsh;
mas01cr@0 242 }
mas01cr@0 243
mas01cr@97 244 audioDB::~audioDB(){
mas01cr@97 245 cleanup();
mas01cr@97 246 }
mas01cr@97 247
mas01cr@370 248 int audioDB::processArgs(const unsigned argc, const char *argv[]){
mas01cr@0 249
mas01cr@0 250 if(argc<2){
mas01cr@0 251 cmdline_parser_print_version ();
mas01cr@0 252 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 253 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 254 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 255 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 256 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 257 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@0 258 exit(0);
mas01cr@0 259 }
mas01cr@0 260
mas01cr@345 261 /* KLUDGE: gengetopt generates a function which is not completely
mas01cr@345 262 const-clean in its declaration. We cast argv here to keep the
mas01cr@345 263 compiler happy. -- CSR, 2008-10-08 */
mas01cr@345 264 if (cmdline_parser (argc, (char *const *) argv, &args_info) != 0)
mas01cr@151 265 error("Error parsing command line");
mas01cr@0 266
mas01cr@0 267 if(args_info.help_given){
mas01cr@0 268 cmdline_parser_print_help();
mas01cr@0 269 exit(0);
mas01cr@0 270 }
mas01cr@0 271
mas01cr@0 272 if(args_info.verbosity_given){
mas01cr@239 273 verbosity = args_info.verbosity_arg;
mas01cr@239 274 if(verbosity < 0 || verbosity > 10){
mas01cr@239 275 std::cerr << "Warning: verbosity out of range, setting to 1" << std::endl;
mas01cr@239 276 verbosity = 1;
mas01cr@0 277 }
mas01cr@0 278 }
mas01cr@0 279
mas01cr@129 280 if(args_info.size_given) {
mas01cr@256 281 if(args_info.datasize_given) {
mas01cr@256 282 error("both --size and --datasize given", "");
mas01cr@256 283 }
mas01cr@256 284 if(args_info.ntracks_given) {
mas01cr@256 285 error("both --size and --ntracks given", "");
mas01cr@256 286 }
mas01cr@256 287 if(args_info.datadim_given) {
mas01cr@256 288 error("both --size and --datadim given", "");
mas01cr@256 289 }
mas01cr@196 290 if (args_info.size_arg < 50 || args_info.size_arg > 32000) {
mas01cr@129 291 error("Size out of range", "");
mas01cr@129 292 }
mas01cr@256 293 double ratio = (double) args_info.size_arg * 1000000 / ((double) O2_DEFAULTDBSIZE);
mas01cr@256 294 /* FIXME: what's the safe way of doing this? */
mas01cr@256 295 datasize = (unsigned int) ceil(datasize * ratio);
mas01cr@256 296 ntracks = (unsigned int) ceil(ntracks * ratio);
mas01cr@256 297 } else {
mas01cr@256 298 if(args_info.datasize_given) {
mas01cr@256 299 datasize = args_info.datasize_arg;
mas01cr@256 300 }
mas01cr@256 301 if(args_info.ntracks_given) {
mas01cr@256 302 ntracks = args_info.ntracks_arg;
mas01cr@256 303 }
mas01cr@256 304 if(args_info.datadim_given) {
mas01cr@256 305 datadim = args_info.datadim_arg;
mas01cr@256 306 }
mas01cr@129 307 }
mas01cr@129 308
mas01cr@239 309 if(args_info.radius_given) {
mas01cr@239 310 radius = args_info.radius_arg;
mas01mc@307 311 if(radius < 0 || radius > 1000000000) {
mas01cr@77 312 error("radius out of range");
mas01cr@239 313 } else {
mas01cr@239 314 VERB_LOG(3, "Setting radius to %f\n", radius);
mas01mc@17 315 }
mas01mc@17 316 }
mas01mc@17 317
mas01mc@292 318 sequenceLength = args_info.sequencelength_arg;
mas01mc@292 319 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01mc@292 320 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01mc@292 321 }
mas01mc@292 322 sequenceHop = args_info.sequencehop_arg;
mas01mc@292 323 if(sequenceHop < 1 || sequenceHop > 1000) {
mas01mc@292 324 error("seqhop out of range: 1 <= seqhop <= 1000");
mas01mc@292 325 }
mas01mc@292 326
mas01mc@292 327 if (args_info.absolute_threshold_given) {
mas01mc@292 328 if (args_info.absolute_threshold_arg >= 0) {
mas01mc@292 329 error("absolute threshold out of range: should be negative");
mas01mc@292 330 }
mas01mc@292 331 use_absolute_threshold = true;
mas01mc@292 332 absolute_threshold = args_info.absolute_threshold_arg;
mas01mc@292 333 }
mas01mc@292 334 if (args_info.relative_threshold_given) {
mas01mc@292 335 use_relative_threshold = true;
mas01mc@292 336 relative_threshold = args_info.relative_threshold_arg;
mas01mc@292 337 }
mas01mc@292 338
mas01mc@324 339 if (args_info.adb_root_given){
mas01mc@324 340 adb_root = args_info.adb_root_arg;
mas01mc@324 341 }
mas01mc@324 342
mas01mc@324 343 if (args_info.adb_feature_root_given){
mas01mc@324 344 adb_feature_root = args_info.adb_feature_root_arg;
mas01mc@324 345 }
mas01mc@324 346
mas01mc@324 347 // perform dbName path prefix SERVER-side subsitution
mas01mc@324 348 if(SERVER_ADB_ROOT && !adb_root)
mas01mc@324 349 adb_root = SERVER_ADB_ROOT;
mas01mc@324 350 if(SERVER_ADB_FEATURE_ROOT && !adb_feature_root)
mas01mc@324 351 adb_feature_root = SERVER_ADB_FEATURE_ROOT;
mas01mc@339 352
mas01cr@0 353 if(args_info.SERVER_given){
mas01cr@0 354 command=COM_SERVER;
mas01cr@0 355 port=args_info.SERVER_arg;
mas01cr@0 356 if(port<100 || port > 100000)
mas01cr@0 357 error("port out of range");
mas01cr@105 358 #if defined(O2_DEBUG)
mas01cr@104 359 struct sigaction sa;
mas01cr@104 360 sa.sa_sigaction = sigterm_action;
mas01cr@104 361 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 362 sigaction(SIGTERM, &sa, NULL);
mas01cr@104 363 sa.sa_sigaction = sighup_action;
mas01cr@104 364 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 365 sigaction(SIGHUP, &sa, NULL);
mas01cr@105 366 #endif
mas01mc@308 367 if(args_info.load_index_given){
mas01mc@308 368 if(!args_info.database_given)
mas01mc@308 369 error("load_index requires a --database argument");
mas01mc@308 370 else
mas01mc@308 371 dbName=args_info.database_arg;
mas01mc@308 372 if(!args_info.radius_given)
mas01mc@308 373 error("load_index requires a --radius argument");
mas01mc@308 374 if(!args_info.sequencelength_given)
mas01mc@308 375 error("load_index requires a --sequenceLength argument");
mas01mc@308 376 WS_load_index = true;
mas01mc@308 377 }
mas01cr@0 378 return 0;
mas01cr@0 379 }
mas01cr@0 380
mas01cr@0 381 // No return on client command, find database command
mas01cr@105 382 if(args_info.client_given){
mas01cr@105 383 command=COM_CLIENT;
mas01cr@105 384 hostport=args_info.client_arg;
mas01cr@105 385 isClient=1;
mas01cr@105 386 }
mas01cr@0 387
mas01cr@105 388 if(args_info.NEW_given){
mas01cr@105 389 command=COM_CREATE;
mas01cr@105 390 dbName=args_info.database_arg;
mas01cr@105 391 return 0;
mas01cr@105 392 }
mas01cr@0 393
mas01cr@105 394 if(args_info.STATUS_given){
mas01cr@105 395 command=COM_STATUS;
mas01cr@105 396 dbName=args_info.database_arg;
mas01cr@105 397 return 0;
mas01cr@105 398 }
mas01cr@0 399
mas01cr@280 400 if(args_info.SAMPLE_given) {
mas01cr@280 401 command = COM_SAMPLE;
mas01cr@280 402 dbName = args_info.database_arg;
mas01cr@280 403 sequenceLength = args_info.sequencelength_arg;
mas01cr@280 404 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01cr@280 405 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01cr@280 406 }
mas01cr@280 407 nsamples = args_info.nsamples_arg;
mas01cr@280 408 return 0;
mas01cr@280 409 }
mas01cr@280 410
mas01cr@105 411 if(args_info.DUMP_given){
mas01cr@105 412 command=COM_DUMP;
mas01cr@105 413 dbName=args_info.database_arg;
mas01cr@131 414 output = args_info.output_arg;
mas01cr@105 415 return 0;
mas01cr@105 416 }
mas01cr@0 417
mas01cr@105 418 if(args_info.L2NORM_given){
mas01cr@105 419 command=COM_L2NORM;
mas01cr@105 420 dbName=args_info.database_arg;
mas01cr@105 421 return 0;
mas01cr@105 422 }
mas01cr@0 423
mas01cr@193 424 if(args_info.POWER_given){
mas01cr@193 425 command=COM_POWER;
mas01cr@193 426 dbName=args_info.database_arg;
mas01cr@193 427 return 0;
mas01cr@193 428 }
mas01cr@193 429
mas01cr@370 430 if(args_info.INSERT_given) {
mas01cr@105 431 command=COM_INSERT;
mas01cr@105 432 dbName=args_info.database_arg;
mas01cr@105 433 inFile=args_info.features_arg;
mas01cr@370 434 if(args_info.key_given) {
mas01cr@370 435 if(!args_info.features_given) {
mas01mc@292 436 error("INSERT: '-k key' argument depends on '-f features'");
mas01cr@370 437 } else {
mas01mc@292 438 key=args_info.key_arg;
mas01cr@370 439 }
mas01cr@370 440 }
mas01cr@370 441 if(args_info.times_given) {
mas01cr@105 442 timesFileName=args_info.times_arg;
mas01cr@370 443 if(strlen(timesFileName)>0) {
mas01cr@370 444 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in))) {
mas01cr@105 445 error("Could not open times file for reading", timesFileName);
mas01cr@370 446 }
mas01cr@105 447 usingTimes=1;
mas01cr@105 448 }
mas01cr@105 449 }
mas01cr@193 450 if (args_info.power_given) {
mas01cr@193 451 powerFileName = args_info.power_arg;
mas01cr@193 452 if (strlen(powerFileName) > 0) {
mas01cr@193 453 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 454 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 455 }
mas01cr@193 456 usingPower = 1;
mas01cr@193 457 }
mas01cr@193 458 }
mas01cr@105 459 return 0;
mas01cr@105 460 }
mas01cr@105 461
mas01cr@370 462 if(args_info.BATCHINSERT_given) {
mas01cr@105 463 command=COM_BATCHINSERT;
mas01cr@105 464 dbName=args_info.database_arg;
mas01cr@105 465 inFile=args_info.featureList_arg;
mas01cr@370 466 if(args_info.keyList_given) {
mas01cr@370 467 if(!args_info.featureList_given) {
mas01tc@300 468 error("BATCHINSERT: '-K keyList' argument depends on '-F featureList'");
mas01cr@370 469 } else {
mas01cr@304 470 key=args_info.keyList_arg; // INCONSISTENT NO CHECK
mas01cr@370 471 }
mas01cr@370 472 }
mas01cr@105 473 /* TO DO: REPLACE WITH
mas01cr@0 474 if(args_info.keyList_given){
mas01mc@18 475 trackFileName=args_info.keyList_arg;
mas01cr@239 476 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01mc@18 477 error("Could not open keyList file for reading",trackFileName);
mas01cr@0 478 }
mas01cr@0 479 AND UPDATE BATCHINSERT()
mas01cr@105 480 */
mas01cr@105 481
mas01cr@370 482 if(args_info.timesList_given) {
mas01cr@105 483 timesFileName=args_info.timesList_arg;
mas01cr@370 484 if(strlen(timesFileName)>0) {
mas01cr@239 485 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 486 error("Could not open timesList file for reading", timesFileName);
mas01cr@105 487 usingTimes=1;
mas01cr@105 488 }
mas01cr@105 489 }
mas01cr@370 490 if(args_info.powerList_given) {
mas01cr@193 491 powerFileName=args_info.powerList_arg;
mas01cr@370 492 if(strlen(powerFileName)>0) {
mas01cr@239 493 if(!(powerFile = new std::ifstream(powerFileName,std::ios::in)))
mas01cr@193 494 error("Could not open powerList file for reading", powerFileName);
mas01cr@193 495 usingPower=1;
mas01cr@193 496 }
mas01cr@193 497 }
mas01cr@105 498 return 0;
mas01cr@105 499 }
mas01mc@292 500
mas01mc@292 501 // Set no_unit_norm flag
mas01mc@292 502 no_unit_norming = args_info.no_unit_norming_flag;
mas01mc@292 503 lsh_use_u_functions = args_info.lsh_use_u_functions_flag;
mas01mc@292 504
mas01mc@292 505 // LSH Index Command
mas01mc@292 506 if(args_info.INDEX_given){
mas01mc@292 507 if(radius <= 0 )
mas01mc@292 508 error("INDEXing requires a Radius argument");
mas01mc@292 509 if(!(sequenceLength>0 && sequenceLength <= O2_MAXSEQLEN))
mas01mc@292 510 error("INDEXing requires 1 <= sequenceLength <= 1000");
mas01mc@292 511 command=COM_INDEX;
mas01mc@337 512 if(!args_info.database_given)
mas01mc@337 513 error("INDEXing requires a database");
mas01mc@292 514 dbName=args_info.database_arg;
mas01mc@292 515
mas01mc@292 516 // Whether to store LSH hash tables for query in core (FORMAT2)
mas01mc@297 517 lsh_in_core = !args_info.lsh_on_disk_flag; // This flag is set to 0 if on_disk requested
mas01mc@292 518
mas01mc@292 519 lsh_param_w = args_info.lsh_w_arg;
mas01mc@292 520 if(!(lsh_param_w>0 && lsh_param_w<=O2_SERIAL_MAX_BINWIDTH))
mas01mc@292 521 error("Indexing parameter w out of range (0.0 < w <= 100.0)");
mas01mc@292 522
mas01mc@292 523 lsh_param_k = args_info.lsh_k_arg;
mas01mc@292 524 if(!(lsh_param_k>0 && lsh_param_k<=O2_SERIAL_MAX_FUNS))
mas01mc@292 525 error("Indexing parameter k out of range (1 <= k <= 100)");
mas01mc@292 526
mas01mc@292 527 lsh_param_m = args_info.lsh_m_arg;
mas01mc@292 528 if(!(lsh_param_m>0 && lsh_param_m<= (1 + (sqrt(1 + O2_SERIAL_MAX_TABLES*8.0)))/2.0))
mas01mc@292 529 error("Indexing parameter m out of range (1 <= m <= 20)");
mas01mc@292 530
mas01mc@292 531 lsh_param_N = args_info.lsh_N_arg;
mas01mc@292 532 if(!(lsh_param_N>0 && lsh_param_N<=O2_SERIAL_MAX_ROWS))
mas01mc@292 533 error("Indexing parameter N out of range (1 <= N <= 1000000)");
mas01mc@292 534
mas01mc@292 535 lsh_param_b = args_info.lsh_b_arg;
mas01mc@292 536 if(!(lsh_param_b>0 && lsh_param_b<=O2_SERIAL_MAX_TRACKBATCH))
mas01mc@292 537 error("Indexing parameter b out of range (1 <= b <= 10000)");
mas01mc@292 538
mas01mc@296 539 lsh_param_ncols = args_info.lsh_ncols_arg;
mas01mc@296 540 if(lsh_in_core) // We don't want to block rows with FORMAT2 indexing
mas01mc@296 541 lsh_param_ncols = O2_SERIAL_MAX_COLS;
mas01mc@292 542 if( !(lsh_param_ncols>0 && lsh_param_ncols<=O2_SERIAL_MAX_COLS))
mas01mc@292 543 error("Indexing parameter ncols out of range (1 <= ncols <= 1000");
mas01mc@292 544
mas01mc@292 545 return 0;
mas01mc@292 546 }
mas01mc@292 547
mas01cr@105 548 // Query command and arguments
mas01cr@105 549 if(args_info.QUERY_given){
mas01cr@105 550 command=COM_QUERY;
mas01cr@105 551 dbName=args_info.database_arg;
mas01mc@292 552 // XOR features and key search
mas01cr@370 553 if((!args_info.features_given && !args_info.key_given) || (args_info.features_given && args_info.key_given))
mas01mc@292 554 error("QUERY requires exactly one of either -f features or -k key");
mas01mc@292 555 if(args_info.features_given)
mas01mc@292 556 inFile=args_info.features_arg; // query from file
mas01mc@292 557 else{
mas01mc@292 558 query_from_key = true;
mas01mc@292 559 key=args_info.key_arg; // query from key
mas01mc@292 560 }
mas01mc@292 561
mas01cr@105 562 if(args_info.keyList_given){
mas01cr@105 563 trackFileName=args_info.keyList_arg;
mas01cr@239 564 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01cr@105 565 error("Could not open keyList file for reading",trackFileName);
mas01cr@105 566 }
mas01cr@105 567
mas01cr@105 568 if(args_info.times_given){
mas01cr@105 569 timesFileName=args_info.times_arg;
mas01cr@105 570 if(strlen(timesFileName)>0){
mas01cr@239 571 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 572 error("Could not open times file for reading", timesFileName);
mas01cr@105 573 usingTimes=1;
mas01cr@105 574 }
mas01cr@105 575 }
mas01cr@193 576
mas01cr@193 577 if(args_info.power_given){
mas01cr@193 578 powerFileName=args_info.power_arg;
mas01cr@193 579 if(strlen(powerFileName)>0){
mas01cr@193 580 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 581 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 582 }
mas01cr@193 583 usingPower = 1;
mas01cr@193 584 }
mas01cr@193 585 }
mas01cr@105 586
mas01cr@105 587 // query type
mas01cr@105 588 if(strncmp(args_info.QUERY_arg, "track", MAXSTR)==0)
mas01cr@105 589 queryType=O2_TRACK_QUERY;
mas01cr@105 590 else if(strncmp(args_info.QUERY_arg, "point", MAXSTR)==0)
mas01cr@105 591 queryType=O2_POINT_QUERY;
mas01cr@105 592 else if(strncmp(args_info.QUERY_arg, "sequence", MAXSTR)==0)
mas01cr@105 593 queryType=O2_SEQUENCE_QUERY;
mas01mc@248 594 else if(strncmp(args_info.QUERY_arg, "nsequence", MAXSTR)==0)
mas01mc@248 595 queryType=O2_N_SEQUENCE_QUERY;
mas01mc@263 596 else if(strncmp(args_info.QUERY_arg, "onetoonensequence", MAXSTR)==0)
mas01mc@263 597 queryType=O2_ONE_TO_ONE_N_SEQUENCE_QUERY;
mas01cr@105 598 else
mas01cr@105 599 error("unsupported query type",args_info.QUERY_arg);
mas01cr@105 600
mas01cr@105 601 if(!args_info.exhaustive_flag){
mas01cr@105 602 queryPoint = args_info.qpoint_arg;
mas01cr@105 603 usingQueryPoint=1;
mas01cr@105 604 if(queryPoint<0 || queryPoint >10000)
mas01cr@105 605 error("queryPoint out of range: 0 <= queryPoint <= 10000");
mas01cr@105 606 }
mas01mc@292 607
mas01mc@296 608 // Whether to pre-load LSH hash tables for query (default on, if flag set then off)
mas01mc@297 609 lsh_in_core = !args_info.lsh_on_disk_flag;
mas01mc@292 610
mas01mc@292 611 // Whether to perform exact evaluation of points returned by LSH
mas01mc@292 612 lsh_exact = args_info.lsh_exact_flag;
mas01mc@292 613
mas01cr@105 614 pointNN = args_info.pointnn_arg;
mas01mc@263 615 if(pointNN < 1 || pointNN > O2_MAXNN) {
mas01mc@263 616 error("pointNN out of range: 1 <= pointNN <= 1000000");
mas01cr@105 617 }
mas01cr@105 618 trackNN = args_info.resultlength_arg;
mas01mc@263 619 if(trackNN < 1 || trackNN > O2_MAXNN) {
mas01mc@263 620 error("resultlength out of range: 1 <= resultlength <= 1000000");
mas01cr@105 621 }
mas01cr@105 622 return 0;
mas01cr@105 623 }
mas01mc@334 624
mas01mc@334 625 if(args_info.LISZT_given){
mas01mc@334 626 command = COM_LISZT;
mas01mc@334 627 dbName=args_info.database_arg;
mas01mc@334 628 lisztOffset = args_info.lisztOffset_arg;
mas01mc@334 629 lisztLength = args_info.lisztLength_arg;
mas01mc@334 630 if(args_info.lisztOffset_arg<0) // check upper bound later when database is opened
mas01mc@334 631 error("lisztOffset cannot be negative");
mas01mc@334 632 if(args_info.lisztLength_arg<0)
mas01mc@334 633 error("lisztLength cannot be negative");
mas01mc@334 634 if(lisztLength >1000000)
mas01mc@334 635 error("lisztLength too large (>1000000)");
mas01mc@334 636 return 0;
mas01mc@334 637 }
mas01mc@334 638
mas01cr@105 639 return -1; // no command found
mas01cr@0 640 }
mas01cr@0 641
mas01cr@133 642 void audioDB::status(const char* dbName, adb__statusResponse *adbStatusResponse){
mas01cr@395 643 adb_status_t status;
mas01cr@399 644 if(!adb) {
mas01cr@399 645 if(!(adb = audiodb_open(dbName, O_RDONLY))) {
mas01cr@399 646 error("Failed to open database file", dbName);
mas01cr@399 647 }
mas01cr@0 648 }
mas01cr@395 649 if(audiodb_status(adb, &status)) {
mas01cr@395 650 error("Failed to retrieve database status", dbName);
mas01cr@395 651 }
mas01cr@76 652
mas01cr@133 653 if(adbStatusResponse == 0) {
mas01cr@395 654 std::cout << "num files:" << status.numFiles << std::endl;
mas01cr@395 655 std::cout << "data dim:" << status.dim <<std::endl;
mas01cr@395 656 if(status.dim > 0) {
mas01cr@397 657 size_t bytes_per_vector = sizeof(double) * status.dim;
mas01cr@397 658 off_t nvectors = status.length / bytes_per_vector;
mas01cr@397 659 off_t data_region_vectors = status.data_region_size / bytes_per_vector;
mas01cr@395 660 std::cout << "total vectors:" << nvectors << std::endl;
mas01cr@395 661 std::cout << "vectors available:";
mas01cr@395 662 if(status.flags & O2_FLAG_LARGE_ADB) {
mas01cr@395 663 std::cout << O2_MAX_VECTORS - nvectors << std::endl;
mas01cr@395 664 } else {
mas01cr@395 665 std::cout << data_region_vectors - nvectors << std::endl;
mas01cr@395 666 }
mas01cr@76 667 }
mas01cr@395 668 if(!(status.flags & O2_FLAG_LARGE_ADB)) {
mas01cr@395 669 double used_frac = ((double) status.length) / status.data_region_size;
mas01cr@395 670 std::cout << "total bytes:" << status.length <<
mas01cr@395 671 " (" << (100.0*used_frac) << "%)" << std::endl;
mas01cr@395 672 std::cout << "bytes available:" << status.data_region_size - status.length <<
mas01cr@395 673 " (" << (100.0*(1-used_frac)) << "%)" << std::endl;
mas01mc@324 674 }
mas01cr@395 675 std::cout << "flags:" << " l2norm[" << DISPLAY_FLAG(status.flags&O2_FLAG_L2NORM)
mas01cr@395 676 << "] minmax[" << DISPLAY_FLAG(status.flags&O2_FLAG_MINMAX)
mas01cr@395 677 << "] power[" << DISPLAY_FLAG(status.flags&O2_FLAG_POWER)
mas01cr@395 678 << "] times[" << DISPLAY_FLAG(status.flags&O2_FLAG_TIMES)
mas01cr@395 679 << "] largeADB[" << DISPLAY_FLAG(status.flags&O2_FLAG_LARGE_ADB)
mas01mc@324 680 << "]" << endl;
mas01mc@324 681
mas01cr@395 682 std::cout << "null count: " << status.nullCount << " small sequence count " << status.dudCount-status.nullCount << std::endl;
mas01cr@76 683 } else {
mas01cr@395 684 adbStatusResponse->result.numFiles = status.numFiles;
mas01cr@395 685 adbStatusResponse->result.dim = status.dim;
mas01cr@395 686 adbStatusResponse->result.length = status.length;
mas01cr@395 687 adbStatusResponse->result.dudCount = status.dudCount;
mas01cr@395 688 adbStatusResponse->result.nullCount = status.nullCount;
mas01cr@395 689 adbStatusResponse->result.flags = status.flags;
mas01cr@76 690 }
mas01cr@0 691 }
mas01cr@0 692
mas01cr@196 693 void audioDB::l2norm(const char* dbName) {
mas01cr@401 694 if(!adb) {
mas01cr@401 695 if(!(adb = audiodb_open(dbName, O_RDWR))) {
mas01cr@401 696 error("Failed to open database file", dbName);
mas01cr@401 697 }
mas01cr@0 698 }
mas01cr@401 699 if(audiodb_l2norm(adb)) {
mas01cr@401 700 error("failed to turn on l2norm flag for database", dbName);
mas01cr@401 701 }
mas01cr@0 702 }
mas01cr@193 703
mas01cr@193 704 void audioDB::power_flag(const char *dbName) {
mas01cr@400 705 if(!adb) {
mas01cr@400 706 if(!(adb = audiodb_open(dbName, O_RDWR))) {
mas01cr@400 707 error("Failed to open database file", dbName);
mas01cr@400 708 }
mas01cr@193 709 }
mas01cr@400 710 if(audiodb_power(adb)) {
mas01cr@400 711 error("can't turn on power flag for database", dbName);
mas01cr@400 712 }
mas01cr@193 713 }
mas01cr@193 714
mas01cr@385 715 void audioDB::create(const char *dbName) {
mas01cr@399 716 if(adb) {
mas01cr@399 717 error("Already have an adb in this object", "");
mas01cr@399 718 }
mas01cr@391 719 if(!(adb = audiodb_create(dbName, datasize, ntracks, datadim))) {
mas01cr@392 720 error("Failed to create database file", dbName);
mas01cr@385 721 }
mas01cr@385 722 }
mas01cr@385 723
mas01cr@399 724 void audioDB::dump(const char *dbName) {
mas01cr@399 725 if(!adb) {
mas01cr@399 726 if(!(adb = audiodb_open(dbName, O_RDONLY))) {
mas01cr@399 727 error("Failed to open database file", dbName);
mas01cr@399 728 }
mas01cr@399 729 }
mas01cr@399 730 if(audiodb_dump(adb, output)) {
mas01cr@399 731 error("Failed to dump database to ", output);
mas01cr@399 732 }
mas01cr@399 733 status(dbName);
mas01cr@399 734 }
mas01cr@193 735
mas01cr@409 736 void audioDB::insert(const char* dbName, const char* inFile) {
mas01cr@409 737 if(!adb) {
mas01cr@409 738 if(!(adb = audiodb_open(dbName, O_RDWR))) {
mas01cr@409 739 error("failed to open database", dbName);
mas01cr@409 740 }
mas01cr@409 741 }
mas01cr@409 742
mas01cr@409 743 /* at this point, we have powerfd (an fd), timesFile (a
mas01cr@409 744 * std::ifstream *) and inFile (a char *). Wacky, huh? Ignore
mas01cr@409 745 * the wackiness and just use the names. */
mas01cr@409 746 adb_insert_t insert;
mas01cr@409 747 insert.features = inFile;
mas01cr@409 748 insert.times = timesFileName;
mas01cr@409 749 insert.power = powerFileName;
mas01cr@409 750 insert.key = key;
mas01cr@409 751
mas01cr@409 752 if(audiodb_insert(adb, &insert)) {
mas01cr@409 753 error("insertion failure", inFile);
mas01cr@409 754 }
mas01cr@409 755 status(dbName);
mas01cr@409 756 }
mas01cr@409 757
mas01cr@409 758 void audioDB::batchinsert(const char* dbName, const char* inFile) {
mas01cr@409 759 if(!adb) {
mas01cr@409 760 if(!(adb = audiodb_open(dbName, O_RDWR))) {
mas01cr@409 761 error("failed to open database", dbName);
mas01cr@409 762 }
mas01cr@409 763 }
mas01cr@409 764
mas01cr@409 765 if(!key)
mas01cr@409 766 key=inFile;
mas01cr@409 767 std::ifstream *filesIn = 0;
mas01cr@409 768 std::ifstream *keysIn = 0;
mas01cr@409 769
mas01cr@409 770 if(!(filesIn = new std::ifstream(inFile)))
mas01cr@409 771 error("Could not open batch in file", inFile);
mas01cr@409 772 if(key && key!=inFile)
mas01cr@409 773 if(!(keysIn = new std::ifstream(key)))
mas01cr@409 774 error("Could not open batch key file",key);
mas01cr@409 775
mas01cr@409 776 unsigned totalVectors=0;
mas01cr@409 777 char *thisFile = new char[MAXSTR];
mas01cr@409 778 char *thisKey = 0;
mas01cr@409 779 if (key && (key != inFile)) {
mas01cr@409 780 thisKey = new char[MAXSTR];
mas01cr@409 781 }
mas01cr@409 782 char *thisTimesFileName = new char[MAXSTR];
mas01cr@409 783 char *thisPowerFileName = new char[MAXSTR];
mas01cr@409 784
mas01cr@409 785 do {
mas01cr@409 786 filesIn->getline(thisFile,MAXSTR);
mas01cr@409 787 if(key && key!=inFile) {
mas01cr@409 788 keysIn->getline(thisKey,MAXSTR);
mas01cr@409 789 } else {
mas01cr@409 790 thisKey = thisFile;
mas01cr@409 791 }
mas01cr@409 792 if(usingTimes) {
mas01cr@409 793 timesFile->getline(thisTimesFileName,MAXSTR);
mas01cr@409 794 }
mas01cr@409 795 if(usingPower) {
mas01cr@409 796 powerFile->getline(thisPowerFileName, MAXSTR);
mas01cr@409 797 }
mas01cr@409 798
mas01cr@409 799 if(filesIn->eof()) {
mas01cr@409 800 break;
mas01cr@409 801 }
mas01cr@409 802 if(usingTimes){
mas01cr@409 803 if(timesFile->eof()) {
mas01cr@409 804 error("not enough timestamp files in timesList", timesFileName);
mas01cr@409 805 }
mas01cr@409 806 }
mas01cr@409 807 if (usingPower) {
mas01cr@409 808 if(powerFile->eof()) {
mas01cr@409 809 error("not enough power files in powerList", powerFileName);
mas01cr@409 810 }
mas01cr@409 811 }
mas01cr@409 812 adb_insert_t insert;
mas01cr@409 813 insert.features = thisFile;
mas01cr@409 814 insert.times = usingTimes ? thisTimesFileName : NULL;
mas01cr@409 815 insert.power = usingPower ? thisPowerFileName : NULL;
mas01cr@409 816 insert.key = thisKey;
mas01cr@409 817 if(audiodb_insert(adb, &insert)) {
mas01cr@409 818 error("insertion failure", thisFile);
mas01cr@409 819 }
mas01cr@409 820 } while(!filesIn->eof());
mas01cr@409 821
mas01cr@409 822 VERB_LOG(0, "%s %s %u vectors %ju bytes.\n", COM_BATCHINSERT, dbName, totalVectors, (intmax_t) (totalVectors * dbH->dim * sizeof(double)));
mas01cr@409 823
mas01cr@409 824 delete [] thisPowerFileName;
mas01cr@409 825 if(key && (key != inFile)) {
mas01cr@409 826 delete [] thisKey;
mas01cr@409 827 }
mas01cr@409 828 delete [] thisFile;
mas01cr@409 829 delete [] thisTimesFileName;
mas01cr@409 830
mas01cr@409 831 delete filesIn;
mas01cr@409 832 delete keysIn;
mas01cr@409 833
mas01cr@409 834 // Report status
mas01cr@409 835 status(dbName);
mas01cr@409 836 }
mas01cr@409 837
mas01mc@308 838 // This entry point is visited once per instance
mas01mc@308 839 // so it is a good place to set any global state variables
mas01cr@370 840 int main(const int argc, const char* argv[]){
mas01mc@308 841 SERVER_LSH_INDEX_SINGLETON = 0; // Initialize global variables
mas01mc@324 842 SERVER_ADB_ROOT = 0; // Server-side database root prefix
mas01mc@324 843 SERVER_ADB_FEATURE_ROOT = 0; // Server-side features root prefix
mas01cr@0 844 audioDB(argc, argv);
mas01cr@0 845 }
mas01ik@355 846
mas01ik@355 847
mas01ik@355 848 extern "C" {
mas01ik@355 849
mas01ik@355 850 /* for API questions contact
mas01ik@355 851 * Christophe Rhodes c.rhodes@gold.ac.uk
mas01ik@355 852 * Ian Knopke mas01ik@gold.ac.uk, ian.knopke@gmail.com */
mas01ik@355 853
mas01ik@355 854 int audiodb_query(adb_ptr mydb, adb_query_ptr adbq, adb_queryresult_ptr adbqr){
mas01ik@355 855
mas01cr@370 856 const char *argv[32];
mas01ik@355 857 int argvctr=0;
mas01ik@355 858 char tempstr1[200];
mas01ik@355 859 char tempstr2[200];
mas01ik@355 860 char tempstr3[200];
mas01ik@355 861 int apierror=0;
mas01ik@355 862
mas01ik@355 863 adb__queryResponse adbQueryResponse;
mas01ik@355 864
mas01ik@355 865 /* TODO: may need error checking here */
mas01ik@355 866 /* currently counting on audioDB binary to fail for me */
mas01ik@355 867 argv[argvctr++]="audioDB";
mas01ik@355 868
mas01ik@355 869 if(adbq->querytype){
mas01ik@355 870 argv[argvctr++]="-Q";
mas01ik@355 871 argv[argvctr++]=adbq->querytype;
mas01ik@355 872 }
mas01ik@355 873
mas01cr@388 874 if(mydb->path){
mas01ik@355 875 argv[argvctr++]="-d";
mas01cr@388 876 argv[argvctr++]=mydb->path;
mas01ik@355 877 }
mas01ik@355 878
mas01ik@355 879 if (adbq->feature){
mas01ik@355 880 argv[argvctr++]="-f";
mas01ik@355 881 argv[argvctr++]=adbq->feature;
mas01ik@355 882 }
mas01ik@355 883
mas01ik@355 884 if (adbq->power){
mas01ik@355 885 argv[argvctr++]="-w";
mas01ik@355 886 argv[argvctr++]=adbq->power;
mas01ik@355 887 }
mas01ik@355 888
mas01ik@355 889 if (adbq->qpoint){
mas01ik@355 890 argv[argvctr++]="-p";
mas01ik@355 891 argv[argvctr++]=adbq->qpoint;
mas01ik@355 892 }
mas01ik@355 893 if (adbq->numpoints){
mas01ik@355 894 argv[argvctr++]="-n";
mas01ik@355 895 argv[argvctr++]=adbq->numpoints;
mas01ik@355 896 }
mas01ik@355 897 if (adbq->radius){
mas01ik@355 898 argv[argvctr++]="-R";
mas01ik@355 899 argv[argvctr++]=adbq->radius;
mas01ik@355 900 }
mas01ik@355 901 if(adbq->resultlength){
mas01ik@355 902 argv[argvctr++]="-r";
mas01ik@355 903 argv[argvctr++]=adbq->resultlength;
mas01ik@355 904 }
mas01ik@355 905 if(adbq->sequencelength){
mas01ik@355 906 argv[argvctr++]="-l";
mas01ik@355 907 argv[argvctr++]=adbq->sequencelength;
mas01ik@355 908 }
mas01ik@355 909 if(adbq->sequencehop){
mas01ik@355 910 argv[argvctr++]="-h";
mas01ik@355 911 argv[argvctr++]=adbq->sequencehop;
mas01ik@355 912 }
mas01ik@355 913
mas01ik@355 914 if (adbq->absolute_threshold){
mas01ik@355 915 argv[argvctr++]="--absolute-threshold";
mas01ik@355 916 snprintf(tempstr1,sizeof(tempstr1),"%f",adbq->absolute_threshold);
mas01ik@355 917 argv[argvctr++]=tempstr1;
mas01ik@355 918 }
mas01ik@355 919
mas01ik@355 920 if (adbq->relative_threshold){
mas01ik@355 921 argv[argvctr++]="--relative-threshold";
mas01ik@355 922 snprintf(tempstr2,sizeof(tempstr2),"%f",adbq->relative_threshold);
mas01ik@355 923 argv[argvctr++]=tempstr2;
mas01ik@355 924 }
mas01ik@355 925
mas01ik@355 926 if (adbq->exhaustive){
mas01ik@355 927 argv[argvctr++]="--exhaustive";
mas01ik@355 928 }
mas01ik@355 929
mas01ik@355 930 if (adbq->expandfactor){
mas01ik@355 931 argv[argvctr++]="--expandfactor";
mas01ik@355 932 snprintf(tempstr3,sizeof(tempstr3),"%f",adbq->expandfactor);
mas01ik@355 933 argv[argvctr++]=tempstr3;
mas01ik@355 934 }
mas01ik@355 935
mas01ik@355 936 if (adbq->rotate){
mas01ik@355 937 argv[argvctr++]="--rotate";
mas01ik@355 938 }
mas01ik@355 939
mas01ik@355 940 if (adbq->keylist){
mas01ik@355 941 argv[argvctr++]="-K";
mas01ik@355 942 argv[argvctr++]=adbq->keylist;
mas01ik@355 943 }
mas01cr@382 944 argv[argvctr]='\0';
mas01ik@355 945
mas01ik@355 946 /* debugging */
mas01ik@355 947
mas01cr@395 948 audioDB::audioDB(argvctr,argv, &adbQueryResponse, &apierror,mydb);
mas01ik@355 949
mas01ik@355 950 //copy data over here from adbQueryResponse to adbqr
mas01ik@355 951 adbqr->sizeRlist=adbQueryResponse.result.__sizeRlist;
mas01ik@355 952 adbqr->sizeDist=adbQueryResponse.result.__sizeDist;
mas01ik@355 953 adbqr->sizeQpos=adbQueryResponse.result.__sizeQpos;
mas01ik@355 954 adbqr->sizeSpos=adbQueryResponse.result.__sizeSpos;
mas01ik@355 955 adbqr->Rlist=adbQueryResponse.result.Rlist;
mas01ik@355 956 adbqr->Dist=adbQueryResponse.result.Dist;
mas01ik@355 957 adbqr->Qpos=adbQueryResponse.result.Qpos;
mas01ik@355 958 adbqr->Spos=adbQueryResponse.result.Spos;
mas01ik@355 959
mas01ik@355 960 return apierror;
mas01ik@355 961 }
mas01ik@355 962 }
mas01ik@355 963