annotate audioDB-internals.h @ 453:16a903968d18 api-inversion

Almost finish with audioDB::query_loop. This patch is a little bit noisy, because we rename adb->keys to adb->keymap, introduce a new vector adb->keys (essentially to replace fileTable), and introduce new functionality (both include and exclude keylists in adb_query_refine_t) as well as modifying the query_loop function itself to take advantage of all of these goodies. Oh, and we also fix an embarrassing state bug in adb->track_offsets for insert -- what was I thinking? (Thank you, regression test suites). Since we are on a private branch at the moment, we can take the luxury of renumbering the ADB_REFINE_ flags to include the exclude list at the logical place; once we have an ABI to support, that won't be possible. Now audioDB::query builds up include and exclude lists as appropriate; query_loop does an [O(NlogN) probably] buildup of the keys to consider, and then iterates over tracks sequentially, seeking only if one or more tracks have been excluded. No more trackFile, yay! The only remaining thing to deal with is the accumulator. It's easy enough to pass it around, but I want to read the indexed version before doing so to see how that all fits together.
author mas01cr
date Wed, 24 Dec 2008 10:57:14 +0000
parents 4fe90fd568fc
children 823bca1e10f5
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@453 15 std::vector<std::string> *keys;
mas01cr@453 16 std::map<std::string,uint32_t> *keymap;
mas01cr@432 17 std::vector<uint32_t> *track_lengths;
mas01cr@442 18 std::vector<off_t> *track_offsets;
mas01cr@402 19 };
mas01cr@402 20
mas01cr@416 21 typedef struct {
mas01cr@416 22 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 23 return strcmp(r1.key, r2.key) < 0;
mas01cr@416 24 }
mas01cr@416 25 } adb_result_key_lt;
mas01cr@416 26
mas01cr@416 27 typedef struct {
mas01cr@416 28 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 29 return r1.qpos < r2.qpos;
mas01cr@416 30 }
mas01cr@416 31 } adb_result_qpos_lt;
mas01cr@416 32
mas01cr@416 33 typedef struct {
mas01cr@416 34 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 35 return r1.dist < r2.dist;
mas01cr@416 36 }
mas01cr@416 37 } adb_result_dist_lt;
mas01cr@416 38
mas01cr@416 39 typedef struct {
mas01cr@416 40 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 41 return r1.dist > r2.dist;
mas01cr@416 42 }
mas01cr@416 43 } adb_result_dist_gt;
mas01cr@416 44
mas01cr@416 45 typedef struct {
mas01cr@416 46 bool operator() (const adb_result_t &r1, const adb_result_t &r2) {
mas01cr@416 47 return ((r1.ipos < r2.ipos) ||
mas01cr@416 48 ((r1.ipos == r2.ipos) &&
mas01cr@416 49 ((r1.qpos < r2.qpos) ||
mas01cr@416 50 ((r1.qpos == r2.qpos) && (strcmp(r1.key, r2.key) < 0)))));
mas01cr@416 51 }
mas01cr@416 52 } adb_result_triple_lt;
mas01cr@416 53
mas01cr@401 54 /* We could go gcc-specific here and use typeof() instead of passing
mas01cr@401 55 * in an explicit type. Answers on a postcard as to whether that's a
mas01cr@401 56 * good plan or not. */
mas01cr@401 57 #define mmap_or_goto_error(type, var, start, length) \
mas01cr@401 58 { void *tmp = mmap(0, length, PROT_READ, MAP_SHARED, adb->fd, (start)); \
mas01cr@401 59 if(tmp == (void *) -1) { \
mas01cr@401 60 goto error; \
mas01cr@401 61 } \
mas01cr@401 62 var = (type) tmp; \
mas01cr@401 63 }
mas01cr@401 64
mas01cr@401 65 #define maybe_munmap(table, length) \
mas01cr@401 66 { if(table) { \
mas01cr@401 67 munmap(table, length); \
mas01cr@401 68 } \
mas01cr@401 69 }
mas01cr@401 70
mas01cr@410 71 #define write_or_goto_error(fd, buffer, size) \
mas01cr@410 72 { ssize_t tmp = size; \
mas01cr@410 73 if(write(fd, buffer, size) != tmp) { \
mas01cr@410 74 goto error; \
mas01cr@410 75 } \
mas01cr@410 76 }
mas01cr@410 77
mas01cr@410 78 #define read_or_goto_error(fd, buffer, size) \
mas01cr@410 79 { ssize_t tmp = size; \
mas01cr@410 80 if(read(fd, buffer, size) != tmp) { \
mas01cr@410 81 goto error; \
mas01cr@410 82 } \
mas01cr@410 83 }
mas01cr@410 84
mas01cr@401 85 static inline int audiodb_sync_header(adb_t *adb) {
mas01cr@401 86 off_t pos;
mas01cr@401 87 pos = lseek(adb->fd, (off_t) 0, SEEK_CUR);
mas01cr@401 88 if(pos == (off_t) -1) {
mas01cr@401 89 goto error;
mas01cr@401 90 }
mas01cr@401 91 if(lseek(adb->fd, (off_t) 0, SEEK_SET) == (off_t) -1) {
mas01cr@401 92 goto error;
mas01cr@401 93 }
mas01cr@401 94 if(write(adb->fd, adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@401 95 goto error;
mas01cr@401 96 }
mas01cr@401 97
mas01cr@401 98 /* can be fsync() if fdatasync() is racily exciting and new */
mas01cr@401 99 fdatasync(adb->fd);
mas01cr@401 100 if(lseek(adb->fd, pos, SEEK_SET) == (off_t) -1) {
mas01cr@401 101 goto error;
mas01cr@401 102 }
mas01cr@401 103 return 0;
mas01cr@401 104
mas01cr@401 105 error:
mas01cr@401 106 return 1;
mas01cr@401 107 }
mas01cr@425 108
mas01cr@425 109 static inline double audiodb_dot_product(double *p, double *q, size_t count) {
mas01cr@425 110 double result = 0;
mas01cr@425 111 while(count--) {
mas01cr@425 112 result += *p++ * *q++;
mas01cr@425 113 }
mas01cr@425 114 return result;
mas01cr@425 115 }
mas01cr@426 116
mas01cr@426 117 static inline void audiodb_l2norm_buffer(double *d, size_t dim, size_t nvectors, double *l) {
mas01cr@426 118 while(nvectors--) {
mas01cr@426 119 double *d1 = d;
mas01cr@426 120 double *d2 = d;
mas01cr@426 121 *l++ = audiodb_dot_product(d1, d2, dim);
mas01cr@426 122 d += dim;
mas01cr@426 123 }
mas01cr@426 124 }
mas01cr@427 125
mas01cr@427 126 // This is a common pattern in sequence queries: what we are doing is
mas01cr@427 127 // taking a window of length seqlen over a buffer of length length,
mas01cr@427 128 // and placing the sum of the elements in that window in the first
mas01cr@427 129 // element of the window: thus replacing all but the last seqlen
mas01cr@427 130 // elements in the buffer with the corresponding windowed sum.
mas01cr@427 131 static inline void audiodb_sequence_sum(double *buffer, int length, int seqlen) {
mas01cr@427 132 double tmp1, tmp2, *ps;
mas01cr@427 133 int j, w;
mas01cr@427 134
mas01cr@427 135 tmp1 = *buffer;
mas01cr@427 136 j = 1;
mas01cr@427 137 w = seqlen - 1;
mas01cr@427 138 while(w--) {
mas01cr@427 139 *buffer += buffer[j++];
mas01cr@427 140 }
mas01cr@427 141 ps = buffer + 1;
mas01cr@427 142 w = length - seqlen; // +1 - 1
mas01cr@427 143 while(w--) {
mas01cr@427 144 tmp2 = *ps;
mas01cr@427 145 if(isfinite(tmp1)) {
mas01cr@427 146 *ps = *(ps - 1) - tmp1 + *(ps + seqlen - 1);
mas01cr@427 147 } else {
mas01cr@427 148 for(int i = 1; i < seqlen; i++) {
mas01cr@427 149 *ps += *(ps + i);
mas01cr@427 150 }
mas01cr@427 151 }
mas01cr@427 152 tmp1 = tmp2;
mas01cr@427 153 ps++;
mas01cr@427 154 }
mas01cr@427 155 }
mas01cr@427 156
mas01cr@427 157 // In contrast to audiodb_sequence_sum() above,
mas01cr@427 158 // audiodb_sequence_sqrt() and audiodb_sequence_average() below are
mas01cr@427 159 // simple mappers across the sequence.
mas01cr@427 160 static inline void audiodb_sequence_sqrt(double *buffer, int length, int seqlen) {
mas01cr@427 161 int w = length - seqlen + 1;
mas01cr@427 162 while(w--) {
mas01cr@427 163 *buffer = sqrt(*buffer);
mas01cr@427 164 buffer++;
mas01cr@427 165 }
mas01cr@427 166 }
mas01cr@427 167
mas01cr@427 168 static inline void audiodb_sequence_average(double *buffer, int length, int seqlen) {
mas01cr@427 169 int w = length - seqlen + 1;
mas01cr@427 170 while(w--) {
mas01cr@427 171 *buffer /= seqlen;
mas01cr@427 172 buffer++;
mas01cr@427 173 }
mas01cr@427 174 }
mas01cr@430 175
mas01cr@430 176 static inline uint32_t audiodb_key_index(adb_t *adb, const char *key) {
mas01cr@430 177 std::map<std::string,uint32_t>::iterator it;
mas01cr@453 178 it = adb->keymap->find(key);
mas01cr@453 179 if(it == adb->keymap->end()) {
mas01cr@430 180 return (uint32_t) -1;
mas01cr@430 181 } else {
mas01cr@430 182 return (*it).second;
mas01cr@430 183 }
mas01cr@430 184 }
mas01cr@433 185
mas01cr@433 186 int audiodb_read_data(adb_t *, int, int, double **, size_t *);
mas01cr@443 187 int audiodb_insert_create_datum(adb_insert_t *, adb_datum_t *);
mas01cr@443 188 int audiodb_free_datum(adb_datum_t *);
mas01cr@444 189 int audiodb_query_spec_qpointers(adb_t *, adb_query_spec_t *, double **, double **, adb_qpointers_internal_t *);