annotate create.cpp @ 601:82d23418d867

Fix some fd leaks in the command-line binary Strictly speaking, they're not really leaks, because the only codepath that suffers from these leaks exits immediately afterwards. On the other hand, this fix makes valgrind on e.g. tests/0025 happier, going from 5 errors to none.
author mas01cr
date Fri, 14 Aug 2009 16:39:32 +0000
parents 6ad0a6e67d4c
children
rev   line source
mas01cr@498 1 extern "C" {
mas01cr@498 2 #include "audioDB_API.h"
mas01cr@498 3 }
mas01cr@498 4 #include "audioDB-internals.h"
mas01cr@239 5
mas01cr@239 6 /* Make a new database.
mas01cr@239 7
mas01cr@509 8 (FIXME: this text, in particular the conditional, will not be true
mas01cr@509 9 once we implement create flags rather than defaulting on format based
mas01cr@509 10 on the requested size arguments)
mas01cr@509 11
mas01cr@509 12 IF size(featuredata) < ADB_FIXME_LARGE_ADB_SIZE
mas01cr@239 13 The database consists of:
mas01cr@239 14
mas01cr@509 15 * a header (see adb_header_t definition);
mas01cr@239 16 * keyTable: list of keys of tracks;
mas01cr@239 17 * trackTable: Maps implicit feature index to a feature vector
mas01cr@239 18 matrix (sizes of tracks)
mas01cr@239 19 * featureTable: Lots of doubles;
mas01cr@239 20 * timesTable: (start,end) time points for each feature vector;
mas01cr@239 21 * powerTable: associated power for each feature vector;
mas01cr@239 22 * l2normTable: squared l2norms for each feature vector.
mas01cr@498 23
mas01mc@324 24 ELSE the database consists of:
mas01cr@498 25
mas01cr@509 26 * a header (see adb_header_t definition);
mas01mc@324 27 * keyTable: list of keys of tracks
mas01mc@324 28 * trackTable: sizes of tracks
mas01mc@324 29 * featureTable: list of feature file names
mas01mc@324 30 * timesTable: list of times file names
mas01mc@324 31 * powerTable: list of power file names
mas01mc@324 32
mas01cr@239 33 */
mas01cr@239 34
mas01cr@498 35 adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim) {
mas01cr@498 36 int fd;
mas01cr@498 37 adb_header_t *header = 0;
mas01cr@498 38 off_t databytes, auxbytes;
mas01cr@498 39 if(datasize == 0) {
mas01cr@509 40 datasize = ADB_DEFAULT_DATASIZE;
mas01cr@498 41 }
mas01cr@498 42 if(ntracks == 0) {
mas01cr@509 43 ntracks = ADB_DEFAULT_NTRACKS;
mas01cr@498 44 }
mas01cr@498 45 if(datadim == 0) {
mas01cr@509 46 datadim = ADB_DEFAULT_DATADIM;
mas01cr@498 47 }
mas01cr@239 48
mas01cr@595 49 if ((fd = open(path, O_RDWR|O_CREAT|O_EXCL, ADB_CREAT_PERMISSIONS)) < 0) {
mas01cr@498 50 goto error;
mas01cr@498 51 }
mas01cr@239 52
mas01cr@498 53 header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@498 54 if(!header) {
mas01cr@498 55 goto error;
mas01cr@498 56 }
mas01cr@239 57
mas01cr@239 58 // Initialize header
mas01cr@509 59 header->magic = ADB_MAGIC;
mas01cr@509 60 header->version = ADB_FORMAT_VERSION;
mas01cr@498 61 header->numFiles = 0;
mas01cr@498 62 header->dim = 0;
mas01cr@498 63 header->flags = 0;
mas01cr@509 64 header->headerSize = ADB_HEADER_SIZE;
mas01cr@498 65 header->length = 0;
mas01cr@509 66 header->fileTableOffset = align_page_up(ADB_HEADER_SIZE);
mas01cr@509 67 header->trackTableOffset = align_page_up(header->fileTableOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks); //
mas01cr@509 68 header->dataOffset = align_page_up(header->trackTableOffset + ADB_TRACKTABLE_ENTRY_SIZE*ntracks);
mas01cr@256 69
mas01cr@498 70 databytes = ((off_t) datasize) * 1024 * 1024;
mas01cr@498 71 auxbytes = databytes / datadim;
mas01cr@498 72
mas01mc@324 73 // If database will fit in a single file the vectors are copied into the AudioDB instance
mas01mc@324 74 // Else all the vectors are left on the FileSystem and we use the dataOffset as storage
mas01mc@324 75 // for the location of the features, powers and times files (assuming that arbitrary keys are used for the fileTable)
mas01cr@509 76 if(ntracks < ADB_FIXME_LARGE_ADB_NTRACKS && datasize < ADB_FIXME_LARGE_ADB_SIZE) {
mas01cr@509 77 header->timesTableOffset = align_page_up(header->dataOffset + databytes);
mas01cr@509 78 header->powerTableOffset = align_page_up(header->timesTableOffset + 2*auxbytes);
mas01cr@509 79 header->l2normTableOffset = align_page_up(header->powerTableOffset + auxbytes);
mas01cr@509 80 header->dbSize = align_page_up(header->l2normTableOffset + auxbytes);
mas01cr@509 81 } else { // Create REFERENCES ADB, features and powers kept on filesystem
mas01cr@509 82 header->flags |= ADB_HEADER_FLAG_REFERENCES;
mas01cr@509 83 header->timesTableOffset = align_page_up(header->dataOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@509 84 header->powerTableOffset = align_page_up(header->timesTableOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@509 85 header->l2normTableOffset = align_page_up(header->powerTableOffset + ADB_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@498 86 header->dbSize = header->l2normTableOffset;
mas01mc@324 87 }
mas01cr@239 88
mas01cr@509 89 write_or_goto_error(fd, header, ADB_HEADER_SIZE);
mas01cr@239 90
mas01cr@596 91 // go to the location corresponding to the last byte of the database
mas01cr@596 92 // file, and write a byte there.
mas01cr@596 93 lseek_set_or_goto_error(fd, header->dbSize - 1);
mas01cr@498 94 write_or_goto_error(fd, "", 1);
mas01cr@239 95
mas01cr@498 96 free(header);
mas01cr@498 97 return audiodb_open(path, O_RDWR);
mas01cr@498 98
mas01cr@498 99 error:
mas01cr@596 100 maybe_free(header);
mas01cr@498 101 return NULL;
mas01cr@239 102 }