Mercurial > hg > audiodb
view audioDB-internals.h @ 442:16c5c51a4c32 api-inversion
Add more information to adb_t
In this case, add a vector to store track offsets.
WARNING WARNING WARNING: unlike trackOffsetTable, this is a raw off_t in
bytes of the feature data: in other words, it already has sizeof(double)
and dbH->dim in it. (I think this is probably minimally unsurprising in
the long run, but as I convert stuff there might well be errors creeping
in...)
author | mas01cr |
---|---|
date | Wed, 24 Dec 2008 10:56:29 +0000 |
parents | 681837f7c903 |
children | cb44e57a96fa |
line wrap: on
line source
typedef struct adb_datum_internal { uint32_t nvectors; uint32_t dim; const char *key; void *data; void *times; void *power; } adb_datum_internal_t; struct adb { char *path; int fd; int flags; adb_header_t *header; std::map<std::string,uint32_t> *keys; std::vector<uint32_t> *track_lengths; std::vector<off_t> *track_offsets; }; typedef struct { bool operator() (const adb_result_t &r1, const adb_result_t &r2) { return strcmp(r1.key, r2.key) < 0; } } adb_result_key_lt; typedef struct { bool operator() (const adb_result_t &r1, const adb_result_t &r2) { return r1.qpos < r2.qpos; } } adb_result_qpos_lt; typedef struct { bool operator() (const adb_result_t &r1, const adb_result_t &r2) { return r1.dist < r2.dist; } } adb_result_dist_lt; typedef struct { bool operator() (const adb_result_t &r1, const adb_result_t &r2) { return r1.dist > r2.dist; } } adb_result_dist_gt; typedef struct { bool operator() (const adb_result_t &r1, const adb_result_t &r2) { return ((r1.ipos < r2.ipos) || ((r1.ipos == r2.ipos) && ((r1.qpos < r2.qpos) || ((r1.qpos == r2.qpos) && (strcmp(r1.key, r2.key) < 0))))); } } adb_result_triple_lt; /* We could go gcc-specific here and use typeof() instead of passing * in an explicit type. Answers on a postcard as to whether that's a * good plan or not. */ #define mmap_or_goto_error(type, var, start, length) \ { void *tmp = mmap(0, length, PROT_READ, MAP_SHARED, adb->fd, (start)); \ if(tmp == (void *) -1) { \ goto error; \ } \ var = (type) tmp; \ } #define maybe_munmap(table, length) \ { if(table) { \ munmap(table, length); \ } \ } #define write_or_goto_error(fd, buffer, size) \ { ssize_t tmp = size; \ if(write(fd, buffer, size) != tmp) { \ goto error; \ } \ } #define read_or_goto_error(fd, buffer, size) \ { ssize_t tmp = size; \ if(read(fd, buffer, size) != tmp) { \ goto error; \ } \ } static inline int audiodb_sync_header(adb_t *adb) { off_t pos; pos = lseek(adb->fd, (off_t) 0, SEEK_CUR); if(pos == (off_t) -1) { goto error; } if(lseek(adb->fd, (off_t) 0, SEEK_SET) == (off_t) -1) { goto error; } if(write(adb->fd, adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) { goto error; } /* can be fsync() if fdatasync() is racily exciting and new */ fdatasync(adb->fd); if(lseek(adb->fd, pos, SEEK_SET) == (off_t) -1) { goto error; } return 0; error: return 1; } static inline double audiodb_dot_product(double *p, double *q, size_t count) { double result = 0; while(count--) { result += *p++ * *q++; } return result; } static inline void audiodb_l2norm_buffer(double *d, size_t dim, size_t nvectors, double *l) { while(nvectors--) { double *d1 = d; double *d2 = d; *l++ = audiodb_dot_product(d1, d2, dim); d += dim; } } // This is a common pattern in sequence queries: what we are doing is // taking a window of length seqlen over a buffer of length length, // and placing the sum of the elements in that window in the first // element of the window: thus replacing all but the last seqlen // elements in the buffer with the corresponding windowed sum. static inline void audiodb_sequence_sum(double *buffer, int length, int seqlen) { double tmp1, tmp2, *ps; int j, w; tmp1 = *buffer; j = 1; w = seqlen - 1; while(w--) { *buffer += buffer[j++]; } ps = buffer + 1; w = length - seqlen; // +1 - 1 while(w--) { tmp2 = *ps; if(isfinite(tmp1)) { *ps = *(ps - 1) - tmp1 + *(ps + seqlen - 1); } else { for(int i = 1; i < seqlen; i++) { *ps += *(ps + i); } } tmp1 = tmp2; ps++; } } // In contrast to audiodb_sequence_sum() above, // audiodb_sequence_sqrt() and audiodb_sequence_average() below are // simple mappers across the sequence. static inline void audiodb_sequence_sqrt(double *buffer, int length, int seqlen) { int w = length - seqlen + 1; while(w--) { *buffer = sqrt(*buffer); buffer++; } } static inline void audiodb_sequence_average(double *buffer, int length, int seqlen) { int w = length - seqlen + 1; while(w--) { *buffer /= seqlen; buffer++; } } static inline uint32_t audiodb_key_index(adb_t *adb, const char *key) { std::map<std::string,uint32_t>::iterator it; it = adb->keys->find(key); if(it == adb->keys->end()) { return (uint32_t) -1; } else { return (*it).second; } } int audiodb_read_data(adb_t *, int, int, double **, size_t *);