annotate dump.cpp @ 401:a8a5f2ca5380 api-inversion

Invert audioDB::l2norm / audiodb_l2norm() We now have some functions that shouldn't be exported to the user of the library, but are used in more than one source file; case in point: audiodb_sync_header(). Make a new audioDB-internals.h file for them, and while we're at it put the scary mmap()-related macros in there too. We can't delete audioDB::unitNormAndInsertL2() quite yet, because it's used in insertion too, but we can delete the non-append branches. That's not very much code to lose, but every little helps.
author mas01cr
date Wed, 03 Dec 2008 14:53:20 +0000
parents 8c7453fb5bd9
children d7e590d58c85
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@399 2 extern "C" {
mas01cr@399 3 #include "audioDB_API.h"
mas01cr@401 4 #include "audioDB-internals.h"
mas01cr@399 5 }
mas01cr@239 6
mas01cr@399 7 int audiodb_dump(adb_t *adb, const char *output) {
mas01cr@399 8 char *fileTable = 0; /* key_table */
mas01cr@399 9 unsigned *trackTable = 0; /* track_size_table */
mas01cr@399 10 double *timesTable = 0; /* timestamps_table */
mas01cr@399 11 double *powerTable = 0; /* power_table */
mas01cr@399 12
mas01cr@399 13 size_t fileTableLength = 0;
mas01cr@399 14 size_t trackTableLength = 0;
mas01cr@399 15 size_t timesTableLength = 0;
mas01cr@399 16 size_t powerTableLength = 0;
mas01cr@399 17
mas01cr@399 18 char *featureFileNameTable = 0;
mas01cr@399 19 char *powerFileNameTable = 0;
mas01cr@399 20 char *timesFileNameTable = 0;
mas01cr@399 21
mas01cr@399 22 char cwd[PATH_MAX];
mas01cr@399 23 int directory_changed = 0;
mas01cr@399 24
mas01cr@399 25 int fLfd = 0, tLfd = 0, pLfd = 0, kLfd = 0;
mas01cr@399 26 FILE *fLFile = 0, *tLFile = 0, *pLFile = 0, *kLFile = 0;
mas01cr@399 27
mas01cr@399 28 int times, power;
mas01cr@399 29
mas01cr@399 30 char fName[256];
mas01cr@399 31 int ffd, pfd;
mas01cr@399 32 FILE *tFile;
mas01cr@399 33 unsigned pos = 0;
mas01cr@399 34 double *data_buffer;
mas01cr@399 35 size_t data_buffer_size;
mas01cr@399 36 FILE *scriptFile = 0;
mas01cr@399 37
mas01cr@399 38 unsigned nfiles = adb->header->numFiles;
mas01cr@399 39
mas01cr@399 40 if(adb->header->length > 0) {
mas01cr@399 41 fileTableLength = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@399 42 trackTableLength = ALIGN_PAGE_UP(nfiles * O2_TRACKTABLE_ENTRY_SIZE);
mas01cr@399 43 if(!(adb->header->flags & O2_FLAG_LARGE_ADB)) {
mas01cr@399 44 off_t length = adb->header->length;
mas01cr@399 45 unsigned dim = adb->header->dim;
mas01cr@399 46 timesTableLength = ALIGN_PAGE_UP(2*length/dim);
mas01cr@399 47 powerTableLength = ALIGN_PAGE_UP(length/dim);
mas01cr@399 48 }
mas01cr@399 49
mas01cr@399 50 mmap_or_goto_error(char *, fileTable, adb->header->fileTableOffset, fileTableLength);
mas01cr@399 51 mmap_or_goto_error(unsigned *, trackTable, adb->header->trackTableOffset, trackTableLength);
mas01cr@399 52 if (adb->header->flags & O2_FLAG_LARGE_ADB) {
mas01cr@399 53 mmap_or_goto_error(char *, featureFileNameTable, adb->header->dataOffset, fileTableLength);
mas01cr@399 54 mmap_or_goto_error(char *, powerFileNameTable, adb->header->powerTableOffset, fileTableLength);
mas01cr@399 55 mmap_or_goto_error(char *, timesFileNameTable, adb->header->timesTableOffset, fileTableLength);
mas01cr@399 56 } else {
mas01cr@399 57 mmap_or_goto_error(double *, powerTable, adb->header->powerTableOffset, powerTableLength);
mas01cr@399 58 mmap_or_goto_error(double *, timesTable, adb->header->timesTableOffset, timesTableLength);
mas01cr@399 59 }
mas01cr@239 60 }
mas01cr@239 61
mas01cr@239 62 if((mkdir(output, S_IRWXU|S_IRWXG|S_IRWXO)) < 0) {
mas01cr@399 63 goto error;
mas01cr@239 64 }
mas01cr@239 65
mas01cr@239 66 if ((getcwd(cwd, PATH_MAX)) == 0) {
mas01cr@399 67 goto error;
mas01cr@239 68 }
mas01cr@239 69
mas01cr@399 70 /* FIXME: Hrm. How does chdir(2) interact with threads? Does each
mas01cr@399 71 * thread have its own working directory? */
mas01cr@239 72 if((chdir(output)) < 0) {
mas01cr@399 73 goto error;
mas01cr@399 74 }
mas01cr@399 75 directory_changed = 1;
mas01cr@399 76
mas01cr@399 77 if ((fLfd = open("featureList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@399 78 goto error;
mas01cr@239 79 }
mas01cr@239 80
mas01cr@399 81 times = adb->header->flags & O2_FLAG_TIMES;
mas01cr@239 82 if (times) {
mas01cr@239 83 if ((tLfd = open("timesList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@399 84 goto error;
mas01cr@239 85 }
mas01cr@239 86 }
mas01cr@239 87
mas01cr@399 88 power = adb->header->flags & O2_FLAG_POWER;
mas01cr@239 89 if (power) {
mas01cr@239 90 if ((pLfd = open("powerList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@399 91 goto error;
mas01cr@239 92 }
mas01cr@239 93 }
mas01cr@239 94
mas01cr@239 95 if ((kLfd = open("keyList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@399 96 goto error;
mas01cr@239 97 }
mas01cr@239 98
mas01cr@239 99 /* can these fail? I sincerely hope not. */
mas01cr@239 100 fLFile = fdopen(fLfd, "w");
mas01cr@239 101 if (times) {
mas01cr@239 102 tLFile = fdopen(tLfd, "w");
mas01cr@239 103 }
mas01cr@239 104 if (power) {
mas01cr@239 105 pLFile = fdopen(pLfd, "w");
mas01cr@239 106 }
mas01cr@239 107 kLFile = fdopen(kLfd, "w");
mas01cr@239 108
mas01cr@399 109 lseek(adb->fd, adb->header->dataOffset, SEEK_SET);
mas01cr@399 110
mas01cr@399 111 for(unsigned k = 0; k < nfiles; k++) {
mas01cr@256 112 fprintf(kLFile, "%s\n", fileTable + k*O2_FILETABLE_ENTRY_SIZE);
mas01cr@399 113 if(adb->header->flags & O2_FLAG_LARGE_ADB) {
mas01cr@380 114 char *featureFileName = featureFileNameTable+k*O2_FILETABLE_ENTRY_SIZE;
mas01cr@399 115 if(*featureFileName != '/') {
mas01cr@399 116 goto error;
mas01cr@399 117 }
mas01cr@380 118 fprintf(fLFile, "%s\n", featureFileName);
mas01cr@380 119 if(times) {
mas01cr@380 120 char *timesFileName = timesFileNameTable + k*O2_FILETABLE_ENTRY_SIZE;
mas01cr@399 121 if(*timesFileName != '/') {
mas01cr@399 122 goto error;
mas01cr@399 123 }
mas01cr@380 124 fprintf(tLFile, "%s\n", timesFileName);
mas01cr@239 125 }
mas01cr@380 126 if(power) {
mas01cr@380 127 char *powerFileName = powerFileNameTable + k*O2_FILETABLE_ENTRY_SIZE;
mas01cr@399 128 if(*powerFileName != '/') {
mas01cr@399 129 goto error;
mas01cr@399 130 }
mas01cr@380 131 fprintf(pLFile, "%s\n", powerFileName);
mas01cr@239 132 }
mas01cr@380 133 } else {
mas01cr@380 134 snprintf(fName, 256, "%05d.features", k);
mas01cr@380 135 if ((ffd = open(fName, O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@399 136 goto error;
mas01cr@239 137 }
mas01cr@399 138 if ((write(ffd, &(adb->header->dim), sizeof(uint32_t))) < 0) {
mas01cr@399 139 goto error;
mas01cr@380 140 }
mas01cr@380 141
mas01cr@380 142 /* FIXME: this repeated malloc()/free() of data buffers is
mas01cr@380 143 inefficient. */
mas01cr@399 144 data_buffer_size = trackTable[k] * adb->header->dim * sizeof(double);
mas01cr@380 145
mas01cr@380 146 {
mas01cr@380 147 void *tmp = malloc(data_buffer_size);
mas01cr@380 148 if (tmp == NULL) {
mas01cr@399 149 goto error;
mas01cr@380 150 }
mas01cr@380 151 data_buffer = (double *) tmp;
mas01cr@380 152 }
mas01cr@380 153
mas01cr@399 154 if ((read(adb->fd, data_buffer, data_buffer_size)) != (ssize_t) data_buffer_size) {
mas01cr@399 155 goto error;
mas01cr@380 156 }
mas01cr@380 157
mas01cr@380 158 if ((write(ffd, data_buffer, data_buffer_size)) < 0) {
mas01cr@399 159 goto error;
mas01cr@239 160 }
mas01cr@380 161
mas01cr@380 162 free(data_buffer);
mas01cr@380 163
mas01cr@380 164 fprintf(fLFile, "%s\n", fName);
mas01cr@380 165 close(ffd);
mas01cr@399 166 ffd = 0;
mas01cr@399 167
mas01cr@380 168 if (times) {
mas01cr@380 169 snprintf(fName, 256, "%05d.times", k);
mas01cr@380 170 tFile = fopen(fName, "w");
mas01cr@380 171 for(unsigned i = 0; i < trackTable[k]; i++) {
mas01cr@380 172 // KLUDGE: specifying 16 digits of precision after the decimal
mas01cr@380 173 // point is (but check this!) sufficient to uniquely identify
mas01cr@380 174 // doubles; however, that will cause ugliness, as that's
mas01cr@380 175 // vastly too many for most values of interest. Moving to %a
mas01cr@380 176 // here and scanf() in the timesFile reading might fix this.
mas01cr@380 177 // -- CSR, 2007-10-19
mas01cr@380 178 fprintf(tFile, "%.16e\n", *(timesTable + 2*pos + 2*i));
mas01cr@380 179 }
mas01cr@380 180 fprintf(tFile, "%.16e\n", *(timesTable + 2*pos + 2*trackTable[k]-1));
mas01cr@399 181 fclose(tFile);
mas01cr@380 182
mas01cr@380 183 fprintf(tLFile, "%s\n", fName);
mas01cr@380 184 }
mas01cr@380 185
mas01cr@380 186 if (power) {
mas01cr@380 187 uint32_t one = 1;
mas01cr@380 188 snprintf(fName, 256, "%05d.power", k);
mas01cr@380 189 if ((pfd = open(fName, O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@399 190 goto error;
mas01cr@380 191 }
mas01cr@380 192 if ((write(pfd, &one, sizeof(uint32_t))) < 0) {
mas01cr@399 193 goto error;
mas01cr@380 194 }
mas01cr@380 195 if ((write(pfd, powerTable + pos, trackTable[k] * sizeof(double))) < 0) {
mas01cr@399 196 goto error;
mas01cr@380 197 }
mas01cr@380 198 fprintf(pLFile, "%s\n", fName);
mas01cr@380 199 close(pfd);
mas01cr@399 200 pfd = 0;
mas01cr@380 201 }
mas01cr@380 202
mas01cr@380 203 pos += trackTable[k];
mas01cr@380 204 std::cout << fileTable+k*O2_FILETABLE_ENTRY_SIZE << " " << trackTable[k] << std::endl;
mas01cr@380 205 }
mas01cr@239 206 }
mas01cr@239 207
mas01cr@239 208 scriptFile = fopen("restore.sh", "w");
mas01cr@239 209 fprintf(scriptFile, "\
mas01cr@239 210 #! /bin/sh\n\
mas01cr@239 211 #\n\
mas01cr@239 212 # usage: AUDIODB=/path/to/audioDB sh ./restore.sh <newdb>\n\
mas01cr@239 213 \n\
mas01cr@239 214 if [ -z \"${AUDIODB}\" ]; then echo set AUDIODB variable; exit 1; fi\n\
mas01cr@239 215 if [ -z \"$1\" ]; then echo usage: $0 newdb; exit 1; fi\n\n\
mas01cr@256 216 \"${AUDIODB}\" -d \"$1\" -N --datasize=%d --ntracks=%d --datadim=%d\n",
mas01cr@399 217 (int) ((adb->header->timesTableOffset - adb->header->dataOffset) / (1024*1024)),
mas01cr@256 218 // fileTable entries (char[256]) are bigger than trackTable
mas01cr@256 219 // (int), so the granularity of page aligning is finer.
mas01cr@399 220 (int) ((adb->header->trackTableOffset - adb->header->fileTableOffset) / O2_FILETABLE_ENTRY_SIZE),
mas01cr@399 221 (int) ceil(((double) (adb->header->timesTableOffset - adb->header->dataOffset)) / ((double) (adb->header->dbSize - adb->header->l2normTableOffset))));
mas01cr@399 222 if(adb->header->flags & O2_FLAG_L2NORM) {
mas01cr@239 223 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -L\n");
mas01cr@239 224 }
mas01cr@239 225 if(power) {
mas01cr@239 226 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -P\n");
mas01cr@239 227 }
mas01cr@239 228 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -B -F featureList.txt -K keyList.txt");
mas01cr@239 229 if(times) {
mas01cr@239 230 fprintf(scriptFile, " -T timesList.txt");
mas01cr@239 231 }
mas01cr@239 232 if(power) {
mas01cr@239 233 fprintf(scriptFile, " -W powerList.txt");
mas01cr@239 234 }
mas01cr@239 235 fprintf(scriptFile, "\n");
mas01cr@239 236 fclose(scriptFile);
mas01cr@239 237
mas01cr@239 238 fclose(fLFile);
mas01cr@239 239 if(times) {
mas01cr@239 240 fclose(tLFile);
mas01cr@239 241 }
mas01cr@239 242 if(power) {
mas01cr@239 243 fclose(pLFile);
mas01cr@239 244 }
mas01cr@239 245 fclose(kLFile);
mas01cr@239 246
mas01cr@399 247 maybe_munmap(fileTable, fileTableLength);
mas01cr@399 248 maybe_munmap(trackTable, trackTableLength);
mas01cr@399 249 maybe_munmap(timesTable, timesTableLength);
mas01cr@399 250 maybe_munmap(powerTable, powerTableLength);
mas01cr@399 251 maybe_munmap(featureFileNameTable, fileTableLength);
mas01cr@399 252 maybe_munmap(timesFileNameTable, fileTableLength);
mas01cr@399 253 maybe_munmap(powerFileNameTable, fileTableLength);
mas01cr@399 254
mas01cr@399 255 if((chdir(cwd)) < 0) {
mas01cr@399 256 /* don't goto error because the error handling will try to
mas01cr@399 257 * chdir() */
mas01cr@399 258 return 1;
mas01cr@399 259 }
mas01cr@399 260
mas01cr@399 261 return 0;
mas01cr@399 262
mas01cr@399 263 error:
mas01cr@399 264 if(fLFile) {
mas01cr@399 265 fclose(fLFile);
mas01cr@399 266 } else if(fLfd) {
mas01cr@399 267 close(fLfd);
mas01cr@399 268 }
mas01cr@399 269 if(tLFile) {
mas01cr@399 270 fclose(tLFile);
mas01cr@399 271 } else if(tLfd) {
mas01cr@399 272 close(fLfd);
mas01cr@399 273 }
mas01cr@399 274 if(pLFile) {
mas01cr@399 275 fclose(pLFile);
mas01cr@399 276 } else if(pLfd) {
mas01cr@399 277 close(pLfd);
mas01cr@399 278 }
mas01cr@399 279 if(kLFile) {
mas01cr@399 280 fclose(kLFile);
mas01cr@399 281 } else if(kLfd) {
mas01cr@399 282 close(kLfd);
mas01cr@399 283 }
mas01cr@399 284 if(scriptFile) {
mas01cr@399 285 fclose(scriptFile);
mas01cr@399 286 }
mas01cr@399 287
mas01cr@399 288 maybe_munmap(fileTable, fileTableLength);
mas01cr@399 289 maybe_munmap(trackTable, trackTableLength);
mas01cr@399 290 maybe_munmap(timesTable, timesTableLength);
mas01cr@399 291 maybe_munmap(powerTable, powerTableLength);
mas01cr@399 292 maybe_munmap(featureFileNameTable, fileTableLength);
mas01cr@399 293 maybe_munmap(timesFileNameTable, fileTableLength);
mas01cr@399 294 maybe_munmap(powerFileNameTable, fileTableLength);
mas01cr@399 295
mas01cr@399 296 if(directory_changed) {
mas01cr@399 297 chdir(cwd);
mas01cr@399 298 }
mas01cr@399 299 return 1;
mas01cr@239 300 }