annotate audioDB-internals.h @ 427:adaa6a688a04 api-inversion

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