annotate 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
rev   line source
mas01cr@408 1 typedef struct adb_datum_internal {
mas01cr@408 2 uint32_t nvectors;
mas01cr@408 3 uint32_t dim;
mas01cr@408 4 const char *key;
mas01cr@408 5 void *data;
mas01cr@408 6 void *times;
mas01cr@408 7 void *power;
mas01cr@408 8 } adb_datum_internal_t;
mas01cr@408 9
mas01cr@402 10 struct adb {
mas01cr@402 11 char *path;
mas01cr@402 12 int fd;
mas01cr@402 13 int flags;
mas01cr@402 14 adb_header_t *header;
mas01cr@430 15 std::map<std::string,uint32_t> *keys;
mas01cr@432 16 std::vector<uint32_t> *track_lengths;
mas01cr@442 17 std::vector<off_t> *track_offsets;
mas01cr@402 18 };
mas01cr@402 19
mas01cr@416 20 typedef struct {
mas01cr@416 21 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 22 return strcmp(r1.key, r2.key) < 0;
mas01cr@416 23 }
mas01cr@416 24 } adb_result_key_lt;
mas01cr@416 25
mas01cr@416 26 typedef struct {
mas01cr@416 27 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 28 return r1.qpos < r2.qpos;
mas01cr@416 29 }
mas01cr@416 30 } adb_result_qpos_lt;
mas01cr@416 31
mas01cr@416 32 typedef struct {
mas01cr@416 33 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 34 return r1.dist < r2.dist;
mas01cr@416 35 }
mas01cr@416 36 } adb_result_dist_lt;
mas01cr@416 37
mas01cr@416 38 typedef struct {
mas01cr@416 39 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 40 return r1.dist > r2.dist;
mas01cr@416 41 }
mas01cr@416 42 } adb_result_dist_gt;
mas01cr@416 43
mas01cr@416 44 typedef struct {
mas01cr@416 45 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 46 return ((r1.ipos < r2.ipos) ||
mas01cr@416 47 ((r1.ipos == r2.ipos) &&
mas01cr@416 48 ((r1.qpos < r2.qpos) ||
mas01cr@416 49 ((r1.qpos == r2.qpos) && (strcmp(r1.key, r2.key) < 0)))));
mas01cr@416 50 }
mas01cr@416 51 } adb_result_triple_lt;
mas01cr@416 52
mas01cr@401 53 /* We could go gcc-specific here and use typeof() instead of passing
mas01cr@401 54 * in an explicit type. Answers on a postcard as to whether that's a
mas01cr@401 55 * good plan or not. */
mas01cr@401 56 #define mmap_or_goto_error(type, var, start, length) \
mas01cr@401 57 { void *tmp = mmap(0, length, PROT_READ, MAP_SHARED, adb->fd, (start)); \
mas01cr@401 58 if(tmp == (void *) -1) { \
mas01cr@401 59 goto error; \
mas01cr@401 60 } \
mas01cr@401 61 var = (type) tmp; \
mas01cr@401 62 }
mas01cr@401 63
mas01cr@401 64 #define maybe_munmap(table, length) \
mas01cr@401 65 { if(table) { \
mas01cr@401 66 munmap(table, length); \
mas01cr@401 67 } \
mas01cr@401 68 }
mas01cr@401 69
mas01cr@410 70 #define write_or_goto_error(fd, buffer, size) \
mas01cr@410 71 { ssize_t tmp = size; \
mas01cr@410 72 if(write(fd, buffer, size) != tmp) { \
mas01cr@410 73 goto error; \
mas01cr@410 74 } \
mas01cr@410 75 }
mas01cr@410 76
mas01cr@410 77 #define read_or_goto_error(fd, buffer, size) \
mas01cr@410 78 { ssize_t tmp = size; \
mas01cr@410 79 if(read(fd, buffer, size) != tmp) { \
mas01cr@410 80 goto error; \
mas01cr@410 81 } \
mas01cr@410 82 }
mas01cr@410 83
mas01cr@401 84 static inline int audiodb_sync_header(adb_t *adb) {
mas01cr@401 85 off_t pos;
mas01cr@401 86 pos = lseek(adb->fd, (off_t) 0, SEEK_CUR);
mas01cr@401 87 if(pos == (off_t) -1) {
mas01cr@401 88 goto error;
mas01cr@401 89 }
mas01cr@401 90 if(lseek(adb->fd, (off_t) 0, SEEK_SET) == (off_t) -1) {
mas01cr@401 91 goto error;
mas01cr@401 92 }
mas01cr@401 93 if(write(adb->fd, adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@401 94 goto error;
mas01cr@401 95 }
mas01cr@401 96
mas01cr@401 97 /* can be fsync() if fdatasync() is racily exciting and new */
mas01cr@401 98 fdatasync(adb->fd);
mas01cr@401 99 if(lseek(adb->fd, pos, SEEK_SET) == (off_t) -1) {
mas01cr@401 100 goto error;
mas01cr@401 101 }
mas01cr@401 102 return 0;
mas01cr@401 103
mas01cr@401 104 error:
mas01cr@401 105 return 1;
mas01cr@401 106 }
mas01cr@425 107
mas01cr@425 108 static inline double audiodb_dot_product(double *p, double *q, size_t count) {
mas01cr@425 109 double result = 0;
mas01cr@425 110 while(count--) {
mas01cr@425 111 result += *p++ * *q++;
mas01cr@425 112 }
mas01cr@425 113 return result;
mas01cr@425 114 }
mas01cr@426 115
mas01cr@426 116 static inline void audiodb_l2norm_buffer(double *d, size_t dim, size_t nvectors, double *l) {
mas01cr@426 117 while(nvectors--) {
mas01cr@426 118 double *d1 = d;
mas01cr@426 119 double *d2 = d;
mas01cr@426 120 *l++ = audiodb_dot_product(d1, d2, dim);
mas01cr@426 121 d += dim;
mas01cr@426 122 }
mas01cr@426 123 }
mas01cr@427 124
mas01cr@427 125 // This is a common pattern in sequence queries: what we are doing is
mas01cr@427 126 // taking a window of length seqlen over a buffer of length length,
mas01cr@427 127 // and placing the sum of the elements in that window in the first
mas01cr@427 128 // element of the window: thus replacing all but the last seqlen
mas01cr@427 129 // elements in the buffer with the corresponding windowed sum.
mas01cr@427 130 static inline void audiodb_sequence_sum(double *buffer, int length, int seqlen) {
mas01cr@427 131 double tmp1, tmp2, *ps;
mas01cr@427 132 int j, w;
mas01cr@427 133
mas01cr@427 134 tmp1 = *buffer;
mas01cr@427 135 j = 1;
mas01cr@427 136 w = seqlen - 1;
mas01cr@427 137 while(w--) {
mas01cr@427 138 *buffer += buffer[j++];
mas01cr@427 139 }
mas01cr@427 140 ps = buffer + 1;
mas01cr@427 141 w = length - seqlen; // +1 - 1
mas01cr@427 142 while(w--) {
mas01cr@427 143 tmp2 = *ps;
mas01cr@427 144 if(isfinite(tmp1)) {
mas01cr@427 145 *ps = *(ps - 1) - tmp1 + *(ps + seqlen - 1);
mas01cr@427 146 } else {
mas01cr@427 147 for(int i = 1; i < seqlen; i++) {
mas01cr@427 148 *ps += *(ps + i);
mas01cr@427 149 }
mas01cr@427 150 }
mas01cr@427 151 tmp1 = tmp2;
mas01cr@427 152 ps++;
mas01cr@427 153 }
mas01cr@427 154 }
mas01cr@427 155
mas01cr@427 156 // In contrast to audiodb_sequence_sum() above,
mas01cr@427 157 // audiodb_sequence_sqrt() and audiodb_sequence_average() below are
mas01cr@427 158 // simple mappers across the sequence.
mas01cr@427 159 static inline void audiodb_sequence_sqrt(double *buffer, int length, int seqlen) {
mas01cr@427 160 int w = length - seqlen + 1;
mas01cr@427 161 while(w--) {
mas01cr@427 162 *buffer = sqrt(*buffer);
mas01cr@427 163 buffer++;
mas01cr@427 164 }
mas01cr@427 165 }
mas01cr@427 166
mas01cr@427 167 static inline void audiodb_sequence_average(double *buffer, int length, int seqlen) {
mas01cr@427 168 int w = length - seqlen + 1;
mas01cr@427 169 while(w--) {
mas01cr@427 170 *buffer /= seqlen;
mas01cr@427 171 buffer++;
mas01cr@427 172 }
mas01cr@427 173 }
mas01cr@430 174
mas01cr@430 175 static inline uint32_t audiodb_key_index(adb_t *adb, const char *key) {
mas01cr@430 176 std::map<std::string,uint32_t>::iterator it;
mas01cr@430 177 it = adb->keys->find(key);
mas01cr@430 178 if(it == adb->keys->end()) {
mas01cr@430 179 return (uint32_t) -1;
mas01cr@430 180 } else {
mas01cr@430 181 return (*it).second;
mas01cr@430 182 }
mas01cr@430 183 }
mas01cr@433 184
mas01cr@433 185 int audiodb_read_data(adb_t *, int, int, double **, size_t *);