annotate dump.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@498 7 int audiodb_dump(adb_t *adb, const char *output) {
mas01cr@498 8 char *fileTable = 0; /* key_table */
mas01cr@498 9 double *timesTable = 0; /* timestamps_table */
mas01cr@498 10 double *powerTable = 0; /* power_table */
mas01cr@498 11
mas01cr@498 12 size_t fileTableLength = 0;
mas01cr@498 13 size_t timesTableLength = 0;
mas01cr@498 14 size_t powerTableLength = 0;
mas01cr@498 15
mas01cr@498 16 char *featureFileNameTable = 0;
mas01cr@498 17 char *powerFileNameTable = 0;
mas01cr@498 18 char *timesFileNameTable = 0;
mas01cr@498 19
mas01cr@498 20 char cwd[PATH_MAX];
mas01cr@498 21 int directory_changed = 0;
mas01cr@498 22
mas01cr@498 23 int fLfd = 0, tLfd = 0, pLfd = 0, kLfd = 0;
mas01cr@498 24 FILE *fLFile = 0, *tLFile = 0, *pLFile = 0, *kLFile = 0;
mas01cr@498 25
mas01cr@498 26 int times, power;
mas01cr@498 27
mas01cr@498 28 char fName[256];
mas01cr@498 29 int ffd, pfd;
mas01cr@498 30 FILE *tFile;
mas01cr@498 31 unsigned pos = 0;
mas01cr@498 32 double *data_buffer;
mas01cr@498 33 size_t data_buffer_size;
mas01cr@498 34 FILE *scriptFile = 0;
mas01cr@498 35
mas01cr@498 36 unsigned nfiles = adb->header->numFiles;
mas01cr@498 37
mas01cr@498 38 if(adb->header->length > 0) {
mas01cr@498 39 fileTableLength = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE);
mas01cr@498 40 if(!(adb->header->flags & O2_FLAG_LARGE_ADB)) {
mas01cr@498 41 off_t length = adb->header->length;
mas01cr@498 42 unsigned dim = adb->header->dim;
mas01cr@498 43 timesTableLength = ALIGN_PAGE_UP(2*length/dim);
mas01cr@498 44 powerTableLength = ALIGN_PAGE_UP(length/dim);
mas01cr@498 45 }
mas01cr@498 46
mas01cr@498 47 mmap_or_goto_error(char *, fileTable, adb->header->fileTableOffset, fileTableLength);
mas01cr@498 48 if (adb->header->flags & O2_FLAG_LARGE_ADB) {
mas01cr@498 49 mmap_or_goto_error(char *, featureFileNameTable, adb->header->dataOffset, fileTableLength);
mas01cr@498 50 mmap_or_goto_error(char *, powerFileNameTable, adb->header->powerTableOffset, fileTableLength);
mas01cr@498 51 mmap_or_goto_error(char *, timesFileNameTable, adb->header->timesTableOffset, fileTableLength);
mas01cr@498 52 } else {
mas01cr@498 53 mmap_or_goto_error(double *, powerTable, adb->header->powerTableOffset, powerTableLength);
mas01cr@498 54 mmap_or_goto_error(double *, timesTable, adb->header->timesTableOffset, timesTableLength);
mas01cr@498 55 }
mas01cr@239 56 }
mas01cr@239 57
mas01cr@239 58 if((mkdir(output, S_IRWXU|S_IRWXG|S_IRWXO)) < 0) {
mas01cr@498 59 goto error;
mas01cr@239 60 }
mas01cr@239 61
mas01cr@239 62 if ((getcwd(cwd, PATH_MAX)) == 0) {
mas01cr@498 63 goto error;
mas01cr@239 64 }
mas01cr@239 65
mas01cr@498 66 /* FIXME: Hrm. How does chdir(2) interact with threads? Does each
mas01cr@498 67 * thread have its own working directory? */
mas01cr@239 68 if((chdir(output)) < 0) {
mas01cr@498 69 goto error;
mas01cr@498 70 }
mas01cr@498 71 directory_changed = 1;
mas01cr@498 72
mas01cr@498 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@498 74 goto error;
mas01cr@239 75 }
mas01cr@239 76
mas01cr@498 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@498 80 goto error;
mas01cr@239 81 }
mas01cr@239 82 }
mas01cr@239 83
mas01cr@498 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@498 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@498 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@498 105 lseek(adb->fd, adb->header->dataOffset, SEEK_SET);
mas01cr@498 106
mas01cr@498 107 for(unsigned k = 0; k < nfiles; k++) {
mas01cr@256 108 fprintf(kLFile, "%s\n", fileTable + k*O2_FILETABLE_ENTRY_SIZE);
mas01cr@498 109 if(adb->header->flags & O2_FLAG_LARGE_ADB) {
mas01cr@380 110 char *featureFileName = featureFileNameTable+k*O2_FILETABLE_ENTRY_SIZE;
mas01cr@498 111 if(*featureFileName != '/') {
mas01cr@498 112 goto error;
mas01cr@498 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@498 117 if(*timesFileName != '/') {
mas01cr@498 118 goto error;
mas01cr@498 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@498 124 if(*powerFileName != '/') {
mas01cr@498 125 goto error;
mas01cr@498 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@498 132 goto error;
mas01cr@239 133 }
mas01cr@498 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@498 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@498 143 goto error;
mas01cr@380 144 }
mas01cr@380 145 data_buffer = (double *) tmp;
mas01cr@380 146 }
mas01cr@380 147
mas01cr@498 148 if ((read(adb->fd, data_buffer, data_buffer_size)) != (ssize_t) data_buffer_size) {
mas01cr@498 149 goto error;
mas01cr@380 150 }
mas01cr@380 151
mas01cr@498 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@498 158 ffd = 0;
mas01cr@498 159
mas01cr@380 160 if (times) {
mas01cr@380 161 snprintf(fName, 256, "%05d.times", k);
mas01cr@380 162 tFile = fopen(fName, "w");
mas01cr@498 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@498 172 fprintf(tFile, "%.16e\n", *(timesTable + 2*pos + 2*(*adb->track_lengths)[k]-1));
mas01cr@498 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@498 182 goto error;
mas01cr@380 183 }
mas01cr@498 184 write_or_goto_error(pfd, &one, sizeof(uint32_t));
mas01cr@498 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@498 188 pfd = 0;
mas01cr@380 189 }
mas01cr@380 190
mas01cr@498 191 pos += (*adb->track_lengths)[k];
mas01cr@498 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@498 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@498 208 (int) ((adb->header->trackTableOffset - adb->header->fileTableOffset) / O2_FILETABLE_ENTRY_SIZE),
mas01cr@498 209 (int) ceil(((double) (adb->header->timesTableOffset - adb->header->dataOffset)) / ((double) (adb->header->dbSize - adb->header->l2normTableOffset))));
mas01cr@498 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@498 235 maybe_munmap(fileTable, fileTableLength);
mas01cr@498 236 maybe_munmap(timesTable, timesTableLength);
mas01cr@498 237 maybe_munmap(powerTable, powerTableLength);
mas01cr@498 238 maybe_munmap(featureFileNameTable, fileTableLength);
mas01cr@498 239 maybe_munmap(timesFileNameTable, fileTableLength);
mas01cr@498 240 maybe_munmap(powerFileNameTable, fileTableLength);
mas01mc@334 241
mas01cr@498 242 if((chdir(cwd)) < 0) {
mas01cr@498 243 /* don't goto error because the error handling will try to
mas01cr@498 244 * chdir() */
mas01cr@498 245 return 1;
mas01mc@334 246 }
mas01mc@334 247
mas01cr@498 248 return 0;
mas01mc@334 249
mas01cr@498 250 error:
mas01cr@498 251 if(fLFile) {
mas01cr@498 252 fclose(fLFile);
mas01cr@498 253 } else if(fLfd) {
mas01cr@498 254 close(fLfd);
mas01cr@498 255 }
mas01cr@498 256 if(tLFile) {
mas01cr@498 257 fclose(tLFile);
mas01cr@498 258 } else if(tLfd) {
mas01cr@498 259 close(fLfd);
mas01cr@498 260 }
mas01cr@498 261 if(pLFile) {
mas01cr@498 262 fclose(pLFile);
mas01cr@498 263 } else if(pLfd) {
mas01cr@498 264 close(pLfd);
mas01cr@498 265 }
mas01cr@498 266 if(kLFile) {
mas01cr@498 267 fclose(kLFile);
mas01cr@498 268 } else if(kLfd) {
mas01cr@498 269 close(kLfd);
mas01cr@498 270 }
mas01cr@498 271 if(scriptFile) {
mas01cr@498 272 fclose(scriptFile);
mas01mc@334 273 }
mas01mc@334 274
mas01cr@498 275 maybe_munmap(fileTable, fileTableLength);
mas01cr@498 276 maybe_munmap(timesTable, timesTableLength);
mas01cr@498 277 maybe_munmap(powerTable, powerTableLength);
mas01cr@498 278 maybe_munmap(featureFileNameTable, fileTableLength);
mas01cr@498 279 maybe_munmap(timesFileNameTable, fileTableLength);
mas01cr@498 280 maybe_munmap(powerFileNameTable, fileTableLength);
mas01cr@498 281
mas01cr@498 282 if(directory_changed) {
mas01cr@498 283 int gcc_warning_workaround = chdir(cwd);
mas01cr@498 284 directory_changed = gcc_warning_workaround;
mas01mc@334 285 }
mas01cr@498 286 return 1;
mas01mc@334 287 }