comparison query.cpp @ 461:2b8cfec91ed7 api-inversion

Factor out some bits of audiodb_query_spec_qpointers() New functions audiodb_track_id_datum() and audiodb_datum_qpointers() will be useful in places where audioDB::init_track_aux_data is currently being called. We should be able to simplify audioDB::query_loop_points quite a lot this way...
author mas01cr
date Tue, 30 Dec 2008 15:38:50 +0000
parents 17003dff8127
children f689510baaf4
comparison
equal deleted inserted replaced
460:17003dff8127 461:2b8cfec91ed7
397 if (!timesFile->eof()) { 397 if (!timesFile->eof()) {
398 error("too many timepoints in times file", timesFileName); 398 error("too many timepoints in times file", timesFileName);
399 } 399 }
400 } 400 }
401 401
402 int audiodb_track_id_datum(adb_t *adb, uint32_t track_id, adb_datum_t *d) {
403 off_t track_offset = (*adb->track_offsets)[track_id];
404 if(adb->header->flags & O2_FLAG_LARGE_ADB) {
405 /* create a reference/insert, then use adb_insert_create_datum() */
406 adb_reference_t reference = {0};
407 char features[MAXSTR], power[MAXSTR], times[MAXSTR];
408 lseek(adb->fd, adb->header->dataOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET);
409 /* FIXME: learn not to worry and love the bomb^Wbuffer overflow */
410 read(adb->fd, features, MAXSTR);
411 reference.features = features;
412 if(adb->header->flags & O2_FLAG_POWER) {
413 lseek(adb->fd, adb->header->powerTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET);
414 read(adb->fd, power, MAXSTR);
415 reference.power = power;
416 }
417 if(adb->header->flags & O2_FLAG_TIMES) {
418 lseek(adb->fd, adb->header->timesTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET);
419 read(adb->fd, times, MAXSTR);
420 reference.times = times;
421 }
422 audiodb_insert_create_datum(&reference, d);
423 } else {
424 /* initialize from sources of data that we already have */
425 d->nvectors = (*adb->track_lengths)[track_id];
426 d->dim = adb->header->dim;
427 d->key = (*adb->keys)[track_id].c_str();
428 /* read out stuff from the database tables */
429 d->data = (double *) malloc(d->nvectors * d->dim * sizeof(double));
430 lseek(adb->fd, adb->header->dataOffset + track_offset, SEEK_SET);
431 read(adb->fd, d->data, d->nvectors * d->dim * sizeof(double));
432 if(adb->header->flags & O2_FLAG_POWER) {
433 d->power = (double *) malloc(d->nvectors * sizeof(double));
434 lseek(adb->fd, adb->header->powerTableOffset + track_offset / d->dim, SEEK_SET);
435 read(adb->fd, d->power, d->nvectors * sizeof(double));
436 }
437 if(adb->header->flags & O2_FLAG_TIMES) {
438 d->times = (double *) malloc(2 * d->nvectors * sizeof(double));
439 lseek(adb->fd, adb->header->timesTableOffset + track_offset / d->dim, SEEK_SET);
440 read(adb->fd, d->times, 2 * d->nvectors * sizeof(double));
441 }
442 }
443 return 0;
444 }
445
446 int audiodb_datum_qpointers(adb_datum_t *d, uint32_t sequence_length, double **vector_data, double **vector, adb_qpointers_internal_t *qpointers) {
447 uint32_t nvectors = d->nvectors;
448
449 qpointers->nvectors = nvectors;
450
451 size_t vector_size = nvectors * sizeof(double) * d->dim;
452 *vector_data = new double[vector_size];
453 memcpy(*vector_data, d->data, vector_size);
454
455 qpointers->l2norm_data = new double[vector_size / d->dim];
456 audiodb_l2norm_buffer(*vector_data, d->dim, nvectors, qpointers->l2norm_data);
457 audiodb_sequence_sum(qpointers->l2norm_data, nvectors, sequence_length);
458 audiodb_sequence_sqrt(qpointers->l2norm_data, nvectors, sequence_length);
459
460 if(d->power) {
461 qpointers->power_data = new double[vector_size / d->dim];
462 memcpy(qpointers->power_data, d->power, vector_size / d->dim);
463 audiodb_sequence_sum(qpointers->power_data, nvectors, sequence_length);
464 audiodb_sequence_average(qpointers->power_data, nvectors, sequence_length);
465 }
466
467 if(d->times) {
468 qpointers->mean_duration = new double[1];
469 *qpointers->mean_duration = 0;
470 for(unsigned int k = 0; k < nvectors; k++) {
471 *qpointers->mean_duration += d->times[2*k+1] - d->times[2*k];
472 }
473 *qpointers->mean_duration /= nvectors;
474 }
475
476 *vector = *vector_data;
477 qpointers->l2norm = qpointers->l2norm_data;
478 qpointers->power = qpointers->power_data;
479 return 0;
480 }
481
402 int audiodb_query_spec_qpointers(adb_t *adb, adb_query_spec_t *spec, double **vector_data, double **vector, adb_qpointers_internal_t *qpointers) { 482 int audiodb_query_spec_qpointers(adb_t *adb, adb_query_spec_t *spec, double **vector_data, double **vector, adb_qpointers_internal_t *qpointers) {
403 adb_datum_t *datum; 483 adb_datum_t *datum;
404 adb_datum_t d = {0}; 484 adb_datum_t d = {0};
405 uint32_t nvectors;
406 uint32_t sequence_length; 485 uint32_t sequence_length;
407 uint32_t sequence_start; 486 uint32_t sequence_start;
408 487
409 datum = spec->qid.datum; 488 datum = spec->qid.datum;
410 sequence_length = spec->qid.sequence_length; 489 sequence_length = spec->qid.sequence_length;
420 } else if (datum->key) { 499 } else if (datum->key) {
421 uint32_t track_id; 500 uint32_t track_id;
422 if((track_id = audiodb_key_index(adb, datum->key)) == (uint32_t) -1) { 501 if((track_id = audiodb_key_index(adb, datum->key)) == (uint32_t) -1) {
423 return 1; 502 return 1;
424 } 503 }
425 off_t track_offset = (*adb->track_offsets)[track_id]; 504 audiodb_track_id_datum(adb, track_id, &d);
426
427 if(adb->header->flags & O2_FLAG_LARGE_ADB) {
428 /* create a reference/insert, then use adb_insert_create_datum() */
429 adb_reference_t reference = {0};
430 char features[MAXSTR], power[MAXSTR], times[MAXSTR];
431 lseek(adb->fd, adb->header->dataOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET);
432 /* FIXME: learn not to worry and love the bomb^Wbuffer overflow */
433 read(adb->fd, features, MAXSTR);
434 reference.features = features;
435 if(adb->header->flags & O2_FLAG_POWER) {
436 lseek(adb->fd, adb->header->powerTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET);
437 read(adb->fd, power, MAXSTR);
438 reference.power = power;
439 }
440 if(adb->header->flags & O2_FLAG_TIMES) {
441 lseek(adb->fd, adb->header->timesTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET);
442 read(adb->fd, times, MAXSTR);
443 reference.times = times;
444 }
445 audiodb_insert_create_datum(&reference, &d);
446 } else {
447 /* initialize from sources of data that we already have */
448 d.nvectors = (*adb->track_lengths)[track_id];
449 d.dim = adb->header->dim;
450 d.key = datum->key;
451 /* read out stuff from the database tables */
452 d.data = (double *) malloc(d.nvectors * d.dim * sizeof(double));
453 lseek(adb->fd, adb->header->dataOffset + track_offset, SEEK_SET);
454 read(adb->fd, d.data, d.nvectors * d.dim * sizeof(double));
455 if(adb->header->flags & O2_FLAG_POWER) {
456 d.power = (double *) malloc(d.nvectors * sizeof(double));
457 lseek(adb->fd, adb->header->powerTableOffset + track_offset / d.dim, SEEK_SET);
458 read(adb->fd, d.power, d.nvectors * sizeof(double));
459 }
460 if(adb->header->flags & O2_FLAG_TIMES) {
461 d.times = (double *) malloc(2 * d.nvectors * sizeof(double));
462 lseek(adb->fd, adb->header->timesTableOffset + track_offset / d.dim, SEEK_SET);
463 read(adb->fd, d.times, 2 * d.nvectors * sizeof(double));
464 }
465 }
466 } else { 505 } else {
467 return 1; 506 return 1;
468 } 507 }
469 508
470 /* Now we have a full(ish) datum, compute all the qpointery stuff
471 that we care about (l2norm/power/mean duration). (This bit could
472 conceivably become a new function) */
473 nvectors = d.nvectors;
474 /* FIXME: check the overflow logic here */ 509 /* FIXME: check the overflow logic here */
475 if(sequence_start + sequence_length > nvectors) { 510 if(sequence_start + sequence_length > d.nvectors) {
476 /* is there something to free? goto error */ 511 if(datum != &d) {
512 audiodb_free_datum(&d);
513 }
477 return 1; 514 return 1;
478 } 515 }
479 516
480 qpointers->nvectors = nvectors; 517 audiodb_datum_qpointers(&d, sequence_length, vector_data, vector, qpointers);
481 518
482 size_t vector_size = nvectors * sizeof(double) * d.dim; 519 /* Finally, if applicable, set up the moving qpointers. */
483 *vector_data = new double[vector_size];
484 memcpy(*vector_data, d.data, vector_size);
485
486 qpointers->l2norm_data = new double[vector_size / d.dim];
487 audiodb_l2norm_buffer(*vector_data, d.dim, nvectors, qpointers->l2norm_data);
488 audiodb_sequence_sum(qpointers->l2norm_data, nvectors, sequence_length);
489 audiodb_sequence_sqrt(qpointers->l2norm_data, nvectors, sequence_length);
490
491 if(d.power) {
492 qpointers->power_data = new double[vector_size / d.dim];
493 memcpy(qpointers->power_data, d.power, vector_size / d.dim);
494 audiodb_sequence_sum(qpointers->power_data, nvectors, sequence_length);
495 audiodb_sequence_average(qpointers->power_data, nvectors, sequence_length);
496 }
497
498 if(d.times) {
499 qpointers->mean_duration = new double[1];
500 *qpointers->mean_duration = 0;
501 for(unsigned int k = 0; k < nvectors; k++) {
502 *qpointers->mean_duration += d.times[2*k+1] - d.times[2*k];
503 }
504 *qpointers->mean_duration /= nvectors;
505 }
506
507
508 /* Finally, set up the moving qpointers. */
509 if(spec->qid.flags & ADB_QUERY_ID_FLAG_EXHAUSTIVE) { 520 if(spec->qid.flags & ADB_QUERY_ID_FLAG_EXHAUSTIVE) {
510 *vector = *vector_data; 521 /* the qpointers are already at the start, and so correct. */
511 qpointers->l2norm = qpointers->l2norm_data;
512 qpointers->power = qpointers->power_data;
513 } else { 522 } else {
523 /* adjust the qpointers to point to the correct place in the sequence */
514 *vector = *vector_data + spec->qid.sequence_start * d.dim; 524 *vector = *vector_data + spec->qid.sequence_start * d.dim;
515 qpointers->l2norm = qpointers->l2norm_data + spec->qid.sequence_start; 525 qpointers->l2norm = qpointers->l2norm_data + spec->qid.sequence_start;
516 if(d.power) { 526 if(d.power) {
517 qpointers->power = qpointers->power_data + spec->qid.sequence_start; 527 qpointers->power = qpointers->power_data + spec->qid.sequence_start;
518 } 528 }
519 /* FIXME: this is a little bit ugly. No, a lot ugly. But at the
520 * moment this is how query_loop() knows when to stop, so for
521 * now... */
522 qpointers->nvectors = sequence_length; 529 qpointers->nvectors = sequence_length;
523 } 530 }
524 531
525 /* Clean up: free any bits of datum that we have ourselves 532 /* Clean up: free any bits of datum that we have ourselves
526 * allocated. */ 533 * allocated. */