Mercurial > hg > audiodb
view l2norm.cpp @ 402:58b88ab69424 api-inversion
Move the struct adb definition from the auidioDB_API.h into the
audioDB-internals.h header file, leaving only the typedef behind.
Thus a user of the API sees only an incomplete type, which cannot be
instantiated (but /pointers/ to it can); there's then less temptation to
break the abstraction barrier by using structure fields in client code.
Not only that, but we can now safely put C++ stuff in the structure.
Take advantage of this by putting a std::set<std::string> in there, to
hold all the keys currently in the database; populate this field on
audiodb_open() (and delete it on audiodb_close). This will be useful
when we come to implement variants of audiodb_insert().
author | mas01cr |
---|---|
date | Wed, 03 Dec 2008 17:40:15 +0000 |
parents | a8a5f2ca5380 |
children | 7038f31124d1 |
line wrap: on
line source
#include "audioDB.h" extern "C" { #include "audioDB_API.h" #include "audioDB-internals.h" } static int audiodb_l2norm_existing(adb_t *adb) { double *data_buffer, *l2norm_buffer; double *dp, *lp; adb_header_t *header = adb->header; size_t data_buffer_size = ALIGN_PAGE_UP(header->length); size_t nvectors = header->length / (sizeof(double) * header->dim); /* FIXME: this map of the vector data will lose if we ever turn the * l2norm flag on when we have already inserted a large number of * vectors, as the mmap() will fail. "Don't do that, then" is one * possible answer. */ mmap_or_goto_error(double *, data_buffer, header->dataOffset, data_buffer_size); l2norm_buffer = (double *) malloc(nvectors * sizeof(double)); if(!l2norm_buffer) { goto error; } dp = data_buffer; lp = l2norm_buffer; for(size_t i = 0; i < nvectors; i++) { *lp = 0; for(unsigned int k = 0; k < header->dim; k++) { *lp += (*dp)*(*dp); dp++; } lp++; } if(lseek(adb->fd, adb->header->l2normTableOffset, SEEK_SET) == (off_t) -1) { goto error; } if(write(adb->fd, l2norm_buffer, nvectors * sizeof(double)) != (ssize_t) (nvectors * sizeof(double))) { goto error; } munmap(data_buffer, data_buffer_size); free(l2norm_buffer); return 0; error: maybe_munmap(data_buffer, data_buffer_size); if(l2norm_buffer) { free(l2norm_buffer); } return 1; } int audiodb_l2norm(adb_t *adb) { adb_header_t *header = adb->header; if(header->flags & O2_FLAG_L2NORM) { /* non-error code for forthcoming backwards-compatibility * reasons */ return 0; } if((!(header->flags & O2_FLAG_LARGE_ADB)) && (header->length > 0)) { if(audiodb_l2norm_existing(adb)) { goto error; } } adb->header->flags |= O2_FLAG_L2NORM; return audiodb_sync_header(adb); error: return 1; }