annotate audioDB.cpp @ 284:cacad987d785

Really finish with the sampling branch, this time merging all of it, yes, even the last revision. (The last revision was one that seeded the RNG with the current time, which is helpful when trying to get multiple independent-ish samples from the same database...)
author mas01cr
date Mon, 07 Jul 2008 08:57:06 +0000
parents 3be15407e814
children d9a88cfd4ab6
rev   line source
mas01cr@0 1 #include "audioDB.h"
mas01cr@0 2
mas01cr@76 3 audioDB::audioDB(const unsigned argc, char* const argv[]): O2_AUDIODB_INITIALIZERS
mas01cr@76 4 {
mas01cr@0 5 if(processArgs(argc, argv)<0){
mas01cr@0 6 printf("No command found.\n");
mas01cr@0 7 cmdline_parser_print_version ();
mas01cr@0 8 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 9 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 10 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 11 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 12 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 13 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@151 14 error("No command found");
mas01cr@0 15 }
mas01cr@77 16
mas01cr@0 17 if(O2_ACTION(COM_SERVER))
mas01cr@0 18 startServer();
mas01cr@0 19
mas01cr@0 20 else if(O2_ACTION(COM_CREATE))
mas01cr@0 21 create(dbName);
mas01cr@0 22
mas01cr@0 23 else if(O2_ACTION(COM_INSERT))
mas01cr@0 24 insert(dbName, inFile);
mas01cr@0 25
mas01cr@0 26 else if(O2_ACTION(COM_BATCHINSERT))
mas01cr@0 27 batchinsert(dbName, inFile);
mas01cr@0 28
mas01cr@0 29 else if(O2_ACTION(COM_QUERY))
mas01cr@0 30 if(isClient)
mas01cr@0 31 ws_query(dbName, inFile, (char*)hostport);
mas01cr@0 32 else
mas01cr@76 33 query(dbName, inFile);
mas01cr@0 34
mas01cr@0 35 else if(O2_ACTION(COM_STATUS))
mas01cr@0 36 if(isClient)
mas01cr@0 37 ws_status(dbName,(char*)hostport);
mas01cr@0 38 else
mas01cr@0 39 status(dbName);
mas01cr@280 40
mas01cr@280 41 else if(O2_ACTION(COM_SAMPLE))
mas01cr@280 42 sample(dbName);
mas01cr@0 43
mas01cr@0 44 else if(O2_ACTION(COM_L2NORM))
mas01cr@0 45 l2norm(dbName);
mas01cr@0 46
mas01cr@193 47 else if(O2_ACTION(COM_POWER))
mas01cr@193 48 power_flag(dbName);
mas01cr@193 49
mas01cr@0 50 else if(O2_ACTION(COM_DUMP))
mas01cr@0 51 dump(dbName);
mas01cr@0 52
mas01cr@0 53 else
mas01cr@0 54 error("Unrecognized command",command);
mas01cr@0 55 }
mas01cr@0 56
mas01cr@133 57 audioDB::audioDB(const unsigned argc, char* const argv[], adb__queryResponse *adbQueryResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 58 {
mas01cr@97 59 try {
mas01cr@151 60 isServer = 1; // FIXME: Hack
mas01cr@97 61 processArgs(argc, argv);
mas01cr@97 62 assert(O2_ACTION(COM_QUERY));
mas01cr@133 63 query(dbName, inFile, adbQueryResponse);
mas01cr@97 64 } catch(char *err) {
mas01cr@97 65 cleanup();
mas01cr@97 66 throw(err);
mas01cr@97 67 }
mas01cr@76 68 }
mas01cr@76 69
mas01cr@133 70 audioDB::audioDB(const unsigned argc, char* const argv[], adb__statusResponse *adbStatusResponse): O2_AUDIODB_INITIALIZERS
mas01cr@76 71 {
mas01cr@97 72 try {
mas01cr@151 73 isServer = 1; // FIXME: Hack
mas01cr@97 74 processArgs(argc, argv);
mas01cr@97 75 assert(O2_ACTION(COM_STATUS));
mas01cr@133 76 status(dbName, adbStatusResponse);
mas01cr@97 77 } catch(char *err) {
mas01cr@97 78 cleanup();
mas01cr@97 79 throw(err);
mas01cr@97 80 }
mas01cr@76 81 }
mas01cr@76 82
mas01cr@97 83 void audioDB::cleanup() {
mas01cr@122 84 cmdline_parser_free(&args_info);
mas01cr@0 85 if(indata)
mas01cr@0 86 munmap(indata,statbuf.st_size);
mas01cr@0 87 if(db)
mas01cr@196 88 munmap(db,getpagesize());
mas01cr@196 89 if(fileTable)
mas01cr@196 90 munmap(fileTable, fileTableLength);
mas01cr@196 91 if(trackTable)
mas01cr@196 92 munmap(trackTable, trackTableLength);
mas01cr@196 93 if(dataBuf)
mas01cr@196 94 munmap(dataBuf, dataBufLength);
mas01cr@196 95 if(timesTable)
mas01cr@196 96 munmap(timesTable, timesTableLength);
mas01cr@196 97 if(l2normTable)
mas01cr@196 98 munmap(l2normTable, l2normTableLength);
mas01cr@196 99
mas01cr@284 100 if(rng)
mas01cr@284 101 gsl_rng_free(rng);
mas01cr@284 102
mas01cr@0 103 if(dbfid>0)
mas01cr@0 104 close(dbfid);
mas01cr@0 105 if(infid>0)
mas01cr@0 106 close(infid);
mas01cr@0 107 if(dbH)
mas01cr@0 108 delete dbH;
mas01cr@0 109 }
mas01cr@0 110
mas01cr@97 111 audioDB::~audioDB(){
mas01cr@97 112 cleanup();
mas01cr@97 113 }
mas01cr@97 114
mas01cr@0 115 int audioDB::processArgs(const unsigned argc, char* const argv[]){
mas01cr@0 116
mas01cr@0 117 if(argc<2){
mas01cr@0 118 cmdline_parser_print_version ();
mas01cr@0 119 if (strlen(gengetopt_args_info_purpose) > 0)
mas01cr@0 120 printf("%s\n", gengetopt_args_info_purpose);
mas01cr@0 121 printf("%s\n", gengetopt_args_info_usage);
mas01cr@0 122 printf("%s\n", gengetopt_args_info_help[1]);
mas01cr@0 123 printf("%s\n", gengetopt_args_info_help[2]);
mas01cr@0 124 printf("%s\n", gengetopt_args_info_help[0]);
mas01cr@0 125 exit(0);
mas01cr@0 126 }
mas01cr@0 127
mas01cr@0 128 if (cmdline_parser (argc, argv, &args_info) != 0)
mas01cr@151 129 error("Error parsing command line");
mas01cr@0 130
mas01cr@0 131 if(args_info.help_given){
mas01cr@0 132 cmdline_parser_print_help();
mas01cr@0 133 exit(0);
mas01cr@0 134 }
mas01cr@0 135
mas01cr@0 136 if(args_info.verbosity_given){
mas01cr@239 137 verbosity = args_info.verbosity_arg;
mas01cr@239 138 if(verbosity < 0 || verbosity > 10){
mas01cr@239 139 std::cerr << "Warning: verbosity out of range, setting to 1" << std::endl;
mas01cr@239 140 verbosity = 1;
mas01cr@0 141 }
mas01cr@0 142 }
mas01cr@0 143
mas01cr@129 144 if(args_info.size_given) {
mas01cr@256 145 if(args_info.datasize_given) {
mas01cr@256 146 error("both --size and --datasize given", "");
mas01cr@256 147 }
mas01cr@256 148 if(args_info.ntracks_given) {
mas01cr@256 149 error("both --size and --ntracks given", "");
mas01cr@256 150 }
mas01cr@256 151 if(args_info.datadim_given) {
mas01cr@256 152 error("both --size and --datadim given", "");
mas01cr@256 153 }
mas01cr@196 154 if (args_info.size_arg < 50 || args_info.size_arg > 32000) {
mas01cr@129 155 error("Size out of range", "");
mas01cr@129 156 }
mas01cr@256 157 double ratio = (double) args_info.size_arg * 1000000 / ((double) O2_DEFAULTDBSIZE);
mas01cr@256 158 /* FIXME: what's the safe way of doing this? */
mas01cr@256 159 datasize = (unsigned int) ceil(datasize * ratio);
mas01cr@256 160 ntracks = (unsigned int) ceil(ntracks * ratio);
mas01cr@256 161 } else {
mas01cr@256 162 if(args_info.datasize_given) {
mas01cr@256 163 datasize = args_info.datasize_arg;
mas01cr@256 164 }
mas01cr@256 165 if(args_info.ntracks_given) {
mas01cr@256 166 ntracks = args_info.ntracks_arg;
mas01cr@256 167 }
mas01cr@256 168 if(args_info.datadim_given) {
mas01cr@256 169 datadim = args_info.datadim_arg;
mas01cr@256 170 }
mas01cr@129 171 }
mas01cr@129 172
mas01cr@239 173 if(args_info.radius_given) {
mas01cr@239 174 radius = args_info.radius_arg;
mas01cr@239 175 if(radius <= 0 || radius > 1000000000) {
mas01cr@77 176 error("radius out of range");
mas01cr@239 177 } else {
mas01cr@239 178 VERB_LOG(3, "Setting radius to %f\n", radius);
mas01mc@17 179 }
mas01mc@17 180 }
mas01mc@17 181
mas01cr@0 182 if(args_info.SERVER_given){
mas01cr@0 183 command=COM_SERVER;
mas01cr@0 184 port=args_info.SERVER_arg;
mas01cr@0 185 if(port<100 || port > 100000)
mas01cr@0 186 error("port out of range");
mas01cr@151 187 isServer = 1;
mas01cr@105 188 #if defined(O2_DEBUG)
mas01cr@104 189 struct sigaction sa;
mas01cr@104 190 sa.sa_sigaction = sigterm_action;
mas01cr@104 191 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 192 sigaction(SIGTERM, &sa, NULL);
mas01cr@104 193 sa.sa_sigaction = sighup_action;
mas01cr@104 194 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
mas01cr@104 195 sigaction(SIGHUP, &sa, NULL);
mas01cr@105 196 #endif
mas01cr@0 197 return 0;
mas01cr@0 198 }
mas01cr@0 199
mas01cr@0 200 // No return on client command, find database command
mas01cr@105 201 if(args_info.client_given){
mas01cr@105 202 command=COM_CLIENT;
mas01cr@105 203 hostport=args_info.client_arg;
mas01cr@105 204 isClient=1;
mas01cr@105 205 }
mas01cr@0 206
mas01cr@105 207 if(args_info.NEW_given){
mas01cr@105 208 command=COM_CREATE;
mas01cr@105 209 dbName=args_info.database_arg;
mas01cr@105 210 return 0;
mas01cr@105 211 }
mas01cr@0 212
mas01cr@105 213 if(args_info.STATUS_given){
mas01cr@105 214 command=COM_STATUS;
mas01cr@105 215 dbName=args_info.database_arg;
mas01cr@105 216 return 0;
mas01cr@105 217 }
mas01cr@0 218
mas01cr@280 219 if(args_info.SAMPLE_given) {
mas01cr@280 220 command = COM_SAMPLE;
mas01cr@280 221 dbName = args_info.database_arg;
mas01cr@280 222 sequenceLength = args_info.sequencelength_arg;
mas01cr@280 223 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01cr@280 224 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01cr@280 225 }
mas01cr@280 226 nsamples = args_info.nsamples_arg;
mas01cr@280 227 return 0;
mas01cr@280 228 }
mas01cr@280 229
mas01cr@105 230 if(args_info.DUMP_given){
mas01cr@105 231 command=COM_DUMP;
mas01cr@105 232 dbName=args_info.database_arg;
mas01cr@131 233 output = args_info.output_arg;
mas01cr@105 234 return 0;
mas01cr@105 235 }
mas01cr@0 236
mas01cr@105 237 if(args_info.L2NORM_given){
mas01cr@105 238 command=COM_L2NORM;
mas01cr@105 239 dbName=args_info.database_arg;
mas01cr@105 240 return 0;
mas01cr@105 241 }
mas01cr@0 242
mas01cr@193 243 if(args_info.POWER_given){
mas01cr@193 244 command=COM_POWER;
mas01cr@193 245 dbName=args_info.database_arg;
mas01cr@193 246 return 0;
mas01cr@193 247 }
mas01cr@193 248
mas01cr@105 249 if(args_info.INSERT_given){
mas01cr@105 250 command=COM_INSERT;
mas01cr@105 251 dbName=args_info.database_arg;
mas01cr@105 252 inFile=args_info.features_arg;
mas01cr@105 253 if(args_info.key_given)
mas01cr@105 254 key=args_info.key_arg;
mas01cr@105 255 if(args_info.times_given){
mas01cr@105 256 timesFileName=args_info.times_arg;
mas01cr@105 257 if(strlen(timesFileName)>0){
mas01cr@239 258 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 259 error("Could not open times file for reading", timesFileName);
mas01cr@105 260 usingTimes=1;
mas01cr@105 261 }
mas01cr@105 262 }
mas01cr@193 263 if (args_info.power_given) {
mas01cr@193 264 powerFileName = args_info.power_arg;
mas01cr@193 265 if (strlen(powerFileName) > 0) {
mas01cr@193 266 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 267 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 268 }
mas01cr@193 269 usingPower = 1;
mas01cr@193 270 }
mas01cr@193 271 }
mas01cr@105 272 return 0;
mas01cr@105 273 }
mas01cr@105 274
mas01cr@105 275 if(args_info.BATCHINSERT_given){
mas01cr@105 276 command=COM_BATCHINSERT;
mas01cr@105 277 dbName=args_info.database_arg;
mas01cr@105 278 inFile=args_info.featureList_arg;
mas01cr@105 279 if(args_info.keyList_given)
mas01cr@105 280 key=args_info.keyList_arg; // INCONSISTENT NO CHECK
mas01cr@0 281
mas01cr@105 282 /* TO DO: REPLACE WITH
mas01cr@0 283 if(args_info.keyList_given){
mas01mc@18 284 trackFileName=args_info.keyList_arg;
mas01cr@239 285 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01mc@18 286 error("Could not open keyList file for reading",trackFileName);
mas01cr@0 287 }
mas01cr@0 288 AND UPDATE BATCHINSERT()
mas01cr@105 289 */
mas01cr@105 290
mas01cr@105 291 if(args_info.timesList_given){
mas01cr@105 292 timesFileName=args_info.timesList_arg;
mas01cr@105 293 if(strlen(timesFileName)>0){
mas01cr@239 294 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 295 error("Could not open timesList file for reading", timesFileName);
mas01cr@105 296 usingTimes=1;
mas01cr@105 297 }
mas01cr@105 298 }
mas01cr@193 299 if(args_info.powerList_given){
mas01cr@193 300 powerFileName=args_info.powerList_arg;
mas01cr@193 301 if(strlen(powerFileName)>0){
mas01cr@239 302 if(!(powerFile = new std::ifstream(powerFileName,std::ios::in)))
mas01cr@193 303 error("Could not open powerList file for reading", powerFileName);
mas01cr@193 304 usingPower=1;
mas01cr@193 305 }
mas01cr@193 306 }
mas01cr@105 307 return 0;
mas01cr@105 308 }
mas01cr@105 309
mas01cr@105 310 // Query command and arguments
mas01cr@105 311 if(args_info.QUERY_given){
mas01cr@105 312 command=COM_QUERY;
mas01cr@105 313 dbName=args_info.database_arg;
mas01cr@105 314 inFile=args_info.features_arg;
mas01cr@105 315
mas01cr@105 316 if(args_info.keyList_given){
mas01cr@105 317 trackFileName=args_info.keyList_arg;
mas01cr@239 318 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
mas01cr@105 319 error("Could not open keyList file for reading",trackFileName);
mas01cr@105 320 }
mas01cr@105 321
mas01cr@105 322 if(args_info.times_given){
mas01cr@105 323 timesFileName=args_info.times_arg;
mas01cr@105 324 if(strlen(timesFileName)>0){
mas01cr@239 325 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
mas01cr@105 326 error("Could not open times file for reading", timesFileName);
mas01cr@105 327 usingTimes=1;
mas01cr@105 328 }
mas01cr@105 329 }
mas01cr@193 330
mas01cr@193 331 if(args_info.power_given){
mas01cr@193 332 powerFileName=args_info.power_arg;
mas01cr@193 333 if(strlen(powerFileName)>0){
mas01cr@193 334 if (!(powerfd = open(powerFileName, O_RDONLY))) {
mas01cr@193 335 error("Could not open power file for reading", powerFileName, "open");
mas01cr@193 336 }
mas01cr@193 337 usingPower = 1;
mas01cr@193 338 }
mas01cr@193 339 }
mas01cr@105 340
mas01cr@105 341 // query type
mas01cr@105 342 if(strncmp(args_info.QUERY_arg, "track", MAXSTR)==0)
mas01cr@105 343 queryType=O2_TRACK_QUERY;
mas01cr@105 344 else if(strncmp(args_info.QUERY_arg, "point", MAXSTR)==0)
mas01cr@105 345 queryType=O2_POINT_QUERY;
mas01cr@105 346 else if(strncmp(args_info.QUERY_arg, "sequence", MAXSTR)==0)
mas01cr@105 347 queryType=O2_SEQUENCE_QUERY;
mas01mc@248 348 else if(strncmp(args_info.QUERY_arg, "nsequence", MAXSTR)==0)
mas01mc@248 349 queryType=O2_N_SEQUENCE_QUERY;
mas01mc@263 350 else if(strncmp(args_info.QUERY_arg, "onetoonensequence", MAXSTR)==0)
mas01mc@263 351 queryType=O2_ONE_TO_ONE_N_SEQUENCE_QUERY;
mas01cr@105 352 else
mas01cr@105 353 error("unsupported query type",args_info.QUERY_arg);
mas01cr@105 354
mas01cr@105 355 if(!args_info.exhaustive_flag){
mas01cr@105 356 queryPoint = args_info.qpoint_arg;
mas01cr@105 357 usingQueryPoint=1;
mas01cr@105 358 if(queryPoint<0 || queryPoint >10000)
mas01cr@105 359 error("queryPoint out of range: 0 <= queryPoint <= 10000");
mas01cr@105 360 }
mas01cr@105 361
mas01cr@105 362 pointNN = args_info.pointnn_arg;
mas01mc@263 363 if(pointNN < 1 || pointNN > O2_MAXNN) {
mas01mc@263 364 error("pointNN out of range: 1 <= pointNN <= 1000000");
mas01cr@105 365 }
mas01cr@105 366 trackNN = args_info.resultlength_arg;
mas01mc@263 367 if(trackNN < 1 || trackNN > O2_MAXNN) {
mas01mc@263 368 error("resultlength out of range: 1 <= resultlength <= 1000000");
mas01cr@105 369 }
mas01cr@105 370 sequenceLength = args_info.sequencelength_arg;
mas01cr@105 371 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01cr@105 372 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01cr@105 373 }
mas01cr@105 374 sequenceHop = args_info.sequencehop_arg;
mas01cr@105 375 if(sequenceHop < 1 || sequenceHop > 1000) {
mas01cr@105 376 error("seqhop out of range: 1 <= seqhop <= 1000");
mas01cr@105 377 }
mas01cr@193 378
mas01cr@193 379 if (args_info.absolute_threshold_given) {
mas01cr@193 380 if (args_info.absolute_threshold_arg >= 0) {
mas01cr@193 381 error("absolute threshold out of range: should be negative");
mas01cr@193 382 }
mas01cr@193 383 use_absolute_threshold = true;
mas01cr@193 384 absolute_threshold = args_info.absolute_threshold_arg;
mas01cr@193 385 }
mas01cr@193 386 if (args_info.relative_threshold_given) {
mas01cr@193 387 use_relative_threshold = true;
mas01cr@193 388 relative_threshold = args_info.relative_threshold_arg;
mas01cr@193 389 }
mas01cr@105 390 return 0;
mas01cr@105 391 }
mas01cr@105 392 return -1; // no command found
mas01cr@0 393 }
mas01cr@0 394
mas01cr@133 395 void audioDB::status(const char* dbName, adb__statusResponse *adbStatusResponse){
mas01cr@0 396 if(!dbH)
mas01cr@196 397 initTables(dbName, 0);
mas01cr@0 398
mas01cr@0 399 unsigned dudCount=0;
mas01cr@0 400 unsigned nullCount=0;
mas01cr@0 401 for(unsigned k=0; k<dbH->numFiles; k++){
mas01mc@18 402 if(trackTable[k]<sequenceLength){
mas01cr@0 403 dudCount++;
mas01mc@18 404 if(!trackTable[k])
mas01cr@76 405 nullCount++;
mas01cr@0 406 }
mas01cr@0 407 }
mas01cr@76 408
mas01cr@133 409 if(adbStatusResponse == 0) {
mas01cr@76 410
mas01cr@76 411 // Update Header information
mas01cr@239 412 std::cout << "num files:" << dbH->numFiles << std::endl;
mas01cr@239 413 std::cout << "data dim:" << dbH->dim <<std::endl;
mas01cr@76 414 if(dbH->dim>0){
mas01cr@239 415 std::cout << "total vectors:" << dbH->length/(sizeof(double)*dbH->dim)<<std::endl;
mas01cr@239 416 std::cout << "vectors available:" << (dbH->timesTableOffset-(dbH->dataOffset+dbH->length))/(sizeof(double)*dbH->dim) << std::endl;
mas01cr@76 417 }
mas01cr@239 418 std::cout << "total bytes:" << dbH->length << " (" << (100.0*dbH->length)/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
mas01cr@239 419 std::cout << "bytes available:" << dbH->timesTableOffset-(dbH->dataOffset+dbH->length) << " (" <<
mas01cr@239 420 (100.0*(dbH->timesTableOffset-(dbH->dataOffset+dbH->length)))/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
mas01cr@239 421 std::cout << "flags:" << dbH->flags << std::endl;
mas01cr@76 422
mas01cr@239 423 std::cout << "null count: " << nullCount << " small sequence count " << dudCount-nullCount << std::endl;
mas01cr@76 424 } else {
mas01cr@133 425 adbStatusResponse->result.numFiles = dbH->numFiles;
mas01cr@133 426 adbStatusResponse->result.dim = dbH->dim;
mas01cr@133 427 adbStatusResponse->result.length = dbH->length;
mas01cr@133 428 adbStatusResponse->result.dudCount = dudCount;
mas01cr@133 429 adbStatusResponse->result.nullCount = nullCount;
mas01cr@133 430 adbStatusResponse->result.flags = dbH->flags;
mas01cr@76 431 }
mas01cr@0 432 }
mas01cr@0 433
mas01cr@196 434 void audioDB::l2norm(const char* dbName) {
mas01cr@196 435 forWrite = true;
mas01cr@196 436 initTables(dbName, 0);
mas01cr@0 437 if(dbH->length>0){
mas01cr@196 438 /* FIXME: should probably be uint64_t */
mas01cr@0 439 unsigned numVectors = dbH->length/(sizeof(double)*dbH->dim);
mas01cr@196 440 CHECKED_MMAP(double *, dataBuf, dbH->dataOffset, dataBufLength);
mas01cr@0 441 unitNormAndInsertL2(dataBuf, dbH->dim, numVectors, 0); // No append
mas01cr@0 442 }
mas01cr@0 443 // Update database flags
mas01cr@0 444 dbH->flags = dbH->flags|O2_FLAG_L2NORM;
mas01cr@0 445 memcpy (db, dbH, O2_HEADERSIZE);
mas01cr@0 446 }
mas01cr@193 447
mas01cr@193 448 void audioDB::power_flag(const char *dbName) {
mas01cr@196 449 forWrite = true;
mas01cr@196 450 initTables(dbName, 0);
mas01cr@193 451 if (dbH->length > 0) {
mas01cr@193 452 error("cannot turn on power storage for non-empty database", dbName);
mas01cr@193 453 }
mas01cr@193 454 dbH->flags |= O2_FLAG_POWER;
mas01cr@193 455 memcpy(db, dbH, O2_HEADERSIZE);
mas01cr@193 456 }
mas01cr@193 457
mas01cr@239 458 // Unit norm block of features
mas01cr@0 459
mas01cr@239 460 /* FIXME: in fact this does not unit norm a block of features, it just
mas01cr@239 461 records the L2 norms somewhere. unitNorm() does in fact unit norm
mas01cr@239 462 a block of features. */
mas01cr@0 463 void audioDB::unitNormAndInsertL2(double* X, unsigned dim, unsigned n, unsigned append=0){
mas01cr@0 464 unsigned d;
mas01cr@59 465 double *p;
mas01cr@0 466 unsigned nn = n;
mas01cr@0 467
mas01cr@0 468 assert(l2normTable);
mas01cr@0 469
mas01cr@0 470 if( !append && (dbH->flags & O2_FLAG_L2NORM) )
mas01cr@0 471 error("Database is already L2 normed", "automatic norm on insert is enabled");
mas01cr@0 472
mas01cr@239 473 VERB_LOG(2, "norming %u vectors...", n);
mas01cr@0 474
mas01cr@0 475 double* l2buf = new double[n];
mas01cr@0 476 double* l2ptr = l2buf;
mas01cr@0 477 assert(l2buf);
mas01cr@0 478 assert(X);
mas01cr@0 479
mas01cr@0 480 while(nn--){
mas01cr@0 481 p=X;
mas01cr@0 482 *l2ptr=0.0;
mas01cr@0 483 d=dim;
mas01cr@0 484 while(d--){
mas01cr@0 485 *l2ptr+=*p**p;
mas01cr@0 486 p++;
mas01cr@0 487 }
mas01mc@17 488 l2ptr++;
mas01mc@17 489 X+=dim;
mas01cr@0 490 }
mas01cr@0 491 unsigned offset;
mas01cr@84 492 if(append) {
mas01cr@84 493 // FIXME: a hack, a very palpable hack: the vectors have already
mas01cr@84 494 // been inserted, and dbH->length has already been updated. We
mas01cr@84 495 // need to subtract off again the number of vectors that we've
mas01cr@84 496 // inserted this time...
mas01cr@84 497 offset=(dbH->length/(dbH->dim*sizeof(double)))-n; // number of vectors
mas01cr@84 498 } else {
mas01cr@0 499 offset=0;
mas01cr@84 500 }
mas01cr@0 501 memcpy(l2normTable+offset, l2buf, n*sizeof(double));
mas01cr@0 502 if(l2buf)
mas01mc@17 503 delete[] l2buf;
mas01cr@239 504 VERB_LOG(2, " done.");
mas01cr@193 505 }
mas01cr@193 506
mas01cr@0 507 int main(const unsigned argc, char* const argv[]){
mas01cr@0 508 audioDB(argc, argv);
mas01cr@0 509 }