annotate dump.cpp @ 497:9d8aee621afb api-inversion

More libtests fixups. Include audiodb_close() calls everywhere (whoops). Add the facility to run tests under valgrind. Unfortunately the error-exitcode flag doesn't actually cause an error exit if the only thing wrong is memory leaks, but it will if there are actual memory errors, which is a start.
author mas01cr
date Sat, 10 Jan 2009 16:07:43 +0000
parents 62a0515f59be
children
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 double *timesTable = 0; /* timestamps_table */
mas01cr@399 10 double *powerTable = 0; /* power_table */
mas01cr@399 11
mas01cr@399 12 size_t fileTableLength = 0;
mas01cr@399 13 size_t timesTableLength = 0;
mas01cr@399 14 size_t powerTableLength = 0;
mas01cr@399 15
mas01cr@399 16 char *featureFileNameTable = 0;
mas01cr@399 17 char *powerFileNameTable = 0;
mas01cr@399 18 char *timesFileNameTable = 0;
mas01cr@399 19
mas01cr@399 20 char cwd[PATH_MAX];
mas01cr@399 21 int directory_changed = 0;
mas01cr@399 22
mas01cr@399 23 int fLfd = 0, tLfd = 0, pLfd = 0, kLfd = 0;
mas01cr@399 24 FILE *fLFile = 0, *tLFile = 0, *pLFile = 0, *kLFile = 0;
mas01cr@399 25
mas01cr@399 26 int times, power;
mas01cr@399 27
mas01cr@399 28 char fName[256];
mas01cr@399 29 int ffd, pfd;
mas01cr@399 30 FILE *tFile;
mas01cr@399 31 unsigned pos = 0;
mas01cr@399 32 double *data_buffer;
mas01cr@399 33 size_t data_buffer_size;
mas01cr@399 34 FILE *scriptFile = 0;
mas01cr@399 35
mas01cr@399 36 unsigned nfiles = adb->header->numFiles;
mas01cr@399 37
mas01cr@399 38 if(adb->header->length > 0) {
mas01cr@399 39 fileTableLength = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@399 40 if(!(adb->header->flags & O2_FLAG_LARGE_ADB)) {
mas01cr@399 41 off_t length = adb->header->length;
mas01cr@399 42 unsigned dim = adb->header->dim;
mas01cr@399 43 timesTableLength = ALIGN_PAGE_UP(2*length/dim);
mas01cr@399 44 powerTableLength = ALIGN_PAGE_UP(length/dim);
mas01cr@399 45 }
mas01cr@399 46
mas01cr@399 47 mmap_or_goto_error(char *, fileTable, adb->header->fileTableOffset, fileTableLength);
mas01cr@399 48 if (adb->header->flags & O2_FLAG_LARGE_ADB) {
mas01cr@399 49 mmap_or_goto_error(char *, featureFileNameTable, adb->header->dataOffset, fileTableLength);
mas01cr@399 50 mmap_or_goto_error(char *, powerFileNameTable, adb->header->powerTableOffset, fileTableLength);
mas01cr@399 51 mmap_or_goto_error(char *, timesFileNameTable, adb->header->timesTableOffset, fileTableLength);
mas01cr@399 52 } else {
mas01cr@399 53 mmap_or_goto_error(double *, powerTable, adb->header->powerTableOffset, powerTableLength);
mas01cr@399 54 mmap_or_goto_error(double *, timesTable, adb->header->timesTableOffset, timesTableLength);
mas01cr@399 55 }
mas01cr@239 56 }
mas01cr@239 57
mas01cr@239 58 if((mkdir(output, S_IRWXU|S_IRWXG|S_IRWXO)) < 0) {
mas01cr@399 59 goto error;
mas01cr@239 60 }
mas01cr@239 61
mas01cr@239 62 if ((getcwd(cwd, PATH_MAX)) == 0) {
mas01cr@399 63 goto error;
mas01cr@239 64 }
mas01cr@239 65
mas01cr@399 66 /* FIXME: Hrm. How does chdir(2) interact with threads? Does each
mas01cr@399 67 * thread have its own working directory? */
mas01cr@239 68 if((chdir(output)) < 0) {
mas01cr@399 69 goto error;
mas01cr@399 70 }
mas01cr@399 71 directory_changed = 1;
mas01cr@399 72
mas01cr@399 73 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 74 goto error;
mas01cr@239 75 }
mas01cr@239 76
mas01cr@399 77 times = adb->header->flags & O2_FLAG_TIMES;
mas01cr@239 78 if (times) {
mas01cr@239 79 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 80 goto error;
mas01cr@239 81 }
mas01cr@239 82 }
mas01cr@239 83
mas01cr@399 84 power = adb->header->flags & O2_FLAG_POWER;
mas01cr@239 85 if (power) {
mas01cr@239 86 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 87 goto error;
mas01cr@239 88 }
mas01cr@239 89 }
mas01cr@239 90
mas01cr@239 91 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 92 goto error;
mas01cr@239 93 }
mas01cr@239 94
mas01cr@239 95 /* can these fail? I sincerely hope not. */
mas01cr@239 96 fLFile = fdopen(fLfd, "w");
mas01cr@239 97 if (times) {
mas01cr@239 98 tLFile = fdopen(tLfd, "w");
mas01cr@239 99 }
mas01cr@239 100 if (power) {
mas01cr@239 101 pLFile = fdopen(pLfd, "w");
mas01cr@239 102 }
mas01cr@239 103 kLFile = fdopen(kLfd, "w");
mas01cr@239 104
mas01cr@399 105 lseek(adb->fd, adb->header->dataOffset, SEEK_SET);
mas01cr@399 106
mas01cr@399 107 for(unsigned k = 0; k < nfiles; k++) {
mas01cr@256 108 fprintf(kLFile, "%s\n", fileTable + k*O2_FILETABLE_ENTRY_SIZE);
mas01cr@399 109 if(adb->header->flags & O2_FLAG_LARGE_ADB) {
mas01cr@380 110 char *featureFileName = featureFileNameTable+k*O2_FILETABLE_ENTRY_SIZE;
mas01cr@399 111 if(*featureFileName != '/') {
mas01cr@399 112 goto error;
mas01cr@399 113 }
mas01cr@380 114 fprintf(fLFile, "%s\n", featureFileName);
mas01cr@380 115 if(times) {
mas01cr@380 116 char *timesFileName = timesFileNameTable + k*O2_FILETABLE_ENTRY_SIZE;
mas01cr@399 117 if(*timesFileName != '/') {
mas01cr@399 118 goto error;
mas01cr@399 119 }
mas01cr@380 120 fprintf(tLFile, "%s\n", timesFileName);
mas01cr@239 121 }
mas01cr@380 122 if(power) {
mas01cr@380 123 char *powerFileName = powerFileNameTable + k*O2_FILETABLE_ENTRY_SIZE;
mas01cr@399 124 if(*powerFileName != '/') {
mas01cr@399 125 goto error;
mas01cr@399 126 }
mas01cr@380 127 fprintf(pLFile, "%s\n", powerFileName);
mas01cr@239 128 }
mas01cr@380 129 } else {
mas01cr@380 130 snprintf(fName, 256, "%05d.features", k);
mas01cr@380 131 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 132 goto error;
mas01cr@239 133 }
mas01cr@410 134 write_or_goto_error(ffd, &(adb->header->dim), sizeof(uint32_t));
mas01cr@380 135
mas01cr@380 136 /* FIXME: this repeated malloc()/free() of data buffers is
mas01cr@380 137 inefficient. */
mas01cr@432 138 data_buffer_size = (*adb->track_lengths)[k] * adb->header->dim * sizeof(double);
mas01cr@380 139
mas01cr@380 140 {
mas01cr@380 141 void *tmp = malloc(data_buffer_size);
mas01cr@380 142 if (tmp == NULL) {
mas01cr@399 143 goto error;
mas01cr@380 144 }
mas01cr@380 145 data_buffer = (double *) tmp;
mas01cr@380 146 }
mas01cr@380 147
mas01cr@399 148 if ((read(adb->fd, data_buffer, data_buffer_size)) != (ssize_t) data_buffer_size) {
mas01cr@399 149 goto error;
mas01cr@380 150 }
mas01cr@380 151
mas01cr@410 152 write_or_goto_error(ffd, data_buffer, data_buffer_size);
mas01cr@380 153
mas01cr@380 154 free(data_buffer);
mas01cr@380 155
mas01cr@380 156 fprintf(fLFile, "%s\n", fName);
mas01cr@380 157 close(ffd);
mas01cr@399 158 ffd = 0;
mas01cr@399 159
mas01cr@380 160 if (times) {
mas01cr@380 161 snprintf(fName, 256, "%05d.times", k);
mas01cr@380 162 tFile = fopen(fName, "w");
mas01cr@432 163 for(unsigned i = 0; i < (*adb->track_lengths)[k]; i++) {
mas01cr@380 164 // KLUDGE: specifying 16 digits of precision after the decimal
mas01cr@380 165 // point is (but check this!) sufficient to uniquely identify
mas01cr@380 166 // doubles; however, that will cause ugliness, as that's
mas01cr@380 167 // vastly too many for most values of interest. Moving to %a
mas01cr@380 168 // here and scanf() in the timesFile reading might fix this.
mas01cr@380 169 // -- CSR, 2007-10-19
mas01cr@380 170 fprintf(tFile, "%.16e\n", *(timesTable + 2*pos + 2*i));
mas01cr@380 171 }
mas01cr@432 172 fprintf(tFile, "%.16e\n", *(timesTable + 2*pos + 2*(*adb->track_lengths)[k]-1));
mas01cr@399 173 fclose(tFile);
mas01cr@380 174
mas01cr@380 175 fprintf(tLFile, "%s\n", fName);
mas01cr@380 176 }
mas01cr@380 177
mas01cr@380 178 if (power) {
mas01cr@380 179 uint32_t one = 1;
mas01cr@380 180 snprintf(fName, 256, "%05d.power", k);
mas01cr@380 181 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 182 goto error;
mas01cr@380 183 }
mas01cr@410 184 write_or_goto_error(pfd, &one, sizeof(uint32_t));
mas01cr@432 185 write_or_goto_error(pfd, powerTable + pos, (*adb->track_lengths)[k] * sizeof(double));
mas01cr@380 186 fprintf(pLFile, "%s\n", fName);
mas01cr@380 187 close(pfd);
mas01cr@399 188 pfd = 0;
mas01cr@380 189 }
mas01cr@380 190
mas01cr@432 191 pos += (*adb->track_lengths)[k];
mas01cr@432 192 std::cout << fileTable+k*O2_FILETABLE_ENTRY_SIZE << " " << (*adb->track_lengths)[k] << std::endl;
mas01cr@380 193 }
mas01cr@239 194 }
mas01cr@239 195
mas01cr@239 196 scriptFile = fopen("restore.sh", "w");
mas01cr@239 197 fprintf(scriptFile, "\
mas01cr@239 198 #! /bin/sh\n\
mas01cr@239 199 #\n\
mas01cr@239 200 # usage: AUDIODB=/path/to/audioDB sh ./restore.sh <newdb>\n\
mas01cr@239 201 \n\
mas01cr@239 202 if [ -z \"${AUDIODB}\" ]; then echo set AUDIODB variable; exit 1; fi\n\
mas01cr@239 203 if [ -z \"$1\" ]; then echo usage: $0 newdb; exit 1; fi\n\n\
mas01cr@256 204 \"${AUDIODB}\" -d \"$1\" -N --datasize=%d --ntracks=%d --datadim=%d\n",
mas01cr@399 205 (int) ((adb->header->timesTableOffset - adb->header->dataOffset) / (1024*1024)),
mas01cr@256 206 // fileTable entries (char[256]) are bigger than trackTable
mas01cr@256 207 // (int), so the granularity of page aligning is finer.
mas01cr@399 208 (int) ((adb->header->trackTableOffset - adb->header->fileTableOffset) / O2_FILETABLE_ENTRY_SIZE),
mas01cr@399 209 (int) ceil(((double) (adb->header->timesTableOffset - adb->header->dataOffset)) / ((double) (adb->header->dbSize - adb->header->l2normTableOffset))));
mas01cr@399 210 if(adb->header->flags & O2_FLAG_L2NORM) {
mas01cr@239 211 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -L\n");
mas01cr@239 212 }
mas01cr@239 213 if(power) {
mas01cr@239 214 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -P\n");
mas01cr@239 215 }
mas01cr@239 216 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -B -F featureList.txt -K keyList.txt");
mas01cr@239 217 if(times) {
mas01cr@239 218 fprintf(scriptFile, " -T timesList.txt");
mas01cr@239 219 }
mas01cr@239 220 if(power) {
mas01cr@239 221 fprintf(scriptFile, " -W powerList.txt");
mas01cr@239 222 }
mas01cr@239 223 fprintf(scriptFile, "\n");
mas01cr@239 224 fclose(scriptFile);
mas01cr@239 225
mas01cr@239 226 fclose(fLFile);
mas01cr@239 227 if(times) {
mas01cr@239 228 fclose(tLFile);
mas01cr@239 229 }
mas01cr@239 230 if(power) {
mas01cr@239 231 fclose(pLFile);
mas01cr@239 232 }
mas01cr@239 233 fclose(kLFile);
mas01cr@239 234
mas01cr@399 235 maybe_munmap(fileTable, fileTableLength);
mas01cr@399 236 maybe_munmap(timesTable, timesTableLength);
mas01cr@399 237 maybe_munmap(powerTable, powerTableLength);
mas01cr@399 238 maybe_munmap(featureFileNameTable, fileTableLength);
mas01cr@399 239 maybe_munmap(timesFileNameTable, fileTableLength);
mas01cr@399 240 maybe_munmap(powerFileNameTable, fileTableLength);
mas01cr@399 241
mas01cr@399 242 if((chdir(cwd)) < 0) {
mas01cr@399 243 /* don't goto error because the error handling will try to
mas01cr@399 244 * chdir() */
mas01cr@399 245 return 1;
mas01cr@399 246 }
mas01cr@399 247
mas01cr@399 248 return 0;
mas01cr@399 249
mas01cr@399 250 error:
mas01cr@399 251 if(fLFile) {
mas01cr@399 252 fclose(fLFile);
mas01cr@399 253 } else if(fLfd) {
mas01cr@399 254 close(fLfd);
mas01cr@399 255 }
mas01cr@399 256 if(tLFile) {
mas01cr@399 257 fclose(tLFile);
mas01cr@399 258 } else if(tLfd) {
mas01cr@399 259 close(fLfd);
mas01cr@399 260 }
mas01cr@399 261 if(pLFile) {
mas01cr@399 262 fclose(pLFile);
mas01cr@399 263 } else if(pLfd) {
mas01cr@399 264 close(pLfd);
mas01cr@399 265 }
mas01cr@399 266 if(kLFile) {
mas01cr@399 267 fclose(kLFile);
mas01cr@399 268 } else if(kLfd) {
mas01cr@399 269 close(kLfd);
mas01cr@399 270 }
mas01cr@399 271 if(scriptFile) {
mas01cr@399 272 fclose(scriptFile);
mas01cr@399 273 }
mas01cr@399 274
mas01cr@399 275 maybe_munmap(fileTable, fileTableLength);
mas01cr@399 276 maybe_munmap(timesTable, timesTableLength);
mas01cr@399 277 maybe_munmap(powerTable, powerTableLength);
mas01cr@399 278 maybe_munmap(featureFileNameTable, fileTableLength);
mas01cr@399 279 maybe_munmap(timesFileNameTable, fileTableLength);
mas01cr@399 280 maybe_munmap(powerFileNameTable, fileTableLength);
mas01cr@399 281
mas01cr@399 282 if(directory_changed) {
mas01cr@410 283 int gcc_warning_workaround = chdir(cwd);
mas01cr@410 284 directory_changed = gcc_warning_workaround;
mas01cr@399 285 }
mas01cr@399 286 return 1;
mas01cr@239 287 }