annotate common.cpp @ 369:6564be3109c5 gcc-4.3-cleanups

gcc-4.3 warning cleanups for lshlib.cpp (I do not believe that any of these changes contain significant copyrightable "intellectual property". However, to the extent that they do, the changes are hereby released into the Public Domain, and may be therefore be used by anyone for any purpose without need for consideration of any kind.)
author mas01cr
date Wed, 12 Nov 2008 15:23:32 +0000
parents 64d5de8b1a68
children 4e68f7d4d524 342822c2d49a fbcc1303dfeb
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@239 2
mas01cr@239 3 #if defined(O2_DEBUG)
mas01cr@239 4 void sigterm_action(int signal, siginfo_t *info, void *context) {
mas01cr@239 5 exit(128+signal);
mas01cr@239 6 }
mas01cr@239 7
mas01cr@239 8 void sighup_action(int signal, siginfo_t *info, void *context) {
mas01cr@239 9 // FIXME: reread any configuration files
mas01cr@239 10 }
mas01cr@239 11 #endif
mas01cr@239 12
mas01cr@239 13 void audioDB::get_lock(int fd, bool exclusive) {
mas01cr@239 14 struct flock lock;
mas01cr@239 15 int status;
mas01cr@239 16
mas01cr@239 17 lock.l_type = exclusive ? F_WRLCK : F_RDLCK;
mas01cr@239 18 lock.l_whence = SEEK_SET;
mas01cr@239 19 lock.l_start = 0;
mas01cr@239 20 lock.l_len = 0; /* "the whole file" */
mas01cr@239 21
mas01cr@239 22 retry:
mas01cr@239 23 do {
mas01cr@239 24 status = fcntl(fd, F_SETLKW, &lock);
mas01cr@239 25 } while (status != 0 && errno == EINTR);
mas01cr@239 26
mas01cr@239 27 if (status) {
mas01cr@239 28 if (errno == EAGAIN) {
mas01cr@239 29 sleep(1);
mas01cr@239 30 goto retry;
mas01cr@239 31 } else {
mas01cr@239 32 error("fcntl lock error", "", "fcntl");
mas01cr@239 33 }
mas01cr@239 34 }
mas01cr@239 35 }
mas01cr@239 36
mas01cr@239 37 void audioDB::release_lock(int fd) {
mas01cr@239 38 struct flock lock;
mas01cr@239 39 int status;
mas01cr@239 40
mas01cr@239 41 lock.l_type = F_UNLCK;
mas01cr@239 42 lock.l_whence = SEEK_SET;
mas01cr@239 43 lock.l_start = 0;
mas01cr@239 44 lock.l_len = 0;
mas01cr@239 45
mas01cr@239 46 status = fcntl(fd, F_SETLKW, &lock);
mas01cr@239 47
mas01cr@239 48 if (status)
mas01cr@239 49 error("fcntl unlock error", "", "fcntl");
mas01cr@239 50 }
mas01cr@239 51
mas01cr@239 52 void audioDB::error(const char* a, const char* b, const char *sysFunc) {
mas01ik@355 53
mas01ik@355 54
mas01ik@355 55 if(isServer) {
mas01cr@363 56 /* FIXME: I think this is leaky -- we never delete err.
mas01cr@363 57 actually deleting it is tricky, though; it gets placed into
mas01cr@363 58 some soap-internal struct with uncertain extent... -- CSR,
mas01cr@363 59 2007-10-01 */
mas01cr@363 60 char *err = new char[256]; /* FIXME: overflows */
mas01cr@363 61 snprintf(err, 255, "%s: %s\n%s", a, b, sysFunc ? strerror(errno) : "");
mas01cr@363 62 /* FIXME: actually we could usefully do with a properly
mas01cr@363 63 structured type, so that we can throw separate faultstring
mas01cr@363 64 and details. -- CSR, 2007-10-01 */
mas01ik@355 65 throw(err);
mas01ik@355 66 } else if (UseApiError){
mas01ik@355 67 apierrortemp=-1;
mas01ik@355 68 throw(apierrortemp);
mas01ik@355 69 } else {
mas01ik@355 70 std::cerr << a << ": " << b << std::endl;
mas01ik@355 71 if (sysFunc) {
mas01ik@355 72 perror(sysFunc);
mas01ik@355 73 }
mas01ik@355 74 exit(1);
mas01cr@239 75 }
mas01ik@355 76
mas01cr@239 77 }
mas01cr@239 78
mas01cr@284 79 void audioDB::initRNG() {
mas01cr@284 80 rng = gsl_rng_alloc(gsl_rng_mt19937);
mas01cr@284 81 if(!rng) {
mas01cr@284 82 error("could not allocate Random Number Generator");
mas01cr@284 83 }
mas01cr@284 84 /* FIXME: maybe we should use a real source of entropy? */
mas01cr@284 85 gsl_rng_set(rng, time(NULL));
mas01cr@284 86 }
mas01cr@284 87
mas01cr@239 88 void audioDB::initDBHeader(const char* dbName) {
mas01cr@239 89 if ((dbfid = open(dbName, forWrite ? O_RDWR : O_RDONLY)) < 0) {
mas01cr@239 90 error("Can't open database file", dbName, "open");
mas01cr@239 91 }
mas01cr@239 92
mas01cr@239 93 get_lock(dbfid, forWrite);
mas01cr@239 94 // Get the database header info
mas01cr@239 95 dbH = new dbTableHeaderT();
mas01cr@239 96 assert(dbH);
mas01cr@239 97
mas01cr@239 98 if(read(dbfid, (char *) dbH, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@239 99 error("error reading db header", dbName, "read");
mas01cr@239 100 }
mas01cr@239 101
mas01cr@239 102 if(dbH->magic == O2_OLD_MAGIC) {
mas01cr@239 103 // FIXME: if anyone ever complains, write the program to convert
mas01cr@239 104 // from the old audioDB format to the new...
mas01cr@239 105 error("database file has old O2 header", dbName);
mas01cr@239 106 }
mas01cr@239 107
mas01cr@239 108 if(dbH->magic != O2_MAGIC) {
mas01cr@239 109 std::cerr << "expected: " << O2_MAGIC << ", got: " << dbH->magic << std::endl;
mas01cr@239 110 error("database file has incorrect header", dbName);
mas01cr@239 111 }
mas01cr@239 112
mas01cr@239 113 if(dbH->version != O2_FORMAT_VERSION) {
mas01cr@239 114 error("database file has incorrect version", dbName);
mas01cr@239 115 }
mas01cr@239 116
mas01cr@239 117 if(dbH->headerSize != O2_HEADERSIZE) {
mas01cr@239 118 error("sizeof(dbTableHeader) unexpected: platform ABI mismatch?", dbName);
mas01cr@239 119 }
mas01cr@239 120
mas01cr@239 121 CHECKED_MMAP(char *, db, 0, getpagesize());
mas01cr@239 122
mas01cr@239 123 // Make some handy tables with correct types
mas01cr@239 124 if(forWrite || (dbH->length > 0)) {
mas01cr@239 125 if(forWrite) {
mas01cr@239 126 fileTableLength = dbH->trackTableOffset - dbH->fileTableOffset;
mas01cr@239 127 trackTableLength = dbH->dataOffset - dbH->trackTableOffset;
mas01cr@239 128 dataBufLength = dbH->timesTableOffset - dbH->dataOffset;
mas01cr@239 129 timesTableLength = dbH->powerTableOffset - dbH->timesTableOffset;
mas01cr@239 130 powerTableLength = dbH->l2normTableOffset - dbH->powerTableOffset;
mas01cr@239 131 l2normTableLength = dbH->dbSize - dbH->l2normTableOffset;
mas01cr@239 132 } else {
mas01cr@256 133 fileTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@256 134 trackTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_TRACKTABLE_ENTRY_SIZE);
mas01mc@324 135 if( dbH->flags & O2_FLAG_LARGE_ADB ){
mas01mc@324 136 dataBufLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 137 timesTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 138 powerTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 139 l2normTableLength = 0;
mas01mc@324 140 }
mas01mc@324 141 else{
mas01mc@324 142 dataBufLength = ALIGN_PAGE_UP(dbH->length);
mas01mc@324 143 timesTableLength = ALIGN_PAGE_UP(2*(dbH->length / dbH->dim));
mas01mc@324 144 powerTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01mc@324 145 l2normTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01mc@324 146 }
mas01cr@239 147 }
mas01cr@239 148 CHECKED_MMAP(char *, fileTable, dbH->fileTableOffset, fileTableLength);
mas01cr@239 149 CHECKED_MMAP(unsigned *, trackTable, dbH->trackTableOffset, trackTableLength);
mas01cr@239 150 /*
mas01cr@239 151 * No more mmap() for dataBuf
mas01cr@239 152 *
mas01cr@239 153 * FIXME: Actually we do do the mmap() in the two cases where it's
mas01cr@239 154 * still "needed": in pointQuery and in l2norm if dbH->length is
mas01cr@239 155 * non-zero. Removing those cases too (and deleting the dataBuf
mas01cr@239 156 * variable completely) would be cool. -- CSR, 2007-11-19
mas01cr@239 157 *
mas01cr@239 158 * CHECKED_MMAP(double *, dataBuf, dbH->dataOffset, dataBufLength);
mas01cr@239 159 */
mas01mc@324 160 if( dbH->flags & O2_FLAG_LARGE_ADB ){
mas01mc@324 161 CHECKED_MMAP(char *, featureFileNameTable, dbH->dataOffset, fileTableLength);
mas01mc@324 162 if( dbH->flags & O2_FLAG_TIMES )
mas01mc@324 163 CHECKED_MMAP(char *, timesFileNameTable, dbH->timesTableOffset, fileTableLength);
mas01mc@324 164 if( dbH->flags & O2_FLAG_POWER )
mas01mc@324 165 CHECKED_MMAP(char *, powerFileNameTable, dbH->powerTableOffset, fileTableLength);
mas01mc@324 166 }
mas01mc@324 167 else{
mas01mc@324 168 CHECKED_MMAP(double *, timesTable, dbH->timesTableOffset, timesTableLength);
mas01mc@324 169 CHECKED_MMAP(double *, powerTable, dbH->powerTableOffset, powerTableLength);
mas01mc@324 170 CHECKED_MMAP(double *, l2normTable, dbH->l2normTableOffset, l2normTableLength);
mas01mc@324 171 }
mas01cr@239 172 }
mas01mc@292 173
mas01mc@292 174 // build track offset table
mas01mc@292 175 trackOffsetTable = new off_t[dbH->numFiles];
mas01mc@292 176 Uns32T cumTrack=0;
mas01mc@292 177 for(Uns32T k = 0; k < dbH->numFiles; k++){
mas01mc@292 178 trackOffsetTable[k] = cumTrack;
mas01mc@292 179 cumTrack += trackTable[k] * dbH->dim;
mas01mc@324 180 }
mas01mc@324 181
mas01mc@324 182 // Assign correct number of point bits per track in LSH indexing / retrieval
mas01mc@324 183 lsh_n_point_bits = dbH->flags >> 28;
mas01mc@324 184 if( !lsh_n_point_bits )
mas01mc@324 185 lsh_n_point_bits = O2_DEFAULT_LSH_N_POINT_BITS;
mas01cr@239 186 }
mas01cr@239 187
mas01mc@324 188 void audioDB::initInputFile (const char *inFile, bool loadData) {
mas01cr@239 189 if (inFile) {
mas01cr@239 190 if ((infid = open(inFile, O_RDONLY)) < 0) {
mas01cr@239 191 error("can't open input file for reading", inFile, "open");
mas01cr@239 192 }
mas01cr@239 193
mas01cr@239 194 if (fstat(infid, &statbuf) < 0) {
mas01cr@239 195 error("fstat error finding size of input", inFile, "fstat");
mas01cr@239 196 }
mas01cr@239 197
mas01cr@239 198 if(dbH->dim == 0 && dbH->length == 0) { // empty database
mas01cr@239 199 // initialize with input dimensionality
mas01cr@239 200 if(read(infid, &dbH->dim, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@239 201 error("short read of input file", inFile);
mas01cr@239 202 }
mas01cr@239 203 if(dbH->dim == 0) {
mas01cr@239 204 error("dimensionality of zero in input file", inFile);
mas01cr@239 205 }
mas01cr@239 206 } else {
mas01cr@239 207 unsigned test;
mas01cr@239 208 if(read(infid, &test, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@239 209 error("short read of input file", inFile);
mas01cr@239 210 }
mas01cr@239 211 if(dbH->dim == 0) {
mas01cr@239 212 error("dimensionality of zero in input file", inFile);
mas01cr@239 213 }
mas01cr@239 214 if(dbH->dim != test) {
mas01cr@239 215 std::cerr << "error: expected dimension: " << dbH->dim << ", got : " << test <<std::endl;
mas01cr@239 216 error("feature dimensions do not match database table dimensions", inFile);
mas01cr@239 217 }
mas01cr@239 218 }
mas01cr@239 219
mas01mc@324 220 if (loadData && ((indata = (char *) mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, infid, 0)) == (caddr_t) -1)) {
mas01cr@239 221 error("mmap error for input", inFile, "mmap");
mas01cr@239 222 }
mas01cr@239 223 }
mas01cr@239 224 }
mas01cr@239 225
mas01mc@292 226 void audioDB::initTables(const char* dbName, const char* inFile) {
mas01cr@284 227 /* FIXME: initRNG() really logically belongs in the audioDB
mas01cr@284 228 contructor. However, there are of the order of four constructors
mas01cr@284 229 at the moment, and more to come from API implementation. Given
mas01cr@284 230 that duplication, I think this is the least worst place to put
mas01cr@284 231 it; the assumption is that nothing which doesn't look at a
mas01cr@284 232 database will need an RNG. -- CSR, 2008-07-02 */
mas01cr@284 233 initRNG();
mas01cr@239 234 initDBHeader(dbName);
mas01mc@292 235 if(inFile)
mas01mc@292 236 initInputFile(inFile);
mas01cr@239 237 }
mas01mc@292 238
mas01mc@324 239 // If name is relative path, side effect name with prefix/name
mas01mc@324 240 // Do not free original pointer
mas01mc@324 241 void audioDB::prefix_name(char** const name, const char* prefix){
mas01mc@324 242 // No prefix if prefix is empty
mas01mc@324 243 if(!prefix)
mas01mc@324 244 return;
mas01mc@324 245 // Allocate new memory, keep old memory
mas01mc@324 246 assert(name && *name);
mas01mc@324 247 if (strlen(*name) + strlen(prefix) + 1 > O2_MAXFILESTR)
mas01mc@324 248 error("error: path prefix + filename too long",prefix);
mas01mc@324 249 // Do not prefix absolute path+filename
mas01mc@324 250 if(**name=='/')
mas01mc@324 251 return;
mas01mc@324 252 // OK to prefix relative path+filename
mas01mc@324 253 char* prefixedName = (char*) malloc(O2_MAXFILESTR);
mas01mc@324 254 sprintf(prefixedName, "%s/%s", prefix, *name);
mas01mc@324 255 *name = prefixedName; // side effect new name to old name
mas01mc@324 256 }