annotate audioDB.cpp @ 307:d1b8b2dec37e

Added reporters radius search via Web Services. The ordering for radius search is degenerate if usingQueryPoint, because the query point can only be counted once. This behaviour is changed by specifying -n 1 to emulate the trackAveragingReporter ordering behaviour
author mas01mc
date Wed, 06 Aug 2008 21:23:14 +0000
parents 2d6efbe56bb8
children 896679d8cc39
rev   line source
mas01cr@0 1 #include "audioDB.h"
mas01cr@0 2
mas01mc@292 3 PointPair::PointPair(Uns32T a, Uns32T b, Uns32T c):trackID(a),qpos(b),spos(c){};
mas01mc@292 4
mas01mc@292 5 bool operator<(const PointPair& a, const PointPair& b){
mas01mc@292 6 return ( (a.qpos<b.qpos) ||
mas01mc@292 7 ((a.qpos==b.qpos) &&
mas01mc@292 8 ( (a.trackID<b.trackID)) || ((a.trackID==b.trackID)&&(a.spos<b.spos)) ) );
mas01mc@292 9 }
mas01mc@292 10
mas01mc@292 11 bool operator>(const PointPair& a, const PointPair& b){
mas01mc@292 12 return ( (a.qpos>b.qpos) ||
mas01mc@292 13 ((a.qpos==b.qpos) &&
mas01mc@292 14 ( (a.trackID>b.trackID)) || ((a.trackID==b.trackID)&&(a.spos>b.spos)) ) );
mas01mc@292 15 }
mas01mc@292 16
mas01mc@292 17 bool operator==(const PointPair& a, const PointPair& b){
mas01mc@292 18 return ( (a.trackID==b.trackID) && (a.qpos==b.qpos) && (a.spos==b.spos) );
mas01mc@292 19 }
mas01mc@292 20
mas01cr@76 21 audioDB::audioDB(const unsigned argc, char* const argv[]): O2_AUDIODB_INITIALIZERS
mas01cr@76 22 {
mas01cr@0 23 if(processArgs(argc, argv)<0){
mas01cr@0 24 printf("No command found.\n");
mas01cr@0 25 cmdline_parser_print_version ();
mas01cr@0 26 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 27 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 28 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 29 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 30 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 31 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@151 32 error("No command found");
mas01cr@0 33 }
mas01cr@77 34
mas01cr@0 35 if(O2_ACTION(COM_SERVER))
mas01cr@0 36 startServer();
mas01cr@0 37
mas01cr@0 38 else if(O2_ACTION(COM_CREATE))
mas01cr@0 39 create(dbName);
mas01cr@0 40
mas01cr@0 41 else if(O2_ACTION(COM_INSERT))
mas01cr@0 42 insert(dbName, inFile);
mas01cr@0 43
mas01cr@0 44 else if(O2_ACTION(COM_BATCHINSERT))
mas01cr@0 45 batchinsert(dbName, inFile);
mas01cr@0 46
mas01cr@0 47 else if(O2_ACTION(COM_QUERY))
mas01mc@307 48 if(isClient){
mas01mc@307 49 if(query_from_key)
mas01mc@307 50 ws_query_by_key(dbName, key, (char*)hostport);
mas01mc@307 51 else
mas01mc@307 52 ws_query(dbName, inFile, (char*)hostport);
mas01mc@307 53 }
mas01cr@0 54 else
mas01cr@76 55 query(dbName, inFile);
mas01cr@0 56
mas01cr@0 57 else if(O2_ACTION(COM_STATUS))
mas01cr@0 58 if(isClient)
mas01cr@0 59 ws_status(dbName,(char*)hostport);
mas01cr@0 60 else
mas01cr@0 61 status(dbName);
mas01cr@280 62
mas01cr@280 63 else if(O2_ACTION(COM_SAMPLE))
mas01cr@280 64 sample(dbName);
mas01cr@0 65
mas01cr@0 66 else if(O2_ACTION(COM_L2NORM))
mas01cr@0 67 l2norm(dbName);
mas01cr@0 68
mas01cr@193 69 else if(O2_ACTION(COM_POWER))
mas01cr@193 70 power_flag(dbName);
mas01cr@193 71
mas01cr@0 72 else if(O2_ACTION(COM_DUMP))
mas01cr@0 73 dump(dbName);
mas01mc@292 74
mas01mc@292 75 else if(O2_ACTION(COM_INDEX))
mas01mc@292 76 index_index_db(dbName);
mas01cr@0 77
mas01cr@0 78 else
mas01cr@0 79 error("Unrecognized command",command);
mas01cr@0 80 }
mas01cr@0 81
mas01cr@133 82 audioDB::audioDB(const unsigned argc, char* const argv[], adb__queryResponse *adbQueryResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 83 {
mas01cr@97 84 try {
mas01cr@151 85 isServer = 1; // FIXME: Hack
mas01cr@97 86 processArgs(argc, argv);
mas01cr@97 87 assert(O2_ACTION(COM_QUERY));
mas01cr@133 88 query(dbName, inFile, adbQueryResponse);
mas01cr@97 89 } catch(char *err) {
mas01cr@97 90 cleanup();
mas01cr@97 91 throw(err);
mas01cr@97 92 }
mas01cr@76 93 }
mas01cr@76 94
mas01cr@133 95 audioDB::audioDB(const unsigned argc, char* const argv[], adb__statusResponse *adbStatusResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 96 {
mas01cr@97 97 try {
mas01cr@151 98 isServer = 1; // FIXME: Hack
mas01cr@97 99 processArgs(argc, argv);
mas01cr@97 100 assert(O2_ACTION(COM_STATUS));
mas01cr@133 101 status(dbName, adbStatusResponse);
mas01cr@97 102 } catch(char *err) {
mas01cr@97 103 cleanup();
mas01cr@97 104 throw(err);
mas01cr@97 105 }
mas01cr@76 106 }
mas01cr@76 107
mas01cr@97 108 void audioDB::cleanup() {
mas01cr@122 109 cmdline_parser_free(&args_info);
mas01cr@0 110 if(indata)
mas01cr@0 111 munmap(indata,statbuf.st_size);
mas01cr@0 112 if(db)
mas01cr@196 113 munmap(db,getpagesize());
mas01cr@196 114 if(fileTable)
mas01cr@196 115 munmap(fileTable, fileTableLength);
mas01cr@196 116 if(trackTable)
mas01cr@196 117 munmap(trackTable, trackTableLength);
mas01cr@196 118 if(dataBuf)
mas01cr@196 119 munmap(dataBuf, dataBufLength);
mas01cr@196 120 if(timesTable)
mas01cr@196 121 munmap(timesTable, timesTableLength);
mas01cr@196 122 if(l2normTable)
mas01cr@196 123 munmap(l2normTable, l2normTableLength);
mas01mc@292 124 if(trackOffsetTable)
mas01mc@292 125 delete trackOffsetTable;
mas01mc@292 126 if(reporter)
mas01mc@292 127 delete reporter;
mas01mc@292 128 if(exact_evaluation_queue)
mas01mc@292 129 delete exact_evaluation_queue;
mas01cr@284 130 if(rng)
mas01cr@284 131 gsl_rng_free(rng);
mas01mc@292 132 if(vv)
mas01mc@292 133 delete vv;
mas01cr@0 134 if(dbfid>0)
mas01cr@0 135 close(dbfid);
mas01cr@0 136 if(infid>0)
mas01cr@0 137 close(infid);
mas01cr@0 138 if(dbH)
mas01cr@0 139 delete dbH;
mas01cr@0 140 }
mas01cr@0 141
mas01cr@97 142 audioDB::~audioDB(){
mas01cr@97 143 cleanup();
mas01cr@97 144 }
mas01cr@97 145
mas01cr@0 146 int audioDB::processArgs(const unsigned argc, char* const argv[]){
mas01cr@0 147
mas01cr@0 148 if(argc<2){
mas01cr@0 149 cmdline_parser_print_version ();
mas01cr@0 150 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 151 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 152 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 153 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 154 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 155 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@0 156 exit(0);
mas01cr@0 157 }
mas01cr@0 158
mas01cr@0 159 if (cmdline_parser (argc, argv, &args_info) != 0)
mas01cr@151 160 error("Error parsing command line");
mas01cr@0 161
mas01cr@0 162 if(args_info.help_given){
mas01cr@0 163 cmdline_parser_print_help();
mas01cr@0 164 exit(0);
mas01cr@0 165 }
mas01cr@0 166
mas01cr@0 167 if(args_info.verbosity_given){
mas01cr@239 168 verbosity = args_info.verbosity_arg;
mas01cr@239 169 if(verbosity < 0 || verbosity > 10){
mas01cr@239 170 std::cerr << "Warning: verbosity out of range, setting to 1" << std::endl;
mas01cr@239 171 verbosity = 1;
mas01cr@0 172 }
mas01cr@0 173 }
mas01cr@0 174
mas01cr@129 175 if(args_info.size_given) {
mas01cr@256 176 if(args_info.datasize_given) {
mas01cr@256 177 error("both --size and --datasize given", "");
mas01cr@256 178 }
mas01cr@256 179 if(args_info.ntracks_given) {
mas01cr@256 180 error("both --size and --ntracks given", "");
mas01cr@256 181 }
mas01cr@256 182 if(args_info.datadim_given) {
mas01cr@256 183 error("both --size and --datadim given", "");
mas01cr@256 184 }
mas01cr@196 185 if (args_info.size_arg < 50 || args_info.size_arg > 32000) {
mas01cr@129 186 error("Size out of range", "");
mas01cr@129 187 }
mas01cr@256 188 double ratio = (double) args_info.size_arg * 1000000 / ((double) O2_DEFAULTDBSIZE);
mas01cr@256 189 /* FIXME: what's the safe way of doing this? */
mas01cr@256 190 datasize = (unsigned int) ceil(datasize * ratio);
mas01cr@256 191 ntracks = (unsigned int) ceil(ntracks * ratio);
mas01cr@256 192 } else {
mas01cr@256 193 if(args_info.datasize_given) {
mas01cr@256 194 datasize = args_info.datasize_arg;
mas01cr@256 195 }
mas01cr@256 196 if(args_info.ntracks_given) {
mas01cr@256 197 ntracks = args_info.ntracks_arg;
mas01cr@256 198 }
mas01cr@256 199 if(args_info.datadim_given) {
mas01cr@256 200 datadim = args_info.datadim_arg;
mas01cr@256 201 }
mas01cr@129 202 }
mas01cr@129 203
mas01cr@239 204 if(args_info.radius_given) {
mas01cr@239 205 radius = args_info.radius_arg;
mas01mc@307 206 if(radius < 0 || radius > 1000000000) {
mas01cr@77 207 error("radius out of range");
mas01cr@239 208 } else {
mas01cr@239 209 VERB_LOG(3, "Setting radius to %f\n", radius);
mas01mc@17 210 }
mas01mc@17 211 }
mas01mc@17 212
mas01mc@292 213 sequenceLength = args_info.sequencelength_arg;
mas01mc@292 214 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01mc@292 215 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01mc@292 216 }
mas01mc@292 217 sequenceHop = args_info.sequencehop_arg;
mas01mc@292 218 if(sequenceHop < 1 || sequenceHop > 1000) {
mas01mc@292 219 error("seqhop out of range: 1 <= seqhop <= 1000");
mas01mc@292 220 }
mas01mc@292 221
mas01mc@292 222 if (args_info.absolute_threshold_given) {
mas01mc@292 223 if (args_info.absolute_threshold_arg >= 0) {
mas01mc@292 224 error("absolute threshold out of range: should be negative");
mas01mc@292 225 }
mas01mc@292 226 use_absolute_threshold = true;
mas01mc@292 227 absolute_threshold = args_info.absolute_threshold_arg;
mas01mc@292 228 }
mas01mc@292 229 if (args_info.relative_threshold_given) {
mas01mc@292 230 use_relative_threshold = true;
mas01mc@292 231 relative_threshold = args_info.relative_threshold_arg;
mas01mc@292 232 }
mas01mc@292 233
mas01cr@0 234 if(args_info.SERVER_given){
mas01cr@0 235 command=COM_SERVER;
mas01cr@0 236 port=args_info.SERVER_arg;
mas01cr@0 237 if(port<100 || port > 100000)
mas01cr@0 238 error("port out of range");
mas01cr@151 239 isServer = 1;
mas01cr@105 240 #if defined(O2_DEBUG)
mas01cr@104 241 struct sigaction sa;
mas01cr@104 242 sa.sa_sigaction = sigterm_action;
mas01cr@104 243 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 244 sigaction(SIGTERM, &sa, NULL);
mas01cr@104 245 sa.sa_sigaction = sighup_action;
mas01cr@104 246 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 247 sigaction(SIGHUP, &sa, NULL);
mas01cr@105 248 #endif
mas01cr@0 249 return 0;
mas01cr@0 250 }
mas01cr@0 251
mas01cr@0 252 // No return on client command, find database command
mas01cr@105 253 if(args_info.client_given){
mas01cr@105 254 command=COM_CLIENT;
mas01cr@105 255 hostport=args_info.client_arg;
mas01cr@105 256 isClient=1;
mas01cr@105 257 }
mas01cr@0 258
mas01cr@105 259 if(args_info.NEW_given){
mas01cr@105 260 command=COM_CREATE;
mas01cr@105 261 dbName=args_info.database_arg;
mas01cr@105 262 return 0;
mas01cr@105 263 }
mas01cr@0 264
mas01cr@105 265 if(args_info.STATUS_given){
mas01cr@105 266 command=COM_STATUS;
mas01cr@105 267 dbName=args_info.database_arg;
mas01cr@105 268 return 0;
mas01cr@105 269 }
mas01cr@0 270
mas01cr@280 271 if(args_info.SAMPLE_given) {
mas01cr@280 272 command = COM_SAMPLE;
mas01cr@280 273 dbName = args_info.database_arg;
mas01cr@280 274 sequenceLength = args_info.sequencelength_arg;
mas01cr@280 275 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01cr@280 276 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01cr@280 277 }
mas01cr@280 278 nsamples = args_info.nsamples_arg;
mas01cr@280 279 return 0;
mas01cr@280 280 }
mas01cr@280 281
mas01cr@105 282 if(args_info.DUMP_given){
mas01cr@105 283 command=COM_DUMP;
mas01cr@105 284 dbName=args_info.database_arg;
mas01cr@131 285 output = args_info.output_arg;
mas01cr@105 286 return 0;
mas01cr@105 287 }
mas01cr@0 288
mas01cr@105 289 if(args_info.L2NORM_given){
mas01cr@105 290 command=COM_L2NORM;
mas01cr@105 291 dbName=args_info.database_arg;
mas01cr@105 292 return 0;
mas01cr@105 293 }
mas01cr@0 294
mas01cr@193 295 if(args_info.POWER_given){
mas01cr@193 296 command=COM_POWER;
mas01cr@193 297 dbName=args_info.database_arg;
mas01cr@193 298 return 0;
mas01cr@193 299 }
mas01cr@193 300
mas01cr@105 301 if(args_info.INSERT_given){
mas01cr@105 302 command=COM_INSERT;
mas01cr@105 303 dbName=args_info.database_arg;
mas01cr@105 304 inFile=args_info.features_arg;
mas01cr@105 305 if(args_info.key_given)
mas01mc@292 306 if(!args_info.features_given)
mas01mc@292 307 error("INSERT: '-k key' argument depends on '-f features'");
mas01mc@292 308 else
mas01mc@292 309 key=args_info.key_arg;
mas01cr@105 310 if(args_info.times_given){
mas01cr@105 311 timesFileName=args_info.times_arg;
mas01cr@105 312 if(strlen(timesFileName)>0){
mas01cr@239 313 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 314 error("Could not open times file for reading", timesFileName);
mas01cr@105 315 usingTimes=1;
mas01cr@105 316 }
mas01cr@105 317 }
mas01cr@193 318 if (args_info.power_given) {
mas01cr@193 319 powerFileName = args_info.power_arg;
mas01cr@193 320 if (strlen(powerFileName) > 0) {
mas01cr@193 321 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 322 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 323 }
mas01cr@193 324 usingPower = 1;
mas01cr@193 325 }
mas01cr@193 326 }
mas01cr@105 327 return 0;
mas01cr@105 328 }
mas01cr@105 329
mas01cr@105 330 if(args_info.BATCHINSERT_given){
mas01cr@105 331 command=COM_BATCHINSERT;
mas01cr@105 332 dbName=args_info.database_arg;
mas01cr@105 333 inFile=args_info.featureList_arg;
mas01cr@105 334 if(args_info.keyList_given)
mas01tc@298 335 if(!args_info.featureList_given)
mas01tc@300 336 error("BATCHINSERT: '-K keyList' argument depends on '-F featureList'");
mas01mc@292 337 else
mas01cr@304 338 key=args_info.keyList_arg; // INCONSISTENT NO CHECK
mas01cr@0 339
mas01cr@105 340 /* TO DO: REPLACE WITH
mas01cr@0 341 if(args_info.keyList_given){
mas01mc@18 342 trackFileName=args_info.keyList_arg;
mas01cr@239 343 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01mc@18 344 error("Could not open keyList file for reading",trackFileName);
mas01cr@0 345 }
mas01cr@0 346 AND UPDATE BATCHINSERT()
mas01cr@105 347 */
mas01cr@105 348
mas01cr@105 349 if(args_info.timesList_given){
mas01cr@105 350 timesFileName=args_info.timesList_arg;
mas01cr@105 351 if(strlen(timesFileName)>0){
mas01cr@239 352 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 353 error("Could not open timesList file for reading", timesFileName);
mas01cr@105 354 usingTimes=1;
mas01cr@105 355 }
mas01cr@105 356 }
mas01cr@193 357 if(args_info.powerList_given){
mas01cr@193 358 powerFileName=args_info.powerList_arg;
mas01cr@193 359 if(strlen(powerFileName)>0){
mas01cr@239 360 if(!(powerFile = new std::ifstream(powerFileName,std::ios::in)))
mas01cr@193 361 error("Could not open powerList file for reading", powerFileName);
mas01cr@193 362 usingPower=1;
mas01cr@193 363 }
mas01cr@193 364 }
mas01cr@105 365 return 0;
mas01cr@105 366 }
mas01mc@292 367
mas01mc@292 368 // Set no_unit_norm flag
mas01mc@292 369 no_unit_norming = args_info.no_unit_norming_flag;
mas01mc@292 370 lsh_use_u_functions = args_info.lsh_use_u_functions_flag;
mas01mc@292 371
mas01mc@292 372 // LSH Index Command
mas01mc@292 373 if(args_info.INDEX_given){
mas01mc@292 374 if(radius <= 0 )
mas01mc@292 375 error("INDEXing requires a Radius argument");
mas01mc@292 376 if(!(sequenceLength>0 && sequenceLength <= O2_MAXSEQLEN))
mas01mc@292 377 error("INDEXing requires 1 <= sequenceLength <= 1000");
mas01mc@292 378 command=COM_INDEX;
mas01mc@292 379 dbName=args_info.database_arg;
mas01mc@292 380
mas01mc@292 381 // Whether to store LSH hash tables for query in core (FORMAT2)
mas01mc@297 382 lsh_in_core = !args_info.lsh_on_disk_flag; // This flag is set to 0 if on_disk requested
mas01mc@292 383
mas01mc@292 384 lsh_param_w = args_info.lsh_w_arg;
mas01mc@292 385 if(!(lsh_param_w>0 && lsh_param_w<=O2_SERIAL_MAX_BINWIDTH))
mas01mc@292 386 error("Indexing parameter w out of range (0.0 < w <= 100.0)");
mas01mc@292 387
mas01mc@292 388 lsh_param_k = args_info.lsh_k_arg;
mas01mc@292 389 if(!(lsh_param_k>0 && lsh_param_k<=O2_SERIAL_MAX_FUNS))
mas01mc@292 390 error("Indexing parameter k out of range (1 <= k <= 100)");
mas01mc@292 391
mas01mc@292 392 lsh_param_m = args_info.lsh_m_arg;
mas01mc@292 393 if(!(lsh_param_m>0 && lsh_param_m<= (1 + (sqrt(1 + O2_SERIAL_MAX_TABLES*8.0)))/2.0))
mas01mc@292 394 error("Indexing parameter m out of range (1 <= m <= 20)");
mas01mc@292 395
mas01mc@292 396 lsh_param_N = args_info.lsh_N_arg;
mas01mc@292 397 if(!(lsh_param_N>0 && lsh_param_N<=O2_SERIAL_MAX_ROWS))
mas01mc@292 398 error("Indexing parameter N out of range (1 <= N <= 1000000)");
mas01mc@292 399
mas01mc@292 400 lsh_param_b = args_info.lsh_b_arg;
mas01mc@292 401 if(!(lsh_param_b>0 && lsh_param_b<=O2_SERIAL_MAX_TRACKBATCH))
mas01mc@292 402 error("Indexing parameter b out of range (1 <= b <= 10000)");
mas01mc@292 403
mas01mc@296 404 lsh_param_ncols = args_info.lsh_ncols_arg;
mas01mc@296 405 if(lsh_in_core) // We don't want to block rows with FORMAT2 indexing
mas01mc@296 406 lsh_param_ncols = O2_SERIAL_MAX_COLS;
mas01mc@292 407 if( !(lsh_param_ncols>0 && lsh_param_ncols<=O2_SERIAL_MAX_COLS))
mas01mc@292 408 error("Indexing parameter ncols out of range (1 <= ncols <= 1000");
mas01mc@292 409
mas01mc@292 410 return 0;
mas01mc@292 411 }
mas01mc@292 412
mas01cr@105 413 // Query command and arguments
mas01cr@105 414 if(args_info.QUERY_given){
mas01cr@105 415 command=COM_QUERY;
mas01cr@105 416 dbName=args_info.database_arg;
mas01mc@292 417 // XOR features and key search
mas01mc@292 418 if(!args_info.features_given && !args_info.key_given || (args_info.features_given && args_info.key_given))
mas01mc@292 419 error("QUERY requires exactly one of either -f features or -k key");
mas01mc@292 420 if(args_info.features_given)
mas01mc@292 421 inFile=args_info.features_arg; // query from file
mas01mc@292 422 else{
mas01mc@292 423 query_from_key = true;
mas01mc@292 424 key=args_info.key_arg; // query from key
mas01mc@292 425 }
mas01mc@292 426
mas01cr@105 427 if(args_info.keyList_given){
mas01cr@105 428 trackFileName=args_info.keyList_arg;
mas01cr@239 429 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01cr@105 430 error("Could not open keyList file for reading",trackFileName);
mas01cr@105 431 }
mas01cr@105 432
mas01cr@105 433 if(args_info.times_given){
mas01cr@105 434 timesFileName=args_info.times_arg;
mas01cr@105 435 if(strlen(timesFileName)>0){
mas01cr@239 436 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 437 error("Could not open times file for reading", timesFileName);
mas01cr@105 438 usingTimes=1;
mas01cr@105 439 }
mas01cr@105 440 }
mas01cr@193 441
mas01cr@193 442 if(args_info.power_given){
mas01cr@193 443 powerFileName=args_info.power_arg;
mas01cr@193 444 if(strlen(powerFileName)>0){
mas01cr@193 445 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 446 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 447 }
mas01cr@193 448 usingPower = 1;
mas01cr@193 449 }
mas01cr@193 450 }
mas01cr@105 451
mas01cr@105 452 // query type
mas01cr@105 453 if(strncmp(args_info.QUERY_arg, "track", MAXSTR)==0)
mas01cr@105 454 queryType=O2_TRACK_QUERY;
mas01cr@105 455 else if(strncmp(args_info.QUERY_arg, "point", MAXSTR)==0)
mas01cr@105 456 queryType=O2_POINT_QUERY;
mas01cr@105 457 else if(strncmp(args_info.QUERY_arg, "sequence", MAXSTR)==0)
mas01cr@105 458 queryType=O2_SEQUENCE_QUERY;
mas01mc@248 459 else if(strncmp(args_info.QUERY_arg, "nsequence", MAXSTR)==0)
mas01mc@248 460 queryType=O2_N_SEQUENCE_QUERY;
mas01mc@263 461 else if(strncmp(args_info.QUERY_arg, "onetoonensequence", MAXSTR)==0)
mas01mc@263 462 queryType=O2_ONE_TO_ONE_N_SEQUENCE_QUERY;
mas01cr@105 463 else
mas01cr@105 464 error("unsupported query type",args_info.QUERY_arg);
mas01cr@105 465
mas01cr@105 466 if(!args_info.exhaustive_flag){
mas01cr@105 467 queryPoint = args_info.qpoint_arg;
mas01cr@105 468 usingQueryPoint=1;
mas01cr@105 469 if(queryPoint<0 || queryPoint >10000)
mas01cr@105 470 error("queryPoint out of range: 0 <= queryPoint <= 10000");
mas01cr@105 471 }
mas01mc@292 472
mas01mc@296 473 // Whether to pre-load LSH hash tables for query (default on, if flag set then off)
mas01mc@297 474 lsh_in_core = !args_info.lsh_on_disk_flag;
mas01mc@292 475
mas01mc@292 476 // Whether to perform exact evaluation of points returned by LSH
mas01mc@292 477 lsh_exact = args_info.lsh_exact_flag;
mas01mc@292 478
mas01cr@105 479 pointNN = args_info.pointnn_arg;
mas01mc@263 480 if(pointNN < 1 || pointNN > O2_MAXNN) {
mas01mc@263 481 error("pointNN out of range: 1 <= pointNN <= 1000000");
mas01cr@105 482 }
mas01cr@105 483 trackNN = args_info.resultlength_arg;
mas01mc@263 484 if(trackNN < 1 || trackNN > O2_MAXNN) {
mas01mc@263 485 error("resultlength out of range: 1 <= resultlength <= 1000000");
mas01cr@105 486 }
mas01cr@105 487 return 0;
mas01cr@105 488 }
mas01cr@105 489 return -1; // no command found
mas01cr@0 490 }
mas01cr@0 491
mas01cr@133 492 void audioDB::status(const char* dbName, adb__statusResponse *adbStatusResponse){
mas01cr@0 493 if(!dbH)
mas01cr@196 494 initTables(dbName, 0);
mas01cr@0 495
mas01cr@0 496 unsigned dudCount=0;
mas01cr@0 497 unsigned nullCount=0;
mas01cr@0 498 for(unsigned k=0; k<dbH->numFiles; k++){
mas01mc@18 499 if(trackTable[k]<sequenceLength){
mas01cr@0 500 dudCount++;
mas01mc@18 501 if(!trackTable[k])
mas01cr@76 502 nullCount++;
mas01cr@0 503 }
mas01cr@0 504 }
mas01cr@76 505
mas01cr@133 506 if(adbStatusResponse == 0) {
mas01cr@76 507
mas01cr@76 508 // Update Header information
mas01cr@239 509 std::cout << "num files:" << dbH->numFiles << std::endl;
mas01cr@239 510 std::cout << "data dim:" << dbH->dim <<std::endl;
mas01cr@76 511 if(dbH->dim>0){
mas01cr@239 512 std::cout << "total vectors:" << dbH->length/(sizeof(double)*dbH->dim)<<std::endl;
mas01cr@239 513 std::cout << "vectors available:" << (dbH->timesTableOffset-(dbH->dataOffset+dbH->length))/(sizeof(double)*dbH->dim) << std::endl;
mas01cr@76 514 }
mas01cr@239 515 std::cout << "total bytes:" << dbH->length << " (" << (100.0*dbH->length)/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
mas01cr@239 516 std::cout << "bytes available:" << dbH->timesTableOffset-(dbH->dataOffset+dbH->length) << " (" <<
mas01cr@239 517 (100.0*(dbH->timesTableOffset-(dbH->dataOffset+dbH->length)))/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
mas01mc@301 518 std::cout << "flags:" << " l2norm[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_L2NORM)
mas01mc@301 519 << "] minmax[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_MINMAX)
mas01mc@301 520 << "] power[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_POWER)
mas01mc@301 521 << "] times[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_TIMES) << "]" << endl;
mas01cr@239 522 std::cout << "null count: " << nullCount << " small sequence count " << dudCount-nullCount << std::endl;
mas01cr@76 523 } else {
mas01cr@133 524 adbStatusResponse->result.numFiles = dbH->numFiles;
mas01cr@133 525 adbStatusResponse->result.dim = dbH->dim;
mas01cr@133 526 adbStatusResponse->result.length = dbH->length;
mas01cr@133 527 adbStatusResponse->result.dudCount = dudCount;
mas01cr@133 528 adbStatusResponse->result.nullCount = nullCount;
mas01cr@133 529 adbStatusResponse->result.flags = dbH->flags;
mas01cr@76 530 }
mas01cr@0 531 }
mas01cr@0 532
mas01cr@196 533 void audioDB::l2norm(const char* dbName) {
mas01cr@196 534 forWrite = true;
mas01cr@196 535 initTables(dbName, 0);
mas01cr@0 536 if(dbH->length>0){
mas01cr@196 537 /* FIXME: should probably be uint64_t */
mas01cr@0 538 unsigned numVectors = dbH->length/(sizeof(double)*dbH->dim);
mas01cr@196 539 CHECKED_MMAP(double *, dataBuf, dbH->dataOffset, dataBufLength);
mas01cr@0 540 unitNormAndInsertL2(dataBuf, dbH->dim, numVectors, 0); // No append
mas01cr@0 541 }
mas01cr@0 542 // Update database flags
mas01cr@0 543 dbH->flags = dbH->flags|O2_FLAG_L2NORM;
mas01cr@0 544 memcpy (db, dbH, O2_HEADERSIZE);
mas01cr@0 545 }
mas01cr@193 546
mas01cr@193 547 void audioDB::power_flag(const char *dbName) {
mas01cr@196 548 forWrite = true;
mas01cr@196 549 initTables(dbName, 0);
mas01cr@193 550 if (dbH->length > 0) {
mas01cr@193 551 error("cannot turn on power storage for non-empty database", dbName);
mas01cr@193 552 }
mas01cr@193 553 dbH->flags |= O2_FLAG_POWER;
mas01cr@193 554 memcpy(db, dbH, O2_HEADERSIZE);
mas01cr@193 555 }
mas01cr@193 556
mas01cr@239 557 // Unit norm block of features
mas01cr@0 558
mas01cr@239 559 /* FIXME: in fact this does not unit norm a block of features, it just
mas01cr@239 560 records the L2 norms somewhere. unitNorm() does in fact unit norm
mas01cr@239 561 a block of features. */
mas01cr@0 562 void audioDB::unitNormAndInsertL2(double* X, unsigned dim, unsigned n, unsigned append=0){
mas01cr@0 563 unsigned d;
mas01cr@59 564 double *p;
mas01cr@0 565 unsigned nn = n;
mas01cr@0 566
mas01cr@0 567 assert(l2normTable);
mas01cr@0 568
mas01cr@0 569 if( !append && (dbH->flags & O2_FLAG_L2NORM) )
mas01cr@0 570 error("Database is already L2 normed", "automatic norm on insert is enabled");
mas01cr@0 571
mas01cr@239 572 VERB_LOG(2, "norming %u vectors...", n);
mas01cr@0 573
mas01cr@0 574 double* l2buf = new double[n];
mas01cr@0 575 double* l2ptr = l2buf;
mas01cr@0 576 assert(l2buf);
mas01cr@0 577 assert(X);
mas01cr@0 578
mas01cr@0 579 while(nn--){
mas01cr@0 580 p=X;
mas01cr@0 581 *l2ptr=0.0;
mas01cr@0 582 d=dim;
mas01cr@0 583 while(d--){
mas01cr@0 584 *l2ptr+=*p**p;
mas01cr@0 585 p++;
mas01cr@0 586 }
mas01mc@17 587 l2ptr++;
mas01mc@17 588 X+=dim;
mas01cr@0 589 }
mas01cr@0 590 unsigned offset;
mas01cr@84 591 if(append) {
mas01cr@84 592 // FIXME: a hack, a very palpable hack: the vectors have already
mas01cr@84 593 // been inserted, and dbH->length has already been updated. We
mas01cr@84 594 // need to subtract off again the number of vectors that we've
mas01cr@84 595 // inserted this time...
mas01cr@84 596 offset=(dbH->length/(dbH->dim*sizeof(double)))-n; // number of vectors
mas01cr@84 597 } else {
mas01cr@0 598 offset=0;
mas01cr@84 599 }
mas01cr@0 600 memcpy(l2normTable+offset, l2buf, n*sizeof(double));
mas01cr@0 601 if(l2buf)
mas01mc@17 602 delete[] l2buf;
mas01cr@239 603 VERB_LOG(2, " done.");
mas01cr@193 604 }
mas01cr@193 605
mas01cr@0 606 int main(const unsigned argc, char* const argv[]){
mas01cr@0 607 audioDB(argc, argv);
mas01cr@0 608 }