annotate audioDB.cpp @ 249:1da9a9ed55a3

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