annotate dump.cpp @ 770:c54bc2ffbf92 tip

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