annotate common.cpp @ 507:e7fd50483311

Free bits of the datum constructed in audioDB::query. We're not quite safe: error calls between allocation of some of these bits and pieces and their use will cause failure... but not freeing things here is definitely wrong.
author mas01cr
date Tue, 13 Jan 2009 21:37:10 +0000
parents 342822c2d49a
children cc2b97d020b1
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@498 2 extern "C" {
mas01cr@498 3 #include "audioDB_API.h"
mas01cr@498 4 #include "audioDB-internals.h"
mas01cr@498 5 }
mas01cr@239 6
mas01cr@239 7 #if defined(O2_DEBUG)
mas01cr@239 8 void sigterm_action(int signal, siginfo_t *info, void *context) {
mas01cr@239 9 exit(128+signal);
mas01cr@239 10 }
mas01cr@239 11
mas01cr@239 12 void sighup_action(int signal, siginfo_t *info, void *context) {
mas01cr@239 13 // FIXME: reread any configuration files
mas01cr@239 14 }
mas01cr@239 15 #endif
mas01cr@239 16
mas01cr@239 17 void audioDB::get_lock(int fd, bool exclusive) {
mas01cr@498 18 if(acquire_lock(fd, exclusive)) {
mas01cr@498 19 error("fcntl lock error", "", "fcntl");
mas01cr@239 20 }
mas01cr@239 21 }
mas01cr@239 22
mas01cr@239 23 void audioDB::release_lock(int fd) {
mas01cr@498 24 if (divest_lock(fd)) {
mas01cr@239 25 error("fcntl unlock error", "", "fcntl");
mas01cr@498 26 }
mas01cr@239 27 }
mas01cr@239 28
mas01cr@239 29 void audioDB::error(const char* a, const char* b, const char *sysFunc) {
mas01ik@355 30
mas01ik@355 31
mas01ik@355 32 if(isServer) {
mas01cr@370 33 /* FIXME: I think this is leaky -- we never delete err.
mas01cr@370 34 actually deleting it is tricky, though; it gets placed into
mas01cr@370 35 some soap-internal struct with uncertain extent... -- CSR,
mas01cr@370 36 2007-10-01 */
mas01cr@370 37 char *err = new char[256]; /* FIXME: overflows */
mas01cr@370 38 snprintf(err, 255, "%s: %s\n%s", a, b, sysFunc ? strerror(errno) : "");
mas01cr@370 39 /* FIXME: actually we could usefully do with a properly
mas01cr@370 40 structured type, so that we can throw separate faultstring
mas01cr@370 41 and details. -- CSR, 2007-10-01 */
mas01ik@355 42 throw(err);
mas01ik@355 43 } else {
mas01ik@355 44 std::cerr << a << ": " << b << std::endl;
mas01ik@355 45 if (sysFunc) {
mas01ik@355 46 perror(sysFunc);
mas01ik@355 47 }
mas01ik@355 48 exit(1);
mas01cr@239 49 }
mas01cr@239 50 }
mas01cr@239 51
mas01cr@284 52 void audioDB::initRNG() {
mas01cr@284 53 rng = gsl_rng_alloc(gsl_rng_mt19937);
mas01cr@284 54 if(!rng) {
mas01cr@284 55 error("could not allocate Random Number Generator");
mas01cr@284 56 }
mas01cr@284 57 /* FIXME: maybe we should use a real source of entropy? */
mas01cr@284 58 gsl_rng_set(rng, time(NULL));
mas01cr@284 59 }
mas01cr@284 60
mas01cr@239 61 void audioDB::initDBHeader(const char* dbName) {
mas01cr@498 62 if(!adb) {
mas01cr@498 63 adb = audiodb_open(dbName, forWrite ? O_RDWR : O_RDONLY);
mas01cr@498 64 if(!adb) {
mas01cr@498 65 error("Failed to open database", dbName);
mas01cr@498 66 }
mas01cr@239 67 }
mas01cr@498 68 dbfid = adb->fd;
mas01cr@498 69 dbH = adb->header;
mas01cr@239 70
mas01cr@239 71 // Make some handy tables with correct types
mas01cr@239 72 if(forWrite || (dbH->length > 0)) {
mas01cr@239 73 if(forWrite) {
mas01cr@239 74 fileTableLength = dbH->trackTableOffset - dbH->fileTableOffset;
mas01cr@239 75 trackTableLength = dbH->dataOffset - dbH->trackTableOffset;
mas01cr@239 76 timesTableLength = dbH->powerTableOffset - dbH->timesTableOffset;
mas01cr@239 77 powerTableLength = dbH->l2normTableOffset - dbH->powerTableOffset;
mas01cr@239 78 l2normTableLength = dbH->dbSize - dbH->l2normTableOffset;
mas01cr@239 79 } else {
mas01cr@256 80 fileTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@256 81 trackTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_TRACKTABLE_ENTRY_SIZE);
mas01mc@324 82 if( dbH->flags & O2_FLAG_LARGE_ADB ){
mas01mc@324 83 timesTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 84 powerTableLength = ALIGN_PAGE_UP(dbH->numFiles * O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 85 l2normTableLength = 0;
mas01mc@324 86 }
mas01mc@324 87 else{
mas01mc@324 88 timesTableLength = ALIGN_PAGE_UP(2*(dbH->length / dbH->dim));
mas01mc@324 89 powerTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01mc@324 90 l2normTableLength = ALIGN_PAGE_UP(dbH->length / dbH->dim);
mas01mc@324 91 }
mas01cr@239 92 }
mas01cr@239 93 CHECKED_MMAP(char *, fileTable, dbH->fileTableOffset, fileTableLength);
mas01cr@239 94 CHECKED_MMAP(unsigned *, trackTable, dbH->trackTableOffset, trackTableLength);
mas01mc@324 95 if( dbH->flags & O2_FLAG_LARGE_ADB ){
mas01mc@324 96 CHECKED_MMAP(char *, featureFileNameTable, dbH->dataOffset, fileTableLength);
mas01mc@324 97 if( dbH->flags & O2_FLAG_TIMES )
mas01mc@324 98 CHECKED_MMAP(char *, timesFileNameTable, dbH->timesTableOffset, fileTableLength);
mas01mc@324 99 if( dbH->flags & O2_FLAG_POWER )
mas01mc@324 100 CHECKED_MMAP(char *, powerFileNameTable, dbH->powerTableOffset, fileTableLength);
mas01mc@324 101 }
mas01mc@324 102 else{
mas01mc@324 103 CHECKED_MMAP(double *, timesTable, dbH->timesTableOffset, timesTableLength);
mas01mc@324 104 CHECKED_MMAP(double *, powerTable, dbH->powerTableOffset, powerTableLength);
mas01mc@324 105 CHECKED_MMAP(double *, l2normTable, dbH->l2normTableOffset, l2normTableLength);
mas01mc@324 106 }
mas01cr@239 107 }
mas01cr@239 108 }
mas01cr@239 109
mas01cr@498 110 void audioDB::initInputFile (const char *inFile) {
mas01cr@239 111 if (inFile) {
mas01cr@239 112 if ((infid = open(inFile, O_RDONLY)) < 0) {
mas01cr@239 113 error("can't open input file for reading", inFile, "open");
mas01cr@239 114 }
mas01cr@239 115
mas01cr@239 116 if (fstat(infid, &statbuf) < 0) {
mas01cr@239 117 error("fstat error finding size of input", inFile, "fstat");
mas01cr@239 118 }
mas01cr@239 119
mas01cr@239 120 if(dbH->dim == 0 && dbH->length == 0) { // empty database
mas01cr@239 121 // initialize with input dimensionality
mas01cr@239 122 if(read(infid, &dbH->dim, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@239 123 error("short read of input file", inFile);
mas01cr@239 124 }
mas01cr@239 125 if(dbH->dim == 0) {
mas01cr@239 126 error("dimensionality of zero in input file", inFile);
mas01cr@239 127 }
mas01cr@239 128 } else {
mas01cr@239 129 unsigned test;
mas01cr@239 130 if(read(infid, &test, sizeof(unsigned)) != sizeof(unsigned)) {
mas01cr@239 131 error("short read of input file", inFile);
mas01cr@239 132 }
mas01cr@239 133 if(dbH->dim == 0) {
mas01cr@239 134 error("dimensionality of zero in input file", inFile);
mas01cr@239 135 }
mas01cr@239 136 if(dbH->dim != test) {
mas01cr@239 137 std::cerr << "error: expected dimension: " << dbH->dim << ", got : " << test <<std::endl;
mas01cr@239 138 error("feature dimensions do not match database table dimensions", inFile);
mas01cr@239 139 }
mas01cr@239 140 }
mas01cr@239 141 }
mas01cr@239 142 }
mas01cr@239 143
mas01mc@292 144 void audioDB::initTables(const char* dbName, const char* inFile) {
mas01cr@284 145 /* FIXME: initRNG() really logically belongs in the audioDB
mas01cr@284 146 contructor. However, there are of the order of four constructors
mas01cr@284 147 at the moment, and more to come from API implementation. Given
mas01cr@284 148 that duplication, I think this is the least worst place to put
mas01cr@284 149 it; the assumption is that nothing which doesn't look at a
mas01cr@284 150 database will need an RNG. -- CSR, 2008-07-02 */
mas01cr@284 151 initRNG();
mas01cr@239 152 initDBHeader(dbName);
mas01mc@292 153 if(inFile)
mas01mc@292 154 initInputFile(inFile);
mas01cr@239 155 }
mas01mc@292 156
mas01mc@324 157 // If name is relative path, side effect name with prefix/name
mas01mc@324 158 // Do not free original pointer
mas01mc@324 159 void audioDB::prefix_name(char** const name, const char* prefix){
mas01mc@324 160 // No prefix if prefix is empty
mas01mc@324 161 if(!prefix)
mas01mc@324 162 return;
mas01mc@324 163 // Allocate new memory, keep old memory
mas01mc@324 164 assert(name && *name);
mas01mc@324 165 if (strlen(*name) + strlen(prefix) + 1 > O2_MAXFILESTR)
mas01mc@324 166 error("error: path prefix + filename too long",prefix);
mas01mc@324 167 // Do not prefix absolute path+filename
mas01mc@324 168 if(**name=='/')
mas01mc@324 169 return;
mas01mc@324 170 // OK to prefix relative path+filename
mas01mc@324 171 char* prefixedName = (char*) malloc(O2_MAXFILESTR);
mas01mc@324 172 sprintf(prefixedName, "%s/%s", prefix, *name);
mas01mc@324 173 *name = prefixedName; // side effect new name to old name
mas01mc@324 174 }
mas01cr@498 175
mas01cr@498 176 void audioDB::insertTimeStamps(unsigned numVectors, std::ifstream *timesFile, double *timesdata) {
mas01cr@498 177 assert(usingTimes);
mas01cr@498 178
mas01cr@498 179 unsigned numtimes = 0;
mas01cr@498 180
mas01cr@498 181 if(!timesFile->is_open()) {
mas01cr@498 182 error("problem opening times file on timestamped database", timesFileName);
mas01cr@498 183 }
mas01cr@498 184
mas01cr@498 185 double timepoint, next;
mas01cr@498 186 *timesFile >> timepoint;
mas01cr@498 187 if (timesFile->eof()) {
mas01cr@498 188 error("no entries in times file", timesFileName);
mas01cr@498 189 }
mas01cr@498 190 numtimes++;
mas01cr@498 191 do {
mas01cr@498 192 *timesFile >> next;
mas01cr@498 193 if (timesFile->eof()) {
mas01cr@498 194 break;
mas01cr@498 195 }
mas01cr@498 196 numtimes++;
mas01cr@498 197 timesdata[0] = timepoint;
mas01cr@498 198 timepoint = (timesdata[1] = next);
mas01cr@498 199 timesdata += 2;
mas01cr@498 200 } while (numtimes < numVectors + 1);
mas01cr@498 201
mas01cr@498 202 if (numtimes < numVectors + 1) {
mas01cr@498 203 error("too few timepoints in times file", timesFileName);
mas01cr@498 204 }
mas01cr@498 205
mas01cr@498 206 *timesFile >> next;
mas01cr@498 207 if (!timesFile->eof()) {
mas01cr@498 208 error("too many timepoints in times file", timesFileName);
mas01cr@498 209 }
mas01cr@498 210 }