annotate l2norm.cpp @ 403:7038f31124d1 api-inversion

Better error-checking for operations which write to the database. When I said /* FIXME: we should probably include... */ it hadn't occurred to me that I had already included the relevant "..." (in this case, the flags field in struct adb, which does contain the O_RDONLY / O_RDWR flag which was used to open the database). Sometimes I am pleasantly surprised with my foresight.
author mas01cr
date Wed, 03 Dec 2008 17:40:17 +0000
parents a8a5f2ca5380
children d7e590d58c85
rev   line source
mas01cr@401 1 #include "audioDB.h"
mas01cr@401 2 extern "C" {
mas01cr@401 3 #include "audioDB_API.h"
mas01cr@401 4 #include "audioDB-internals.h"
mas01cr@401 5 }
mas01cr@401 6
mas01cr@401 7 static int audiodb_l2norm_existing(adb_t *adb) {
mas01cr@401 8 double *data_buffer, *l2norm_buffer;
mas01cr@401 9 double *dp, *lp;
mas01cr@401 10 adb_header_t *header = adb->header;
mas01cr@401 11 size_t data_buffer_size = ALIGN_PAGE_UP(header->length);
mas01cr@401 12 size_t nvectors = header->length / (sizeof(double) * header->dim);
mas01cr@401 13 /* FIXME: this map of the vector data will lose if we ever turn the
mas01cr@401 14 * l2norm flag on when we have already inserted a large number of
mas01cr@401 15 * vectors, as the mmap() will fail. "Don't do that, then" is one
mas01cr@401 16 * possible answer. */
mas01cr@401 17 mmap_or_goto_error(double *, data_buffer, header->dataOffset, data_buffer_size);
mas01cr@401 18 l2norm_buffer = (double *) malloc(nvectors * sizeof(double));
mas01cr@401 19 if(!l2norm_buffer) {
mas01cr@401 20 goto error;
mas01cr@401 21 }
mas01cr@401 22
mas01cr@401 23 dp = data_buffer;
mas01cr@401 24 lp = l2norm_buffer;
mas01cr@401 25 for(size_t i = 0; i < nvectors; i++) {
mas01cr@401 26 *lp = 0;
mas01cr@401 27 for(unsigned int k = 0; k < header->dim; k++) {
mas01cr@401 28 *lp += (*dp)*(*dp);
mas01cr@401 29 dp++;
mas01cr@401 30 }
mas01cr@401 31 lp++;
mas01cr@401 32 }
mas01cr@401 33
mas01cr@401 34 if(lseek(adb->fd, adb->header->l2normTableOffset, SEEK_SET) == (off_t) -1) {
mas01cr@401 35 goto error;
mas01cr@401 36 }
mas01cr@401 37 if(write(adb->fd, l2norm_buffer, nvectors * sizeof(double)) != (ssize_t) (nvectors * sizeof(double))) {
mas01cr@401 38 goto error;
mas01cr@401 39 }
mas01cr@401 40
mas01cr@401 41 munmap(data_buffer, data_buffer_size);
mas01cr@401 42 free(l2norm_buffer);
mas01cr@401 43
mas01cr@401 44 return 0;
mas01cr@401 45
mas01cr@401 46 error:
mas01cr@401 47 maybe_munmap(data_buffer, data_buffer_size);
mas01cr@401 48 if(l2norm_buffer) {
mas01cr@401 49 free(l2norm_buffer);
mas01cr@401 50 }
mas01cr@401 51 return 1;
mas01cr@401 52 }
mas01cr@401 53
mas01cr@401 54 int audiodb_l2norm(adb_t *adb) {
mas01cr@401 55 adb_header_t *header = adb->header;
mas01cr@403 56 if(!(adb->flags & O_RDWR)) {
mas01cr@403 57 return 1;
mas01cr@403 58 }
mas01cr@401 59 if(header->flags & O2_FLAG_L2NORM) {
mas01cr@401 60 /* non-error code for forthcoming backwards-compatibility
mas01cr@401 61 * reasons */
mas01cr@401 62 return 0;
mas01cr@401 63 }
mas01cr@401 64 if((!(header->flags & O2_FLAG_LARGE_ADB)) && (header->length > 0)) {
mas01cr@401 65 if(audiodb_l2norm_existing(adb)) {
mas01cr@401 66 goto error;
mas01cr@401 67 }
mas01cr@401 68 }
mas01cr@401 69 adb->header->flags |= O2_FLAG_L2NORM;
mas01cr@401 70 return audiodb_sync_header(adb);
mas01cr@401 71
mas01cr@401 72 error:
mas01cr@401 73 return 1;
mas01cr@401 74 }