annotate audioDB.cpp @ 381:9742ea0ac33d

API const correctness. The char *path arguments to audiodb_open() and audiodb_create() should be const; make it so. Also arrange for the datasize, ntracks and datadim arguments to audiodb_create() to be unsigned to match the fields in the internal audioDB class. Technically this is an ABI change, but since nothing is calling this function with anything other than zero arguments yet (correct me if I'm wrong) no-one should notice. (If you notice, shout)
author mas01cr
date Fri, 21 Nov 2008 14:32:27 +0000
parents cfc55df37ceb
children 8425d05eda33
rev   line source
mas01cr@0 1 #include "audioDB.h"
mas01cr@0 2
mas01mc@308 3 LSH* SERVER_LSH_INDEX_SINGLETON;
mas01mc@324 4 char* SERVER_ADB_ROOT;
mas01mc@324 5 char* SERVER_ADB_FEATURE_ROOT;
mas01mc@308 6
mas01mc@292 7 PointPair::PointPair(Uns32T a, Uns32T b, Uns32T c):trackID(a),qpos(b),spos(c){};
mas01mc@292 8
mas01mc@292 9 bool operator<(const PointPair& a, const PointPair& b){
mas01mc@324 10 return ( (a.trackID<b.trackID) ||
mas01mc@324 11 ( (a.trackID==b.trackID) &&
mas01mc@324 12 ( (a.spos<b.spos) || ( (a.spos==b.spos) && (a.qpos < b.qpos) )) ) );
mas01mc@292 13 }
mas01mc@292 14
mas01mc@292 15 bool operator>(const PointPair& a, const PointPair& b){
mas01mc@324 16 return ( (a.trackID>b.trackID) ||
mas01mc@324 17 ( (a.trackID==b.trackID) &&
mas01mc@324 18 ( (a.spos>b.spos) || ( (a.spos==b.spos) && (a.qpos > b.qpos) )) ) );
mas01mc@292 19 }
mas01mc@292 20
mas01mc@292 21 bool operator==(const PointPair& a, const PointPair& b){
mas01mc@292 22 return ( (a.trackID==b.trackID) && (a.qpos==b.qpos) && (a.spos==b.spos) );
mas01mc@292 23 }
mas01mc@292 24
mas01cr@370 25 audioDB::audioDB(const unsigned argc, const char *argv[]): O2_AUDIODB_INITIALIZERS
mas01cr@76 26 {
mas01cr@0 27 if(processArgs(argc, argv)<0){
mas01cr@0 28 printf("No command found.\n");
mas01cr@0 29 cmdline_parser_print_version ();
mas01cr@0 30 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 31 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 32 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 33 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 34 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 35 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@151 36 error("No command found");
mas01cr@0 37 }
mas01cr@77 38
mas01mc@324 39 // Perform database prefix substitution
mas01mc@328 40 if(dbName && adb_root)
mas01mc@324 41 prefix_name((char** const)&dbName, adb_root);
mas01mc@324 42
mas01cr@0 43 if(O2_ACTION(COM_SERVER))
mas01cr@371 44 #ifdef LIBRARY
mas01cr@371 45 ;
mas01cr@371 46 #else
mas01cr@0 47 startServer();
mas01cr@371 48 #endif
mas01cr@0 49
mas01cr@0 50 else if(O2_ACTION(COM_CREATE))
mas01cr@0 51 create(dbName);
mas01cr@0 52
mas01cr@0 53 else if(O2_ACTION(COM_INSERT))
mas01cr@0 54 insert(dbName, inFile);
mas01cr@0 55
mas01cr@0 56 else if(O2_ACTION(COM_BATCHINSERT))
mas01cr@0 57 batchinsert(dbName, inFile);
mas01cr@0 58
mas01cr@0 59 else if(O2_ACTION(COM_QUERY))
mas01mc@307 60 if(isClient){
mas01cr@371 61 #ifdef LIBRARY
mas01cr@371 62 ;
mas01cr@371 63 #else
mas01mc@329 64 if(query_from_key){
mas01mc@332 65 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 66 ws_query_by_key(dbName, key, inFile, (char*)hostport);
mas01mc@329 67 }
mas01mc@329 68 else{
mas01mc@332 69 VERB_LOG(1, "Calling web services query on database %s, query=%s\n", dbName, (key&&strlen(key))?key:inFile);
mas01mc@307 70 ws_query(dbName, inFile, (char*)hostport);
mas01mc@329 71 }
mas01cr@371 72 #endif
mas01mc@307 73 }
mas01cr@0 74 else
mas01cr@76 75 query(dbName, inFile);
mas01cr@0 76
mas01cr@0 77 else if(O2_ACTION(COM_STATUS))
mas01cr@0 78 if(isClient)
mas01cr@371 79 #ifdef LIBRARY
mas01cr@371 80 ;
mas01cr@371 81 #else
mas01cr@0 82 ws_status(dbName,(char*)hostport);
mas01cr@371 83 #endif
mas01cr@0 84 else
mas01cr@0 85 status(dbName);
mas01cr@280 86
mas01cr@280 87 else if(O2_ACTION(COM_SAMPLE))
mas01cr@280 88 sample(dbName);
mas01cr@0 89
mas01cr@0 90 else if(O2_ACTION(COM_L2NORM))
mas01cr@0 91 l2norm(dbName);
mas01cr@0 92
mas01cr@193 93 else if(O2_ACTION(COM_POWER))
mas01cr@193 94 power_flag(dbName);
mas01cr@193 95
mas01cr@0 96 else if(O2_ACTION(COM_DUMP))
mas01cr@0 97 dump(dbName);
mas01mc@292 98
mas01mc@334 99 else if(O2_ACTION(COM_LISZT))
mas01mc@334 100 if(isClient)
mas01cr@371 101 #ifdef LIBRARY
mas01cr@371 102 ;
mas01cr@371 103 #else
mas01mc@334 104 ws_liszt(dbName, (char*) hostport);
mas01cr@371 105 #endif
mas01mc@334 106 else
mas01mc@334 107 liszt(dbName, lisztOffset, lisztLength);
mas01mc@334 108
mas01mc@292 109 else if(O2_ACTION(COM_INDEX))
mas01mc@292 110 index_index_db(dbName);
mas01cr@0 111
mas01cr@0 112 else
mas01cr@0 113 error("Unrecognized command",command);
mas01cr@0 114 }
mas01cr@0 115
mas01cr@370 116 audioDB::audioDB(const unsigned argc, const char *argv[], adb__queryResponse *adbQueryResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 117 {
mas01cr@97 118 try {
mas01mc@338 119 isServer = 1; // Set to make errors report over SOAP
mas01cr@97 120 processArgs(argc, argv);
mas01mc@324 121 // Perform database prefix substitution
mas01mc@328 122 if(dbName && adb_root)
mas01mc@324 123 prefix_name((char** const)&dbName, adb_root);
mas01cr@97 124 assert(O2_ACTION(COM_QUERY));
mas01cr@133 125 query(dbName, inFile, adbQueryResponse);
mas01cr@97 126 } catch(char *err) {
mas01cr@97 127 cleanup();
mas01cr@97 128 throw(err);
mas01cr@97 129 }
mas01cr@76 130 }
mas01cr@76 131
mas01cr@370 132 audioDB::audioDB(const unsigned argc, const char *argv[], adb__statusResponse *adbStatusResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 133 {
mas01cr@97 134 try {
mas01mc@338 135 isServer = 1; // Set to make errors report over SOAP
mas01cr@97 136 processArgs(argc, argv);
mas01mc@324 137 // Perform database prefix substitution
mas01mc@328 138 if(dbName && adb_root)
mas01mc@324 139 prefix_name((char** const)&dbName, adb_root);
mas01cr@97 140 assert(O2_ACTION(COM_STATUS));
mas01cr@133 141 status(dbName, adbStatusResponse);
mas01cr@97 142 } catch(char *err) {
mas01cr@97 143 cleanup();
mas01cr@97 144 throw(err);
mas01cr@97 145 }
mas01cr@76 146 }
mas01cr@76 147
mas01cr@370 148 audioDB::audioDB(const unsigned argc, const char *argv[], adb__lisztResponse *adbLisztResponse): O2_AUDIODB_INITIALIZERS
mas01mc@334 149 {
mas01mc@334 150 try {
mas01mc@338 151 isServer = 1; // Set to make errors report over SOAP
mas01mc@338 152 processArgs(argc, argv);
mas01mc@334 153 // Perform database prefix substitution
mas01mc@334 154 if(dbName && adb_root)
mas01mc@334 155 prefix_name((char** const)&dbName, adb_root);
mas01mc@334 156 assert(O2_ACTION(COM_LISZT));
mas01mc@334 157 liszt(dbName, lisztOffset, lisztLength, adbLisztResponse);
mas01mc@334 158 } catch(char *err) {
mas01mc@334 159 cleanup();
mas01mc@334 160 throw(err);
mas01mc@334 161 }
mas01mc@334 162 }
mas01mc@334 163
mas01ik@355 164
mas01ik@355 165 //for the lib / API
mas01cr@370 166 audioDB::audioDB(const unsigned argc, const char *argv[], int * apierror): O2_AUDIODB_INITIALIZERS
mas01ik@355 167 {
mas01ik@355 168
mas01ik@355 169 try {
mas01ik@355 170 UseApiError=1;
mas01ik@355 171
mas01ik@355 172 if(processArgs(argc, argv)<0){
mas01ik@355 173 printf("No command found.\n");
mas01ik@355 174 cmdline_parser_print_version ();
mas01ik@355 175 if (strlen(gengetopt_args_info_purpose) > 0)
mas01ik@355 176 printf("%s\n", gengetopt_args_info_purpose);
mas01ik@355 177 printf("%s\n", gengetopt_args_info_usage);
mas01ik@355 178 printf("%s\n", gengetopt_args_info_help[1]);
mas01ik@355 179 printf("%s\n", gengetopt_args_info_help[2]);
mas01ik@355 180 printf("%s\n", gengetopt_args_info_help[0]);
mas01ik@355 181 error("No command found");
mas01ik@355 182 }
mas01ik@355 183
mas01ik@355 184 adb__queryResponse adbq;
mas01ik@355 185
mas01ik@355 186 if(O2_ACTION(COM_CREATE))
mas01ik@355 187 create(dbName);
mas01ik@355 188
mas01ik@355 189 else if(O2_ACTION(COM_INSERT))
mas01ik@355 190 insert(dbName, inFile);
mas01ik@355 191
mas01ik@355 192 else if(O2_ACTION(COM_BATCHINSERT))
mas01ik@355 193 batchinsert(dbName, inFile);
mas01ik@355 194
mas01ik@355 195 else if(O2_ACTION(COM_QUERY))
mas01ik@355 196 if(isClient)
mas01ik@355 197 ;//ws_query(dbName, inFile, (char*)hostport);
mas01ik@355 198 else
mas01ik@355 199 query(dbName, inFile, &adbq);
mas01ik@355 200 //query(dbName, inFile);
mas01ik@355 201
mas01ik@355 202 else if(O2_ACTION(COM_STATUS))
mas01ik@355 203 if(isClient)
mas01ik@355 204 ;//ws_status(dbName,(char*)hostport);
mas01ik@355 205 else
mas01ik@355 206 status(dbName);
mas01ik@355 207
mas01ik@355 208 else if(O2_ACTION(COM_L2NORM))
mas01ik@355 209 l2norm(dbName);
mas01ik@355 210
mas01ik@355 211 else if(O2_ACTION(COM_POWER))
mas01ik@355 212 power_flag(dbName);
mas01ik@355 213
mas01ik@355 214 else if(O2_ACTION(COM_DUMP))
mas01ik@355 215 dump(dbName);
mas01ik@355 216
mas01ik@355 217 else
mas01ik@355 218 error("Unrecognized command",command);
mas01ik@355 219
mas01ik@355 220 } catch(int a) {
mas01ik@355 221 *apierror=a;
mas01ik@355 222 return;
mas01ik@355 223
mas01ik@355 224 }
mas01ik@355 225 *apierror=apierrortemp;
mas01ik@355 226 return;
mas01ik@355 227
mas01ik@355 228 }
mas01ik@355 229
mas01ik@355 230 //for API status
mas01cr@370 231 audioDB::audioDB(const unsigned argc, const char *argv[], cppstatusptr stat, int * apierror): O2_AUDIODB_INITIALIZERS
mas01ik@355 232 {
mas01ik@355 233
mas01ik@355 234 try {
mas01ik@355 235 UseApiError=1;
mas01ik@355 236
mas01ik@355 237
mas01ik@355 238 if(processArgs(argc, argv)<0){
mas01ik@355 239 printf("No command found.\n");
mas01ik@355 240 cmdline_parser_print_version ();
mas01ik@355 241 if (strlen(gengetopt_args_info_purpose) > 0)
mas01ik@355 242 printf("%s\n", gengetopt_args_info_purpose);
mas01ik@355 243 printf("%s\n", gengetopt_args_info_usage);
mas01ik@355 244 printf("%s\n", gengetopt_args_info_help[1]);
mas01ik@355 245 printf("%s\n", gengetopt_args_info_help[2]);
mas01ik@355 246 printf("%s\n", gengetopt_args_info_help[0]);
mas01ik@355 247 error("No command found");
mas01ik@355 248 }
mas01ik@355 249
mas01ik@355 250 status(dbName, stat);
mas01ik@355 251
mas01ik@355 252
mas01ik@355 253 } catch(int a) {
mas01ik@355 254 *apierror=a;
mas01ik@355 255 return;
mas01ik@355 256
mas01ik@355 257 }
mas01ik@355 258 *apierror=apierrortemp;
mas01ik@355 259 return;
mas01ik@355 260
mas01ik@355 261 }
mas01ik@355 262
mas01ik@355 263
mas01ik@355 264 //for API query
mas01cr@370 265 audioDB::audioDB(const unsigned argc, const char *argv[],adb__queryResponse *adbQueryResponse, int * apierror): O2_AUDIODB_INITIALIZERS
mas01ik@355 266 {
mas01ik@355 267
mas01ik@355 268 try {
mas01ik@355 269 UseApiError=1;
mas01ik@355 270
mas01ik@355 271 if(processArgs(argc, argv)<0){
mas01ik@355 272 printf("No command found.\n");
mas01ik@355 273 cmdline_parser_print_version ();
mas01ik@355 274 if (strlen(gengetopt_args_info_purpose) > 0)
mas01ik@355 275 printf("%s\n", gengetopt_args_info_purpose);
mas01ik@355 276 printf("%s\n", gengetopt_args_info_usage);
mas01ik@355 277 printf("%s\n", gengetopt_args_info_help[1]);
mas01ik@355 278 printf("%s\n", gengetopt_args_info_help[2]);
mas01ik@355 279 printf("%s\n", gengetopt_args_info_help[0]);
mas01ik@355 280 error("No command found");
mas01ik@355 281 }
mas01ik@355 282
mas01ik@355 283 query(dbName, inFile, adbQueryResponse);
mas01ik@355 284
mas01ik@355 285 } catch(int a) {
mas01ik@355 286 *apierror=a;
mas01ik@355 287 return;
mas01ik@355 288
mas01ik@355 289 }
mas01ik@355 290 *apierror=apierrortemp;
mas01ik@355 291 return;
mas01ik@355 292
mas01ik@355 293 }
mas01ik@355 294
mas01ik@355 295
mas01ik@355 296
mas01ik@355 297
mas01ik@355 298
mas01cr@97 299 void audioDB::cleanup() {
mas01cr@122 300 cmdline_parser_free(&args_info);
mas01cr@0 301 if(indata)
mas01cr@0 302 munmap(indata,statbuf.st_size);
mas01cr@0 303 if(db)
mas01cr@196 304 munmap(db,getpagesize());
mas01cr@196 305 if(fileTable)
mas01cr@196 306 munmap(fileTable, fileTableLength);
mas01cr@196 307 if(trackTable)
mas01cr@196 308 munmap(trackTable, trackTableLength);
mas01cr@196 309 if(dataBuf)
mas01cr@196 310 munmap(dataBuf, dataBufLength);
mas01cr@196 311 if(timesTable)
mas01cr@196 312 munmap(timesTable, timesTableLength);
mas01mc@314 313 if(powerTable)
mas01mc@314 314 munmap(powerTable, powerTableLength);
mas01cr@196 315 if(l2normTable)
mas01cr@196 316 munmap(l2normTable, l2normTableLength);
mas01mc@324 317 if(featureFileNameTable)
mas01mc@324 318 munmap(featureFileNameTable, fileTableLength);
mas01mc@324 319 if(timesFileNameTable)
mas01mc@324 320 munmap(timesFileNameTable, fileTableLength);
mas01mc@324 321 if(powerFileNameTable)
mas01mc@324 322 munmap(powerFileNameTable, fileTableLength);
mas01mc@292 323 if(trackOffsetTable)
mas01ik@355 324 delete [] trackOffsetTable;
mas01mc@292 325 if(reporter)
mas01mc@292 326 delete reporter;
mas01mc@292 327 if(exact_evaluation_queue)
mas01mc@292 328 delete exact_evaluation_queue;
mas01cr@284 329 if(rng)
mas01cr@284 330 gsl_rng_free(rng);
mas01mc@292 331 if(vv)
mas01mc@292 332 delete vv;
mas01cr@0 333 if(dbfid>0)
mas01cr@0 334 close(dbfid);
mas01cr@0 335 if(infid>0)
mas01cr@0 336 close(infid);
mas01cr@0 337 if(dbH)
mas01cr@0 338 delete dbH;
mas01mc@308 339 if(lsh!=SERVER_LSH_INDEX_SINGLETON)
mas01mc@308 340 delete lsh;
mas01cr@0 341 }
mas01cr@0 342
mas01cr@97 343 audioDB::~audioDB(){
mas01cr@97 344 cleanup();
mas01cr@97 345 }
mas01cr@97 346
mas01cr@370 347 int audioDB::processArgs(const unsigned argc, const char *argv[]){
mas01cr@0 348
mas01cr@0 349 if(argc<2){
mas01cr@0 350 cmdline_parser_print_version ();
mas01cr@0 351 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 352 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 353 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 354 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 355 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 356 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@0 357 exit(0);
mas01cr@0 358 }
mas01cr@0 359
mas01cr@345 360 /* KLUDGE: gengetopt generates a function which is not completely
mas01cr@345 361 const-clean in its declaration. We cast argv here to keep the
mas01cr@345 362 compiler happy. -- CSR, 2008-10-08 */
mas01cr@345 363 if (cmdline_parser (argc, (char *const *) argv, &args_info) != 0)
mas01cr@151 364 error("Error parsing command line");
mas01cr@0 365
mas01cr@0 366 if(args_info.help_given){
mas01cr@0 367 cmdline_parser_print_help();
mas01cr@0 368 exit(0);
mas01cr@0 369 }
mas01cr@0 370
mas01cr@0 371 if(args_info.verbosity_given){
mas01cr@239 372 verbosity = args_info.verbosity_arg;
mas01cr@239 373 if(verbosity < 0 || verbosity > 10){
mas01cr@239 374 std::cerr << "Warning: verbosity out of range, setting to 1" << std::endl;
mas01cr@239 375 verbosity = 1;
mas01cr@0 376 }
mas01cr@0 377 }
mas01cr@0 378
mas01cr@129 379 if(args_info.size_given) {
mas01cr@256 380 if(args_info.datasize_given) {
mas01cr@256 381 error("both --size and --datasize given", "");
mas01cr@256 382 }
mas01cr@256 383 if(args_info.ntracks_given) {
mas01cr@256 384 error("both --size and --ntracks given", "");
mas01cr@256 385 }
mas01cr@256 386 if(args_info.datadim_given) {
mas01cr@256 387 error("both --size and --datadim given", "");
mas01cr@256 388 }
mas01cr@196 389 if (args_info.size_arg < 50 || args_info.size_arg > 32000) {
mas01cr@129 390 error("Size out of range", "");
mas01cr@129 391 }
mas01cr@256 392 double ratio = (double) args_info.size_arg * 1000000 / ((double) O2_DEFAULTDBSIZE);
mas01cr@256 393 /* FIXME: what's the safe way of doing this? */
mas01cr@256 394 datasize = (unsigned int) ceil(datasize * ratio);
mas01cr@256 395 ntracks = (unsigned int) ceil(ntracks * ratio);
mas01cr@256 396 } else {
mas01cr@256 397 if(args_info.datasize_given) {
mas01cr@256 398 datasize = args_info.datasize_arg;
mas01cr@256 399 }
mas01cr@256 400 if(args_info.ntracks_given) {
mas01cr@256 401 ntracks = args_info.ntracks_arg;
mas01cr@256 402 }
mas01cr@256 403 if(args_info.datadim_given) {
mas01cr@256 404 datadim = args_info.datadim_arg;
mas01cr@256 405 }
mas01cr@129 406 }
mas01cr@129 407
mas01cr@239 408 if(args_info.radius_given) {
mas01cr@239 409 radius = args_info.radius_arg;
mas01mc@307 410 if(radius < 0 || radius > 1000000000) {
mas01cr@77 411 error("radius out of range");
mas01cr@239 412 } else {
mas01cr@239 413 VERB_LOG(3, "Setting radius to %f\n", radius);
mas01mc@17 414 }
mas01mc@17 415 }
mas01mc@17 416
mas01mc@292 417 sequenceLength = args_info.sequencelength_arg;
mas01mc@292 418 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01mc@292 419 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01mc@292 420 }
mas01mc@292 421 sequenceHop = args_info.sequencehop_arg;
mas01mc@292 422 if(sequenceHop < 1 || sequenceHop > 1000) {
mas01mc@292 423 error("seqhop out of range: 1 <= seqhop <= 1000");
mas01mc@292 424 }
mas01mc@292 425
mas01mc@292 426 if (args_info.absolute_threshold_given) {
mas01mc@292 427 if (args_info.absolute_threshold_arg >= 0) {
mas01mc@292 428 error("absolute threshold out of range: should be negative");
mas01mc@292 429 }
mas01mc@292 430 use_absolute_threshold = true;
mas01mc@292 431 absolute_threshold = args_info.absolute_threshold_arg;
mas01mc@292 432 }
mas01mc@292 433 if (args_info.relative_threshold_given) {
mas01mc@292 434 use_relative_threshold = true;
mas01mc@292 435 relative_threshold = args_info.relative_threshold_arg;
mas01mc@292 436 }
mas01mc@292 437
mas01mc@324 438 if (args_info.adb_root_given){
mas01mc@324 439 adb_root = args_info.adb_root_arg;
mas01mc@324 440 }
mas01mc@324 441
mas01mc@324 442 if (args_info.adb_feature_root_given){
mas01mc@324 443 adb_feature_root = args_info.adb_feature_root_arg;
mas01mc@324 444 }
mas01mc@324 445
mas01mc@324 446 // perform dbName path prefix SERVER-side subsitution
mas01mc@324 447 if(SERVER_ADB_ROOT && !adb_root)
mas01mc@324 448 adb_root = SERVER_ADB_ROOT;
mas01mc@324 449 if(SERVER_ADB_FEATURE_ROOT && !adb_feature_root)
mas01mc@324 450 adb_feature_root = SERVER_ADB_FEATURE_ROOT;
mas01mc@339 451
mas01cr@0 452 if(args_info.SERVER_given){
mas01cr@0 453 command=COM_SERVER;
mas01cr@0 454 port=args_info.SERVER_arg;
mas01cr@0 455 if(port<100 || port > 100000)
mas01cr@0 456 error("port out of range");
mas01cr@105 457 #if defined(O2_DEBUG)
mas01cr@104 458 struct sigaction sa;
mas01cr@104 459 sa.sa_sigaction = sigterm_action;
mas01cr@104 460 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 461 sigaction(SIGTERM, &sa, NULL);
mas01cr@104 462 sa.sa_sigaction = sighup_action;
mas01cr@104 463 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 464 sigaction(SIGHUP, &sa, NULL);
mas01cr@105 465 #endif
mas01mc@308 466 if(args_info.load_index_given){
mas01mc@308 467 if(!args_info.database_given)
mas01mc@308 468 error("load_index requires a --database argument");
mas01mc@308 469 else
mas01mc@308 470 dbName=args_info.database_arg;
mas01mc@308 471 if(!args_info.radius_given)
mas01mc@308 472 error("load_index requires a --radius argument");
mas01mc@308 473 if(!args_info.sequencelength_given)
mas01mc@308 474 error("load_index requires a --sequenceLength argument");
mas01mc@308 475 WS_load_index = true;
mas01mc@308 476 }
mas01cr@0 477 return 0;
mas01cr@0 478 }
mas01cr@0 479
mas01cr@0 480 // No return on client command, find database command
mas01cr@105 481 if(args_info.client_given){
mas01cr@105 482 command=COM_CLIENT;
mas01cr@105 483 hostport=args_info.client_arg;
mas01cr@105 484 isClient=1;
mas01cr@105 485 }
mas01cr@0 486
mas01cr@105 487 if(args_info.NEW_given){
mas01cr@105 488 command=COM_CREATE;
mas01cr@105 489 dbName=args_info.database_arg;
mas01cr@105 490 return 0;
mas01cr@105 491 }
mas01cr@0 492
mas01cr@105 493 if(args_info.STATUS_given){
mas01cr@105 494 command=COM_STATUS;
mas01cr@105 495 dbName=args_info.database_arg;
mas01cr@105 496 return 0;
mas01cr@105 497 }
mas01cr@0 498
mas01cr@280 499 if(args_info.SAMPLE_given) {
mas01cr@280 500 command = COM_SAMPLE;
mas01cr@280 501 dbName = args_info.database_arg;
mas01cr@280 502 sequenceLength = args_info.sequencelength_arg;
mas01cr@280 503 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01cr@280 504 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01cr@280 505 }
mas01cr@280 506 nsamples = args_info.nsamples_arg;
mas01cr@280 507 return 0;
mas01cr@280 508 }
mas01cr@280 509
mas01cr@105 510 if(args_info.DUMP_given){
mas01cr@105 511 command=COM_DUMP;
mas01cr@105 512 dbName=args_info.database_arg;
mas01cr@131 513 output = args_info.output_arg;
mas01cr@105 514 return 0;
mas01cr@105 515 }
mas01cr@0 516
mas01cr@105 517 if(args_info.L2NORM_given){
mas01cr@105 518 command=COM_L2NORM;
mas01cr@105 519 dbName=args_info.database_arg;
mas01cr@105 520 return 0;
mas01cr@105 521 }
mas01cr@0 522
mas01cr@193 523 if(args_info.POWER_given){
mas01cr@193 524 command=COM_POWER;
mas01cr@193 525 dbName=args_info.database_arg;
mas01cr@193 526 return 0;
mas01cr@193 527 }
mas01cr@193 528
mas01cr@370 529 if(args_info.INSERT_given) {
mas01cr@105 530 command=COM_INSERT;
mas01cr@105 531 dbName=args_info.database_arg;
mas01cr@105 532 inFile=args_info.features_arg;
mas01cr@370 533 if(args_info.key_given) {
mas01cr@370 534 if(!args_info.features_given) {
mas01mc@292 535 error("INSERT: '-k key' argument depends on '-f features'");
mas01cr@370 536 } else {
mas01mc@292 537 key=args_info.key_arg;
mas01cr@370 538 }
mas01cr@370 539 }
mas01cr@370 540 if(args_info.times_given) {
mas01cr@105 541 timesFileName=args_info.times_arg;
mas01cr@370 542 if(strlen(timesFileName)>0) {
mas01cr@370 543 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in))) {
mas01cr@105 544 error("Could not open times file for reading", timesFileName);
mas01cr@370 545 }
mas01cr@105 546 usingTimes=1;
mas01cr@105 547 }
mas01cr@105 548 }
mas01cr@193 549 if (args_info.power_given) {
mas01cr@193 550 powerFileName = args_info.power_arg;
mas01cr@193 551 if (strlen(powerFileName) > 0) {
mas01cr@193 552 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 553 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 554 }
mas01cr@193 555 usingPower = 1;
mas01cr@193 556 }
mas01cr@193 557 }
mas01cr@105 558 return 0;
mas01cr@105 559 }
mas01cr@105 560
mas01cr@370 561 if(args_info.BATCHINSERT_given) {
mas01cr@105 562 command=COM_BATCHINSERT;
mas01cr@105 563 dbName=args_info.database_arg;
mas01cr@105 564 inFile=args_info.featureList_arg;
mas01cr@370 565 if(args_info.keyList_given) {
mas01cr@370 566 if(!args_info.featureList_given) {
mas01tc@300 567 error("BATCHINSERT: '-K keyList' argument depends on '-F featureList'");
mas01cr@370 568 } else {
mas01cr@304 569 key=args_info.keyList_arg; // INCONSISTENT NO CHECK
mas01cr@370 570 }
mas01cr@370 571 }
mas01cr@105 572 /* TO DO: REPLACE WITH
mas01cr@0 573 if(args_info.keyList_given){
mas01mc@18 574 trackFileName=args_info.keyList_arg;
mas01cr@239 575 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01mc@18 576 error("Could not open keyList file for reading",trackFileName);
mas01cr@0 577 }
mas01cr@0 578 AND UPDATE BATCHINSERT()
mas01cr@105 579 */
mas01cr@105 580
mas01cr@370 581 if(args_info.timesList_given) {
mas01cr@105 582 timesFileName=args_info.timesList_arg;
mas01cr@370 583 if(strlen(timesFileName)>0) {
mas01cr@239 584 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 585 error("Could not open timesList file for reading", timesFileName);
mas01cr@105 586 usingTimes=1;
mas01cr@105 587 }
mas01cr@105 588 }
mas01cr@370 589 if(args_info.powerList_given) {
mas01cr@193 590 powerFileName=args_info.powerList_arg;
mas01cr@370 591 if(strlen(powerFileName)>0) {
mas01cr@239 592 if(!(powerFile = new std::ifstream(powerFileName,std::ios::in)))
mas01cr@193 593 error("Could not open powerList file for reading", powerFileName);
mas01cr@193 594 usingPower=1;
mas01cr@193 595 }
mas01cr@193 596 }
mas01cr@105 597 return 0;
mas01cr@105 598 }
mas01mc@292 599
mas01mc@292 600 // Set no_unit_norm flag
mas01mc@292 601 no_unit_norming = args_info.no_unit_norming_flag;
mas01mc@292 602 lsh_use_u_functions = args_info.lsh_use_u_functions_flag;
mas01mc@292 603
mas01mc@292 604 // LSH Index Command
mas01mc@292 605 if(args_info.INDEX_given){
mas01mc@292 606 if(radius <= 0 )
mas01mc@292 607 error("INDEXing requires a Radius argument");
mas01mc@292 608 if(!(sequenceLength>0 && sequenceLength <= O2_MAXSEQLEN))
mas01mc@292 609 error("INDEXing requires 1 <= sequenceLength <= 1000");
mas01mc@292 610 command=COM_INDEX;
mas01mc@337 611 if(!args_info.database_given)
mas01mc@337 612 error("INDEXing requires a database");
mas01mc@292 613 dbName=args_info.database_arg;
mas01mc@292 614
mas01mc@292 615 // Whether to store LSH hash tables for query in core (FORMAT2)
mas01mc@297 616 lsh_in_core = !args_info.lsh_on_disk_flag; // This flag is set to 0 if on_disk requested
mas01mc@292 617
mas01mc@292 618 lsh_param_w = args_info.lsh_w_arg;
mas01mc@292 619 if(!(lsh_param_w>0 && lsh_param_w<=O2_SERIAL_MAX_BINWIDTH))
mas01mc@292 620 error("Indexing parameter w out of range (0.0 < w <= 100.0)");
mas01mc@292 621
mas01mc@292 622 lsh_param_k = args_info.lsh_k_arg;
mas01mc@292 623 if(!(lsh_param_k>0 && lsh_param_k<=O2_SERIAL_MAX_FUNS))
mas01mc@292 624 error("Indexing parameter k out of range (1 <= k <= 100)");
mas01mc@292 625
mas01mc@292 626 lsh_param_m = args_info.lsh_m_arg;
mas01mc@292 627 if(!(lsh_param_m>0 && lsh_param_m<= (1 + (sqrt(1 + O2_SERIAL_MAX_TABLES*8.0)))/2.0))
mas01mc@292 628 error("Indexing parameter m out of range (1 <= m <= 20)");
mas01mc@292 629
mas01mc@292 630 lsh_param_N = args_info.lsh_N_arg;
mas01mc@292 631 if(!(lsh_param_N>0 && lsh_param_N<=O2_SERIAL_MAX_ROWS))
mas01mc@292 632 error("Indexing parameter N out of range (1 <= N <= 1000000)");
mas01mc@292 633
mas01mc@292 634 lsh_param_b = args_info.lsh_b_arg;
mas01mc@292 635 if(!(lsh_param_b>0 && lsh_param_b<=O2_SERIAL_MAX_TRACKBATCH))
mas01mc@292 636 error("Indexing parameter b out of range (1 <= b <= 10000)");
mas01mc@292 637
mas01mc@296 638 lsh_param_ncols = args_info.lsh_ncols_arg;
mas01mc@296 639 if(lsh_in_core) // We don't want to block rows with FORMAT2 indexing
mas01mc@296 640 lsh_param_ncols = O2_SERIAL_MAX_COLS;
mas01mc@292 641 if( !(lsh_param_ncols>0 && lsh_param_ncols<=O2_SERIAL_MAX_COLS))
mas01mc@292 642 error("Indexing parameter ncols out of range (1 <= ncols <= 1000");
mas01mc@292 643
mas01mc@292 644 return 0;
mas01mc@292 645 }
mas01mc@292 646
mas01cr@105 647 // Query command and arguments
mas01cr@105 648 if(args_info.QUERY_given){
mas01cr@105 649 command=COM_QUERY;
mas01cr@105 650 dbName=args_info.database_arg;
mas01mc@292 651 // XOR features and key search
mas01cr@370 652 if((!args_info.features_given && !args_info.key_given) || (args_info.features_given && args_info.key_given))
mas01mc@292 653 error("QUERY requires exactly one of either -f features or -k key");
mas01mc@292 654 if(args_info.features_given)
mas01mc@292 655 inFile=args_info.features_arg; // query from file
mas01mc@292 656 else{
mas01mc@292 657 query_from_key = true;
mas01mc@292 658 key=args_info.key_arg; // query from key
mas01mc@292 659 }
mas01mc@292 660
mas01cr@105 661 if(args_info.keyList_given){
mas01cr@105 662 trackFileName=args_info.keyList_arg;
mas01cr@239 663 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01cr@105 664 error("Could not open keyList file for reading",trackFileName);
mas01cr@105 665 }
mas01cr@105 666
mas01cr@105 667 if(args_info.times_given){
mas01cr@105 668 timesFileName=args_info.times_arg;
mas01cr@105 669 if(strlen(timesFileName)>0){
mas01cr@239 670 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 671 error("Could not open times file for reading", timesFileName);
mas01cr@105 672 usingTimes=1;
mas01cr@105 673 }
mas01cr@105 674 }
mas01cr@193 675
mas01cr@193 676 if(args_info.power_given){
mas01cr@193 677 powerFileName=args_info.power_arg;
mas01cr@193 678 if(strlen(powerFileName)>0){
mas01cr@193 679 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 680 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 681 }
mas01cr@193 682 usingPower = 1;
mas01cr@193 683 }
mas01cr@193 684 }
mas01cr@105 685
mas01cr@105 686 // query type
mas01cr@105 687 if(strncmp(args_info.QUERY_arg, "track", MAXSTR)==0)
mas01cr@105 688 queryType=O2_TRACK_QUERY;
mas01cr@105 689 else if(strncmp(args_info.QUERY_arg, "point", MAXSTR)==0)
mas01cr@105 690 queryType=O2_POINT_QUERY;
mas01cr@105 691 else if(strncmp(args_info.QUERY_arg, "sequence", MAXSTR)==0)
mas01cr@105 692 queryType=O2_SEQUENCE_QUERY;
mas01mc@248 693 else if(strncmp(args_info.QUERY_arg, "nsequence", MAXSTR)==0)
mas01mc@248 694 queryType=O2_N_SEQUENCE_QUERY;
mas01mc@263 695 else if(strncmp(args_info.QUERY_arg, "onetoonensequence", MAXSTR)==0)
mas01mc@263 696 queryType=O2_ONE_TO_ONE_N_SEQUENCE_QUERY;
mas01cr@105 697 else
mas01cr@105 698 error("unsupported query type",args_info.QUERY_arg);
mas01cr@105 699
mas01cr@105 700 if(!args_info.exhaustive_flag){
mas01cr@105 701 queryPoint = args_info.qpoint_arg;
mas01cr@105 702 usingQueryPoint=1;
mas01cr@105 703 if(queryPoint<0 || queryPoint >10000)
mas01cr@105 704 error("queryPoint out of range: 0 <= queryPoint <= 10000");
mas01cr@105 705 }
mas01mc@292 706
mas01mc@296 707 // Whether to pre-load LSH hash tables for query (default on, if flag set then off)
mas01mc@297 708 lsh_in_core = !args_info.lsh_on_disk_flag;
mas01mc@292 709
mas01mc@292 710 // Whether to perform exact evaluation of points returned by LSH
mas01mc@292 711 lsh_exact = args_info.lsh_exact_flag;
mas01mc@292 712
mas01cr@105 713 pointNN = args_info.pointnn_arg;
mas01mc@263 714 if(pointNN < 1 || pointNN > O2_MAXNN) {
mas01mc@263 715 error("pointNN out of range: 1 <= pointNN <= 1000000");
mas01cr@105 716 }
mas01cr@105 717 trackNN = args_info.resultlength_arg;
mas01mc@263 718 if(trackNN < 1 || trackNN > O2_MAXNN) {
mas01mc@263 719 error("resultlength out of range: 1 <= resultlength <= 1000000");
mas01cr@105 720 }
mas01cr@105 721 return 0;
mas01cr@105 722 }
mas01mc@334 723
mas01mc@334 724 if(args_info.LISZT_given){
mas01mc@334 725 command = COM_LISZT;
mas01mc@334 726 dbName=args_info.database_arg;
mas01mc@334 727 lisztOffset = args_info.lisztOffset_arg;
mas01mc@334 728 lisztLength = args_info.lisztLength_arg;
mas01mc@334 729 if(args_info.lisztOffset_arg<0) // check upper bound later when database is opened
mas01mc@334 730 error("lisztOffset cannot be negative");
mas01mc@334 731 if(args_info.lisztLength_arg<0)
mas01mc@334 732 error("lisztLength cannot be negative");
mas01mc@334 733 if(lisztLength >1000000)
mas01mc@334 734 error("lisztLength too large (>1000000)");
mas01mc@334 735 return 0;
mas01mc@334 736 }
mas01mc@334 737
mas01cr@105 738 return -1; // no command found
mas01cr@0 739 }
mas01cr@0 740
mas01cr@133 741 void audioDB::status(const char* dbName, adb__statusResponse *adbStatusResponse){
mas01cr@0 742 if(!dbH)
mas01cr@196 743 initTables(dbName, 0);
mas01cr@0 744
mas01cr@0 745 unsigned dudCount=0;
mas01cr@0 746 unsigned nullCount=0;
mas01cr@0 747 for(unsigned k=0; k<dbH->numFiles; k++){
mas01mc@18 748 if(trackTable[k]<sequenceLength){
mas01cr@0 749 dudCount++;
mas01mc@18 750 if(!trackTable[k])
mas01cr@76 751 nullCount++;
mas01cr@0 752 }
mas01cr@0 753 }
mas01cr@76 754
mas01cr@133 755 if(adbStatusResponse == 0) {
mas01cr@76 756
mas01cr@76 757 // Update Header information
mas01cr@239 758 std::cout << "num files:" << dbH->numFiles << std::endl;
mas01cr@239 759 std::cout << "data dim:" << dbH->dim <<std::endl;
mas01cr@76 760 if(dbH->dim>0){
mas01cr@239 761 std::cout << "total vectors:" << dbH->length/(sizeof(double)*dbH->dim)<<std::endl;
mas01mc@324 762 if(dbH->flags & O2_FLAG_LARGE_ADB)
mas01mc@324 763 std::cout << "vectors available:" << O2_MAX_VECTORS - (dbH->length / (sizeof(double)*dbH->dim)) << std::endl;
mas01mc@324 764 else
mas01mc@324 765 std::cout << "vectors available:" << (dbH->timesTableOffset-(dbH->dataOffset+dbH->length))/(sizeof(double)*dbH->dim) << std::endl;
mas01cr@76 766 }
mas01mc@324 767 if( ! (dbH->flags & O2_FLAG_LARGE_ADB) ){
mas01mc@324 768 std::cout << "total bytes:" << dbH->length << " (" << (100.0*dbH->length)/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
mas01mc@324 769 std::cout << "bytes available:" << dbH->timesTableOffset-(dbH->dataOffset+dbH->length) << " (" <<
mas01mc@324 770 (100.0*(dbH->timesTableOffset-(dbH->dataOffset+dbH->length)))/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
mas01mc@324 771 }
mas01mc@301 772 std::cout << "flags:" << " l2norm[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_L2NORM)
mas01mc@301 773 << "] minmax[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_MINMAX)
mas01mc@301 774 << "] power[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_POWER)
mas01mc@324 775 << "] times[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_TIMES)
mas01mc@324 776 << "] largeADB[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_LARGE_ADB)
mas01mc@324 777 << "]" << endl;
mas01mc@324 778
mas01cr@239 779 std::cout << "null count: " << nullCount << " small sequence count " << dudCount-nullCount << std::endl;
mas01cr@76 780 } else {
mas01cr@133 781 adbStatusResponse->result.numFiles = dbH->numFiles;
mas01cr@133 782 adbStatusResponse->result.dim = dbH->dim;
mas01cr@133 783 adbStatusResponse->result.length = dbH->length;
mas01cr@133 784 adbStatusResponse->result.dudCount = dudCount;
mas01cr@133 785 adbStatusResponse->result.nullCount = nullCount;
mas01cr@133 786 adbStatusResponse->result.flags = dbH->flags;
mas01cr@76 787 }
mas01cr@0 788 }
mas01cr@0 789
mas01ik@355 790 ///used by lib/API
mas01ik@355 791 void audioDB::status(const char* dbName, cppstatusptr status){
mas01ik@355 792 if(!dbH) {
mas01ik@355 793 initTables(dbName, 0);
mas01ik@355 794 }
mas01ik@355 795
mas01ik@355 796 unsigned dudCount=0;
mas01ik@355 797 unsigned nullCount=0;
mas01ik@355 798 for(unsigned k=0; k<dbH->numFiles; k++){
mas01ik@355 799 if(trackTable[k]<sequenceLength){
mas01ik@355 800 dudCount++;
mas01ik@355 801 if(!trackTable[k])
mas01ik@355 802 nullCount++;
mas01ik@355 803 }
mas01ik@355 804 }
mas01ik@355 805
mas01ik@355 806 status->numFiles = dbH->numFiles;
mas01ik@355 807 status->dim = dbH->dim;
mas01ik@355 808 status->length = dbH->length;
mas01ik@355 809 status->dudCount = dudCount;
mas01ik@355 810 status->nullCount = nullCount;
mas01ik@355 811 status->flags = dbH->flags;
mas01ik@355 812
mas01ik@355 813 return;
mas01ik@355 814 }
mas01ik@355 815
mas01ik@355 816
mas01ik@355 817
mas01ik@355 818
mas01cr@196 819 void audioDB::l2norm(const char* dbName) {
mas01cr@196 820 forWrite = true;
mas01cr@196 821 initTables(dbName, 0);
mas01mc@324 822 if( !(dbH->flags & O2_FLAG_LARGE_ADB ) && (dbH->length>0) ){
mas01cr@196 823 /* FIXME: should probably be uint64_t */
mas01cr@0 824 unsigned numVectors = dbH->length/(sizeof(double)*dbH->dim);
mas01cr@196 825 CHECKED_MMAP(double *, dataBuf, dbH->dataOffset, dataBufLength);
mas01cr@0 826 unitNormAndInsertL2(dataBuf, dbH->dim, numVectors, 0); // No append
mas01cr@0 827 }
mas01cr@0 828 // Update database flags
mas01cr@0 829 dbH->flags = dbH->flags|O2_FLAG_L2NORM;
mas01cr@0 830 memcpy (db, dbH, O2_HEADERSIZE);
mas01cr@0 831 }
mas01cr@193 832
mas01cr@193 833 void audioDB::power_flag(const char *dbName) {
mas01cr@196 834 forWrite = true;
mas01mc@324 835 initTables(dbName, 0);
mas01mc@324 836 if( !(dbH->flags & O2_FLAG_LARGE_ADB ) && (dbH->length>0) ){
mas01cr@193 837 error("cannot turn on power storage for non-empty database", dbName);
mas01cr@193 838 }
mas01cr@193 839 dbH->flags |= O2_FLAG_POWER;
mas01cr@193 840 memcpy(db, dbH, O2_HEADERSIZE);
mas01cr@193 841 }
mas01cr@193 842
mas01cr@239 843 // Unit norm block of features
mas01cr@0 844
mas01cr@239 845 /* FIXME: in fact this does not unit norm a block of features, it just
mas01cr@239 846 records the L2 norms somewhere. unitNorm() does in fact unit norm
mas01cr@239 847 a block of features. */
mas01cr@0 848 void audioDB::unitNormAndInsertL2(double* X, unsigned dim, unsigned n, unsigned append=0){
mas01cr@0 849 unsigned d;
mas01cr@59 850 double *p;
mas01cr@0 851 unsigned nn = n;
mas01cr@0 852
mas01cr@0 853 assert(l2normTable);
mas01cr@0 854
mas01mc@324 855 if( !(dbH->flags & O2_FLAG_LARGE_ADB) && !append && (dbH->flags & O2_FLAG_L2NORM) )
mas01cr@0 856 error("Database is already L2 normed", "automatic norm on insert is enabled");
mas01cr@0 857
mas01cr@239 858 VERB_LOG(2, "norming %u vectors...", n);
mas01cr@0 859
mas01cr@0 860 double* l2buf = new double[n];
mas01cr@0 861 double* l2ptr = l2buf;
mas01cr@0 862 assert(l2buf);
mas01cr@0 863 assert(X);
mas01cr@0 864
mas01cr@0 865 while(nn--){
mas01cr@0 866 p=X;
mas01cr@0 867 *l2ptr=0.0;
mas01cr@0 868 d=dim;
mas01cr@0 869 while(d--){
mas01cr@0 870 *l2ptr+=*p**p;
mas01cr@0 871 p++;
mas01cr@0 872 }
mas01mc@17 873 l2ptr++;
mas01mc@17 874 X+=dim;
mas01cr@0 875 }
mas01cr@0 876 unsigned offset;
mas01cr@84 877 if(append) {
mas01cr@84 878 // FIXME: a hack, a very palpable hack: the vectors have already
mas01cr@84 879 // been inserted, and dbH->length has already been updated. We
mas01cr@84 880 // need to subtract off again the number of vectors that we've
mas01cr@84 881 // inserted this time...
mas01cr@84 882 offset=(dbH->length/(dbH->dim*sizeof(double)))-n; // number of vectors
mas01cr@84 883 } else {
mas01cr@0 884 offset=0;
mas01cr@84 885 }
mas01cr@0 886 memcpy(l2normTable+offset, l2buf, n*sizeof(double));
mas01cr@0 887 if(l2buf)
mas01mc@17 888 delete[] l2buf;
mas01cr@239 889 VERB_LOG(2, " done.");
mas01cr@193 890 }
mas01cr@193 891
mas01mc@308 892 // This entry point is visited once per instance
mas01mc@308 893 // so it is a good place to set any global state variables
mas01cr@370 894 int main(const int argc, const char* argv[]){
mas01mc@308 895 SERVER_LSH_INDEX_SINGLETON = 0; // Initialize global variables
mas01mc@324 896 SERVER_ADB_ROOT = 0; // Server-side database root prefix
mas01mc@324 897 SERVER_ADB_FEATURE_ROOT = 0; // Server-side features root prefix
mas01cr@0 898 audioDB(argc, argv);
mas01cr@0 899 }
mas01ik@355 900
mas01ik@355 901
mas01ik@355 902 extern "C" {
mas01ik@355 903
mas01ik@355 904 /* for API questions contact
mas01ik@355 905 * Christophe Rhodes c.rhodes@gold.ac.uk
mas01ik@355 906 * Ian Knopke mas01ik@gold.ac.uk, ian.knopke@gmail.com */
mas01ik@355 907
mas01ik@355 908 #include "audioDB_API.h"
mas01ik@355 909
mas01cr@381 910 adb_ptr audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim) {
mas01cr@370 911 const char *argv[12];
mas01ik@355 912 int argvctr=0;
mas01ik@355 913 char tempstr1[200];
mas01ik@355 914 char tempstr2[200];
mas01ik@355 915 char tempstr3[200];
mas01ik@355 916 int apierror=0;
mas01ik@355 917
mas01ik@355 918
mas01ik@355 919 argv[argvctr++] = "audioDB";
mas01ik@355 920 argv[argvctr++] = "--NEW";
mas01ik@355 921 argv[argvctr++] = "-d";
mas01ik@355 922 argv[argvctr++] = path;
mas01ik@355 923
mas01ik@355 924 if (datasize >0){
mas01ik@355 925 argv[argvctr++]="--datasize";
mas01cr@381 926 snprintf(tempstr1,sizeof(tempstr1),"%u",datasize);
mas01ik@355 927 argv[argvctr++]=tempstr1;
mas01ik@355 928 }
mas01ik@355 929
mas01ik@355 930 if (ntracks >0){
mas01ik@355 931 argv[argvctr++]="--ntracks";
mas01cr@381 932 snprintf(tempstr2,sizeof(tempstr2),"%u",ntracks);
mas01ik@355 933 argv[argvctr++]=tempstr2;
mas01ik@355 934 }
mas01ik@355 935
mas01ik@355 936 if (datadim > 0){
mas01ik@355 937 argv[argvctr++]="--datadim";
mas01cr@381 938 snprintf(tempstr3,sizeof(tempstr3),"%u",datadim);
mas01ik@355 939 argv[argvctr++]=tempstr3;
mas01ik@355 940 }
mas01ik@355 941
mas01ik@355 942 argv[argvctr+1]='\0';
mas01ik@355 943
mas01ik@355 944 audioDB::audioDB(argvctr, argv, &apierror);
mas01ik@355 945
mas01ik@355 946 if (!apierror){
mas01ik@355 947 return audiodb_open(path);
mas01ik@355 948 }
mas01ik@355 949
mas01ik@355 950 /* database exists, so fail and pass NULL */
mas01ik@355 951 return NULL;
mas01ik@355 952 }
mas01ik@355 953
mas01ik@355 954
mas01ik@355 955
mas01ik@355 956 int audiodb_insert(adb_ptr mydb, adb_insert_ptr ins) {
mas01cr@370 957 const char *argv[15];
mas01ik@355 958 int argvctr=0;
mas01ik@355 959 int apierror=0;
mas01ik@355 960
mas01ik@355 961 argv[argvctr++]="audioDB";
mas01ik@355 962 argv[argvctr++]="-I";
mas01ik@355 963 argv[argvctr++]="-d";
mas01ik@355 964 argv[argvctr++]=mydb->dbname;
mas01ik@355 965 argv[argvctr++]="-f";
mas01ik@355 966 argv[argvctr++]=ins->features;
mas01ik@355 967
mas01ik@355 968 if (ins->times){
mas01ik@355 969 argv[argvctr++]="--times";
mas01ik@355 970 argv[argvctr++]=ins->times;
mas01ik@355 971 }
mas01ik@355 972
mas01ik@355 973 if (ins->power){
mas01ik@355 974 argv[argvctr++]="-w";
mas01ik@355 975 argv[argvctr++]=ins->power;
mas01ik@355 976 }
mas01ik@355 977
mas01ik@355 978 if (ins->key){
mas01ik@355 979 argv[argvctr++]="--key";
mas01ik@355 980 argv[argvctr++]=ins->key;
mas01ik@355 981 }
mas01ik@355 982 argv[argvctr+1]='\0';
mas01ik@355 983
mas01ik@355 984 audioDB::audioDB(argvctr,argv,&apierror);
mas01ik@355 985 return apierror;
mas01ik@355 986 }
mas01ik@355 987
mas01ik@355 988
mas01ik@355 989 int audiodb_batchinsert(adb_ptr mydb, adb_insert_ptr ins, unsigned int size) {
mas01ik@355 990
mas01cr@370 991 const char *argv[22];
mas01ik@355 992 int argvctr=0;
mas01ik@355 993 unsigned int i=0;
mas01ik@355 994 char tempfeaturename[]="tempfeatureXXXXXX";
mas01ik@355 995 char temppowername[]="temppowerXXXXXX";
mas01ik@355 996 char tempkeyname[]="tempkeyXXXXXX";
mas01ik@355 997 char temptimesname[]="temptimesXXXXXX";
mas01cr@370 998 int tempfeaturefd = -1;
mas01cr@370 999 int temppowerfd = -1;
mas01cr@370 1000 int tempkeyfd = -1;
mas01cr@370 1001 int temptimesfd = -1;
mas01ik@355 1002
mas01ik@355 1003 int flags[4]={0};
mas01ik@355 1004 int apierror=0;
mas01ik@355 1005
mas01ik@355 1006 /* So the final API should take an array of structs. However, the current
mas01ik@355 1007 * version requires four separate text files. So temporarily, we need to
mas01ik@355 1008 * unpack the struct array, make four separate text files, and then reinsert
mas01ik@355 1009 * them into the command-line call. This should change as soon as possible */
mas01ik@355 1010
mas01ik@355 1011
mas01ik@355 1012 argv[argvctr++]="audioDB";
mas01ik@355 1013 argv[argvctr++]="-B";
mas01ik@355 1014 argv[argvctr++]="-d";
mas01ik@355 1015 argv[argvctr++]=mydb->dbname;
mas01ik@355 1016
mas01ik@355 1017
mas01ik@355 1018 /* assume struct is well formed for all entries */
mas01ik@355 1019 if (ins[0].features){ flags[0]++;} else {
mas01ik@355 1020 /* short circuit the case where there are no features in the structs */
mas01ik@355 1021 return -1;
mas01ik@355 1022 } ;
mas01ik@355 1023 if (ins[0].power){ flags[1]++;};
mas01ik@355 1024 if (ins[0].key){ flags[2]++;};
mas01ik@355 1025 if (ins[0].times){ flags[3]++;};
mas01ik@355 1026
mas01ik@355 1027
mas01ik@355 1028 /* make four temp files */
mas01cr@370 1029 if ((tempfeaturefd = mkstemp(tempfeaturename)) == -1)
mas01cr@370 1030 goto error;
mas01cr@370 1031 if ((temppowerfd = mkstemp(temppowername)) == -1)
mas01cr@370 1032 goto error;
mas01cr@370 1033 if ((tempkeyfd=mkstemp(tempkeyname)) == -1)
mas01cr@370 1034 goto error;
mas01cr@370 1035 if ((temptimesfd=mkstemp(temptimesname)) == -1)
mas01cr@370 1036 goto error;
mas01ik@355 1037
mas01ik@355 1038 /* Ok, so we should have a working set of files to write to */
mas01ik@355 1039 /* I'm going to assume that the same format is kept for all structs in the array */
mas01ik@355 1040 /* That is, each struct should be correctly formed, and contain at least a features file, because I'm just going to pass the terms along to the text files */
mas01cr@370 1041 for (i = 0; i < size; i++) {
mas01cr@370 1042 if (write(tempfeaturefd,ins[i].features,strlen(ins[i].features)) != (ssize_t) strlen(ins[i].features))
mas01cr@370 1043 goto error;
mas01cr@370 1044 if (write(tempfeaturefd,"\n",1) != 1)
mas01cr@370 1045 goto error;
mas01ik@355 1046
mas01cr@370 1047 if (flags[1]) {
mas01cr@370 1048 if (write(temppowerfd,ins[i].power,strlen(ins[i].power)) != (ssize_t) strlen(ins[i].power))
mas01cr@370 1049 goto error;
mas01cr@370 1050 if (write(temppowerfd,"\n",1) != 1)
mas01cr@370 1051 goto error;
mas01cr@370 1052 }
mas01cr@370 1053 if (flags[2]) {
mas01cr@370 1054 if (write(tempkeyfd,ins[i].key,strlen(ins[i].key)) != (ssize_t) strlen(ins[i].key))
mas01cr@370 1055 goto error;
mas01cr@370 1056 if (write(tempkeyfd,"\n",1) != 1)
mas01cr@370 1057 goto error;
mas01cr@370 1058 }
mas01cr@370 1059 if (flags[3]) {
mas01cr@370 1060 if (write(temptimesfd,ins[i].times,strlen(ins[i].times)) != (ssize_t) strlen(ins[i].times))
mas01cr@370 1061 goto error;
mas01cr@370 1062 if (write(temptimesfd,"\n",1) != 1)
mas01cr@370 1063 goto error;
mas01cr@370 1064 }
mas01cr@370 1065 }
mas01ik@355 1066
mas01ik@355 1067 argv[argvctr++]="-F";
mas01ik@355 1068 argv[argvctr++]=tempfeaturename;
mas01ik@355 1069 close(tempfeaturefd);
mas01ik@355 1070 close(temppowerfd);
mas01ik@355 1071 close(tempkeyfd);
mas01ik@355 1072 close(temptimesfd);
mas01ik@355 1073
mas01ik@355 1074 if (flags[1]){
mas01ik@355 1075 argv[argvctr++]="--powerList";
mas01ik@355 1076 argv[argvctr++]=temppowername;
mas01ik@355 1077 }
mas01ik@355 1078
mas01ik@355 1079 if (flags[2]){
mas01ik@355 1080 argv[argvctr++]="--keyList";
mas01ik@355 1081 argv[argvctr++]=tempkeyname;
mas01ik@355 1082 }
mas01ik@355 1083
mas01ik@355 1084 if (flags[3]){
mas01ik@355 1085 argv[argvctr++]="--timesList";
mas01ik@355 1086 argv[argvctr++]=temptimesname;
mas01ik@355 1087 }
mas01ik@355 1088
mas01ik@355 1089 argv[argvctr+1]='\0';
mas01ik@355 1090
mas01ik@355 1091 audioDB::audioDB(argvctr,argv,&apierror);
mas01ik@355 1092
mas01ik@355 1093 remove(tempfeaturename);
mas01ik@355 1094 remove(temppowername);
mas01ik@355 1095 remove(tempkeyname);
mas01ik@355 1096 remove(temptimesname);
mas01ik@355 1097
mas01ik@355 1098
mas01ik@355 1099 return apierror;
mas01cr@370 1100
mas01cr@370 1101 error:
mas01cr@370 1102 if(tempfeaturefd != -1) {
mas01cr@370 1103 close(tempfeaturefd);
mas01cr@370 1104 remove(tempfeaturename);
mas01cr@370 1105 }
mas01cr@370 1106 if(temppowerfd != -1) {
mas01cr@370 1107 close(temppowerfd);
mas01cr@370 1108 remove(temppowername);
mas01cr@370 1109 }
mas01cr@370 1110 if(tempkeyfd != -1) {
mas01cr@370 1111 close(tempkeyfd);
mas01cr@370 1112 remove(tempkeyname);
mas01cr@370 1113 }
mas01cr@370 1114 if(temptimesfd != -1) {
mas01cr@370 1115 close(temptimesfd);
mas01cr@370 1116 remove(temptimesname);
mas01cr@370 1117 }
mas01cr@370 1118 return -1;
mas01ik@355 1119 }
mas01ik@355 1120
mas01ik@355 1121
mas01ik@355 1122 int audiodb_query(adb_ptr mydb, adb_query_ptr adbq, adb_queryresult_ptr adbqr){
mas01ik@355 1123
mas01cr@370 1124 const char *argv[32];
mas01ik@355 1125 int argvctr=0;
mas01ik@355 1126 char tempstr1[200];
mas01ik@355 1127 char tempstr2[200];
mas01ik@355 1128 char tempstr3[200];
mas01ik@355 1129 int apierror=0;
mas01ik@355 1130
mas01ik@355 1131 adb__queryResponse adbQueryResponse;
mas01ik@355 1132
mas01ik@355 1133 /* TODO: may need error checking here */
mas01ik@355 1134 /* currently counting on audioDB binary to fail for me */
mas01ik@355 1135 argv[argvctr++]="audioDB";
mas01ik@355 1136
mas01ik@355 1137 if(adbq->querytype){
mas01ik@355 1138 argv[argvctr++]="-Q";
mas01ik@355 1139 argv[argvctr++]=adbq->querytype;
mas01ik@355 1140 }
mas01ik@355 1141
mas01ik@355 1142 if(mydb->dbname){
mas01ik@355 1143 argv[argvctr++]="-d";
mas01ik@355 1144 argv[argvctr++]=mydb->dbname;
mas01ik@355 1145 }
mas01ik@355 1146
mas01ik@355 1147 if (adbq->feature){
mas01ik@355 1148 argv[argvctr++]="-f";
mas01ik@355 1149 argv[argvctr++]=adbq->feature;
mas01ik@355 1150 }
mas01ik@355 1151
mas01ik@355 1152 if (adbq->power){
mas01ik@355 1153 argv[argvctr++]="-w";
mas01ik@355 1154 argv[argvctr++]=adbq->power;
mas01ik@355 1155 }
mas01ik@355 1156
mas01ik@355 1157 if (adbq->qpoint){
mas01ik@355 1158 argv[argvctr++]="-p";
mas01ik@355 1159 argv[argvctr++]=adbq->qpoint;
mas01ik@355 1160 }
mas01ik@355 1161 if (adbq->numpoints){
mas01ik@355 1162 argv[argvctr++]="-n";
mas01ik@355 1163 argv[argvctr++]=adbq->numpoints;
mas01ik@355 1164 }
mas01ik@355 1165 if (adbq->radius){
mas01ik@355 1166 argv[argvctr++]="-R";
mas01ik@355 1167 argv[argvctr++]=adbq->radius;
mas01ik@355 1168 }
mas01ik@355 1169 if(adbq->resultlength){
mas01ik@355 1170 argv[argvctr++]="-r";
mas01ik@355 1171 argv[argvctr++]=adbq->resultlength;
mas01ik@355 1172 }
mas01ik@355 1173 if(adbq->sequencelength){
mas01ik@355 1174 argv[argvctr++]="-l";
mas01ik@355 1175 argv[argvctr++]=adbq->sequencelength;
mas01ik@355 1176 }
mas01ik@355 1177 if(adbq->sequencehop){
mas01ik@355 1178 argv[argvctr++]="-h";
mas01ik@355 1179 argv[argvctr++]=adbq->sequencehop;
mas01ik@355 1180 }
mas01ik@355 1181
mas01ik@355 1182 if (adbq->absolute_threshold){
mas01ik@355 1183 argv[argvctr++]="--absolute-threshold";
mas01ik@355 1184 snprintf(tempstr1,sizeof(tempstr1),"%f",adbq->absolute_threshold);
mas01ik@355 1185 argv[argvctr++]=tempstr1;
mas01ik@355 1186 }
mas01ik@355 1187
mas01ik@355 1188 if (adbq->relative_threshold){
mas01ik@355 1189 argv[argvctr++]="--relative-threshold";
mas01ik@355 1190 snprintf(tempstr2,sizeof(tempstr2),"%f",adbq->relative_threshold);
mas01ik@355 1191 argv[argvctr++]=tempstr2;
mas01ik@355 1192 }
mas01ik@355 1193
mas01ik@355 1194 if (adbq->exhaustive){
mas01ik@355 1195 argv[argvctr++]="--exhaustive";
mas01ik@355 1196 }
mas01ik@355 1197
mas01ik@355 1198 if (adbq->expandfactor){
mas01ik@355 1199 argv[argvctr++]="--expandfactor";
mas01ik@355 1200 snprintf(tempstr3,sizeof(tempstr3),"%f",adbq->expandfactor);
mas01ik@355 1201 argv[argvctr++]=tempstr3;
mas01ik@355 1202 }
mas01ik@355 1203
mas01ik@355 1204 if (adbq->rotate){
mas01ik@355 1205 argv[argvctr++]="--rotate";
mas01ik@355 1206 }
mas01ik@355 1207
mas01ik@355 1208 if (adbq->keylist){
mas01ik@355 1209 argv[argvctr++]="-K";
mas01ik@355 1210 argv[argvctr++]=adbq->keylist;
mas01ik@355 1211 }
mas01ik@355 1212 argv[argvctr+1]='\0';
mas01ik@355 1213
mas01ik@355 1214 /* debugging */
mas01ik@355 1215
mas01ik@355 1216 audioDB::audioDB(argvctr,argv, &adbQueryResponse, &apierror);
mas01ik@355 1217
mas01ik@355 1218 //copy data over here from adbQueryResponse to adbqr
mas01ik@355 1219 adbqr->sizeRlist=adbQueryResponse.result.__sizeRlist;
mas01ik@355 1220 adbqr->sizeDist=adbQueryResponse.result.__sizeDist;
mas01ik@355 1221 adbqr->sizeQpos=adbQueryResponse.result.__sizeQpos;
mas01ik@355 1222 adbqr->sizeSpos=adbQueryResponse.result.__sizeSpos;
mas01ik@355 1223 adbqr->Rlist=adbQueryResponse.result.Rlist;
mas01ik@355 1224 adbqr->Dist=adbQueryResponse.result.Dist;
mas01ik@355 1225 adbqr->Qpos=adbQueryResponse.result.Qpos;
mas01ik@355 1226 adbqr->Spos=adbQueryResponse.result.Spos;
mas01ik@355 1227
mas01ik@355 1228 return apierror;
mas01ik@355 1229 }
mas01ik@355 1230
mas01ik@355 1231 ///* status command */
mas01ik@355 1232 int audiodb_status(adb_ptr mydb, adb_status_ptr status){
mas01ik@355 1233
mas01ik@355 1234 cppstatus sss;
mas01ik@355 1235 int apierror=0;
mas01ik@355 1236
mas01cr@370 1237 const char *argv[5];
mas01ik@355 1238
mas01ik@355 1239 apierror=0;
mas01ik@355 1240 argv[0]="audioDB";
mas01ik@355 1241 argv[1]="--STATUS";
mas01ik@355 1242 argv[2]="-d";
mas01ik@355 1243 argv[3]=mydb->dbname;
mas01ik@355 1244 argv[4]='\0';
mas01ik@355 1245
mas01ik@355 1246 audioDB::audioDB(4,argv,&sss ,&apierror);
mas01ik@355 1247
mas01ik@355 1248 status->numFiles=sss.numFiles;
mas01ik@355 1249 status->dim=sss.dim;
mas01ik@355 1250 status->length=sss.length;
mas01ik@355 1251 status->dudCount=sss.dudCount;
mas01ik@355 1252 status->nullCount=sss.nullCount;
mas01ik@355 1253 status->flags=sss.flags;
mas01ik@355 1254
mas01ik@355 1255 return apierror;
mas01ik@355 1256 }
mas01ik@355 1257
mas01ik@355 1258 int audiodb_dump(adb_ptr mydb){
mas01ik@355 1259 return audiodb_dump_withdir(mydb,"audioDB.dump");
mas01ik@355 1260 }
mas01ik@355 1261
mas01cr@370 1262 int audiodb_dump_withdir(adb_ptr mydb, const char *outputdir){
mas01ik@355 1263
mas01cr@370 1264 const char *argv[7];
mas01ik@355 1265 int argvctr=0;
mas01ik@355 1266 int apierror=0;
mas01ik@355 1267
mas01ik@355 1268 argv[argvctr++]="audioDB";
mas01ik@355 1269 argv[argvctr++]="--DUMP";
mas01ik@355 1270 argv[argvctr++]="-d";
mas01ik@355 1271 argv[argvctr++]=mydb->dbname;
mas01ik@355 1272 argv[argvctr++]="--output";
mas01ik@355 1273 argv[argvctr++]=(char *)outputdir;
mas01cr@370 1274 argv[argvctr]='\0';
mas01ik@355 1275
mas01ik@355 1276 audioDB::audioDB(6,argv,&apierror);
mas01ik@355 1277
mas01ik@355 1278 return apierror;
mas01ik@355 1279 }
mas01ik@355 1280
mas01ik@355 1281 int audiodb_l2norm(adb_ptr mydb){
mas01ik@355 1282
mas01cr@370 1283 const char *argv[5];
mas01ik@355 1284 int apierror=0;
mas01ik@355 1285
mas01ik@355 1286 argv[0]="audioDB";
mas01ik@355 1287 argv[1]="--L2NORM";
mas01ik@355 1288 argv[2]="-d";
mas01ik@355 1289 argv[3]=mydb->dbname;
mas01ik@355 1290 argv[4]='\0';
mas01ik@355 1291
mas01ik@355 1292 audioDB::audioDB(4,argv,&apierror);
mas01ik@355 1293 return apierror;
mas01ik@355 1294 }
mas01ik@355 1295
mas01ik@355 1296 int audiodb_power(adb_ptr mydb){
mas01ik@355 1297
mas01cr@370 1298 const char *argv[5];
mas01ik@355 1299 int apierror=0;
mas01ik@355 1300
mas01ik@355 1301 argv[0]="audioDB";
mas01ik@355 1302 argv[1]="--POWER";
mas01ik@355 1303 argv[2]="-d";
mas01ik@355 1304 argv[3]=mydb->dbname;
mas01ik@355 1305 argv[4]='\0';
mas01ik@355 1306
mas01ik@355 1307 audioDB::audioDB(4,argv,&apierror);
mas01ik@355 1308 return apierror;
mas01ik@355 1309 }
mas01ik@355 1310
mas01cr@381 1311 adb_ptr audiodb_open(const char *path){
mas01ik@355 1312
mas01ik@355 1313 adb_ptr mydbp;
mas01ik@355 1314 adbstatus mystatus;
mas01ik@355 1315
mas01ik@355 1316 /* if db exists */
mas01ik@355 1317
mas01ik@355 1318 if (open(path, O_EXCL) != -1){
mas01ik@355 1319
mas01ik@355 1320 mydbp=(adb_ptr)malloc(sizeof(adb));
mas01cr@376 1321 mydbp->dbname=(char *)malloc(1+strlen(path));
mas01ik@355 1322
mas01ik@355 1323 strcpy(mydbp->dbname,path);
mas01ik@355 1324
mas01ik@355 1325 audiodb_status(mydbp, &mystatus);
mas01ik@355 1326 mydbp->ntracks=mystatus.numFiles;
mas01ik@355 1327 mydbp->datadim=mystatus.dim;
mas01ik@355 1328
mas01ik@355 1329 return mydbp;
mas01ik@355 1330 }
mas01ik@355 1331
mas01ik@355 1332 return NULL;
mas01ik@355 1333 };
mas01ik@355 1334
mas01ik@355 1335
mas01ik@355 1336
mas01ik@355 1337 void audiodb_close(adb_ptr db){
mas01ik@355 1338
mas01ik@355 1339 free(db->dbname);
mas01ik@355 1340 free(db);
mas01ik@355 1341
mas01ik@355 1342 }
mas01ik@355 1343
mas01ik@355 1344
mas01ik@355 1345 }
mas01ik@355 1346