Mercurial > hg > audiodb
changeset 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 |
files | audioDB-internals.h query.cpp |
diffstat | 2 files changed, 91 insertions(+), 83 deletions(-) [+] |
line wrap: on
line diff
--- a/audioDB-internals.h Tue Dec 30 10:36:01 2008 +0000 +++ b/audioDB-internals.h Tue Dec 30 15:38:50 2008 +0000 @@ -202,7 +202,6 @@ } } -/************************* LSH point index to audioDB conversion *****************/ static inline uint32_t audiodb_index_to_track_id(uint32_t lshid, uint32_t n_point_bits) { return (lshid >> n_point_bits); } @@ -222,7 +221,9 @@ int audiodb_read_data(adb_t *, int, int, double **, size_t *); int audiodb_insert_create_datum(adb_insert_t *, adb_datum_t *); +int audiodb_track_id_datum(adb_t *, uint32_t, adb_datum_t *); int audiodb_free_datum(adb_datum_t *); +int audiodb_datum_qpointers(adb_datum_t *, uint32_t, double **, double **, adb_qpointers_internal_t *); int audiodb_query_spec_qpointers(adb_t *, adb_query_spec_t *, double **, double **, adb_qpointers_internal_t *); char *audiodb_index_get_name(const char *, double, uint32_t); bool audiodb_index_exists(const char *, double, uint32_t);
--- a/query.cpp Tue Dec 30 10:36:01 2008 +0000 +++ b/query.cpp Tue Dec 30 15:38:50 2008 +0000 @@ -399,10 +399,89 @@ } } +int audiodb_track_id_datum(adb_t *adb, uint32_t track_id, adb_datum_t *d) { + off_t track_offset = (*adb->track_offsets)[track_id]; + if(adb->header->flags & O2_FLAG_LARGE_ADB) { + /* create a reference/insert, then use adb_insert_create_datum() */ + adb_reference_t reference = {0}; + char features[MAXSTR], power[MAXSTR], times[MAXSTR]; + lseek(adb->fd, adb->header->dataOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); + /* FIXME: learn not to worry and love the bomb^Wbuffer overflow */ + read(adb->fd, features, MAXSTR); + reference.features = features; + if(adb->header->flags & O2_FLAG_POWER) { + lseek(adb->fd, adb->header->powerTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); + read(adb->fd, power, MAXSTR); + reference.power = power; + } + if(adb->header->flags & O2_FLAG_TIMES) { + lseek(adb->fd, adb->header->timesTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); + read(adb->fd, times, MAXSTR); + reference.times = times; + } + audiodb_insert_create_datum(&reference, d); + } else { + /* initialize from sources of data that we already have */ + d->nvectors = (*adb->track_lengths)[track_id]; + d->dim = adb->header->dim; + d->key = (*adb->keys)[track_id].c_str(); + /* read out stuff from the database tables */ + d->data = (double *) malloc(d->nvectors * d->dim * sizeof(double)); + lseek(adb->fd, adb->header->dataOffset + track_offset, SEEK_SET); + read(adb->fd, d->data, d->nvectors * d->dim * sizeof(double)); + if(adb->header->flags & O2_FLAG_POWER) { + d->power = (double *) malloc(d->nvectors * sizeof(double)); + lseek(adb->fd, adb->header->powerTableOffset + track_offset / d->dim, SEEK_SET); + read(adb->fd, d->power, d->nvectors * sizeof(double)); + } + if(adb->header->flags & O2_FLAG_TIMES) { + d->times = (double *) malloc(2 * d->nvectors * sizeof(double)); + lseek(adb->fd, adb->header->timesTableOffset + track_offset / d->dim, SEEK_SET); + read(adb->fd, d->times, 2 * d->nvectors * sizeof(double)); + } + } + return 0; +} + +int audiodb_datum_qpointers(adb_datum_t *d, uint32_t sequence_length, double **vector_data, double **vector, adb_qpointers_internal_t *qpointers) { + uint32_t nvectors = d->nvectors; + + qpointers->nvectors = nvectors; + + size_t vector_size = nvectors * sizeof(double) * d->dim; + *vector_data = new double[vector_size]; + memcpy(*vector_data, d->data, vector_size); + + qpointers->l2norm_data = new double[vector_size / d->dim]; + audiodb_l2norm_buffer(*vector_data, d->dim, nvectors, qpointers->l2norm_data); + audiodb_sequence_sum(qpointers->l2norm_data, nvectors, sequence_length); + audiodb_sequence_sqrt(qpointers->l2norm_data, nvectors, sequence_length); + + if(d->power) { + qpointers->power_data = new double[vector_size / d->dim]; + memcpy(qpointers->power_data, d->power, vector_size / d->dim); + audiodb_sequence_sum(qpointers->power_data, nvectors, sequence_length); + audiodb_sequence_average(qpointers->power_data, nvectors, sequence_length); + } + + if(d->times) { + qpointers->mean_duration = new double[1]; + *qpointers->mean_duration = 0; + for(unsigned int k = 0; k < nvectors; k++) { + *qpointers->mean_duration += d->times[2*k+1] - d->times[2*k]; + } + *qpointers->mean_duration /= nvectors; + } + + *vector = *vector_data; + qpointers->l2norm = qpointers->l2norm_data; + qpointers->power = qpointers->power_data; + return 0; +} + int audiodb_query_spec_qpointers(adb_t *adb, adb_query_spec_t *spec, double **vector_data, double **vector, adb_qpointers_internal_t *qpointers) { adb_datum_t *datum; adb_datum_t d = {0}; - uint32_t nvectors; uint32_t sequence_length; uint32_t sequence_start; @@ -422,103 +501,31 @@ if((track_id = audiodb_key_index(adb, datum->key)) == (uint32_t) -1) { return 1; } - off_t track_offset = (*adb->track_offsets)[track_id]; - - if(adb->header->flags & O2_FLAG_LARGE_ADB) { - /* create a reference/insert, then use adb_insert_create_datum() */ - adb_reference_t reference = {0}; - char features[MAXSTR], power[MAXSTR], times[MAXSTR]; - lseek(adb->fd, adb->header->dataOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); - /* FIXME: learn not to worry and love the bomb^Wbuffer overflow */ - read(adb->fd, features, MAXSTR); - reference.features = features; - if(adb->header->flags & O2_FLAG_POWER) { - lseek(adb->fd, adb->header->powerTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); - read(adb->fd, power, MAXSTR); - reference.power = power; - } - if(adb->header->flags & O2_FLAG_TIMES) { - lseek(adb->fd, adb->header->timesTableOffset + track_id * O2_FILETABLE_ENTRY_SIZE, SEEK_SET); - read(adb->fd, times, MAXSTR); - reference.times = times; - } - audiodb_insert_create_datum(&reference, &d); - } else { - /* initialize from sources of data that we already have */ - d.nvectors = (*adb->track_lengths)[track_id]; - d.dim = adb->header->dim; - d.key = datum->key; - /* read out stuff from the database tables */ - d.data = (double *) malloc(d.nvectors * d.dim * sizeof(double)); - lseek(adb->fd, adb->header->dataOffset + track_offset, SEEK_SET); - read(adb->fd, d.data, d.nvectors * d.dim * sizeof(double)); - if(adb->header->flags & O2_FLAG_POWER) { - d.power = (double *) malloc(d.nvectors * sizeof(double)); - lseek(adb->fd, adb->header->powerTableOffset + track_offset / d.dim, SEEK_SET); - read(adb->fd, d.power, d.nvectors * sizeof(double)); - } - if(adb->header->flags & O2_FLAG_TIMES) { - d.times = (double *) malloc(2 * d.nvectors * sizeof(double)); - lseek(adb->fd, adb->header->timesTableOffset + track_offset / d.dim, SEEK_SET); - read(adb->fd, d.times, 2 * d.nvectors * sizeof(double)); - } - } + audiodb_track_id_datum(adb, track_id, &d); } else { return 1; } - /* Now we have a full(ish) datum, compute all the qpointery stuff - that we care about (l2norm/power/mean duration). (This bit could - conceivably become a new function) */ - nvectors = d.nvectors; /* FIXME: check the overflow logic here */ - if(sequence_start + sequence_length > nvectors) { - /* is there something to free? goto error */ + if(sequence_start + sequence_length > d.nvectors) { + if(datum != &d) { + audiodb_free_datum(&d); + } return 1; } - qpointers->nvectors = nvectors; + audiodb_datum_qpointers(&d, sequence_length, vector_data, vector, qpointers); - size_t vector_size = nvectors * sizeof(double) * d.dim; - *vector_data = new double[vector_size]; - memcpy(*vector_data, d.data, vector_size); - - qpointers->l2norm_data = new double[vector_size / d.dim]; - audiodb_l2norm_buffer(*vector_data, d.dim, nvectors, qpointers->l2norm_data); - audiodb_sequence_sum(qpointers->l2norm_data, nvectors, sequence_length); - audiodb_sequence_sqrt(qpointers->l2norm_data, nvectors, sequence_length); - - if(d.power) { - qpointers->power_data = new double[vector_size / d.dim]; - memcpy(qpointers->power_data, d.power, vector_size / d.dim); - audiodb_sequence_sum(qpointers->power_data, nvectors, sequence_length); - audiodb_sequence_average(qpointers->power_data, nvectors, sequence_length); - } - - if(d.times) { - qpointers->mean_duration = new double[1]; - *qpointers->mean_duration = 0; - for(unsigned int k = 0; k < nvectors; k++) { - *qpointers->mean_duration += d.times[2*k+1] - d.times[2*k]; - } - *qpointers->mean_duration /= nvectors; - } - - - /* Finally, set up the moving qpointers. */ + /* Finally, if applicable, set up the moving qpointers. */ if(spec->qid.flags & ADB_QUERY_ID_FLAG_EXHAUSTIVE) { - *vector = *vector_data; - qpointers->l2norm = qpointers->l2norm_data; - qpointers->power = qpointers->power_data; + /* the qpointers are already at the start, and so correct. */ } else { + /* adjust the qpointers to point to the correct place in the sequence */ *vector = *vector_data + spec->qid.sequence_start * d.dim; qpointers->l2norm = qpointers->l2norm_data + spec->qid.sequence_start; if(d.power) { qpointers->power = qpointers->power_data + spec->qid.sequence_start; } - /* FIXME: this is a little bit ugly. No, a lot ugly. But at the - * moment this is how query_loop() knows when to stop, so for - * now... */ qpointers->nvectors = sequence_length; }