annotate audioDB.cpp @ 279:dee55886eca0 sampling

make the RNG a part of the audioDB object. Easier to deal with memory discipline and initialization (though note the FIXME comment in audioDB::initTables()). Also initialize the RNG from the current time. A mature implementation would use a proper source of entropy...
author mas01cr
date Wed, 02 Jul 2008 13:53:23 +0000
parents 1c76d5f41708
children
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@266 40
mas01cr@266 41 else if(O2_ACTION(COM_SAMPLE))
mas01cr@266 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@279 100 if(rng)
mas01cr@279 101 gsl_rng_free(rng);
mas01cr@279 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@266 219 if(args_info.SAMPLE_given) {
mas01cr@266 220 command = COM_SAMPLE;
mas01cr@266 221 dbName = args_info.database_arg;
mas01cr@267 222 sequenceLength = args_info.sequencelength_arg;
mas01cr@267 223 if(sequenceLength < 1 || sequenceLength > 1000) {
mas01cr@267 224 error("seqlen out of range: 1 <= seqlen <= 1000");
mas01cr@267 225 }
mas01cr@274 226 nsamples = args_info.nsamples_arg;
mas01cr@266 227 return 0;
mas01cr@266 228 }
mas01cr@266 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 }