annotate create.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 f2e2d1ffcc4e 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 }
mas01cr@498 5 #include "audioDB-internals.h"
mas01cr@239 6
mas01cr@239 7 /* Make a new database.
mas01cr@239 8
mas01cr@498 9 IF size(featuredata) < O2_LARGE_ADB_SIZE
mas01cr@239 10 The database consists of:
mas01cr@239 11
mas01cr@239 12 * a header (see dbTableHeader struct definition);
mas01cr@239 13 * keyTable: list of keys of tracks;
mas01cr@239 14 * trackTable: Maps implicit feature index to a feature vector
mas01cr@239 15 matrix (sizes of tracks)
mas01cr@239 16 * featureTable: Lots of doubles;
mas01cr@239 17 * timesTable: (start,end) time points for each feature vector;
mas01cr@239 18 * powerTable: associated power for each feature vector;
mas01cr@239 19 * l2normTable: squared l2norms for each feature vector.
mas01cr@498 20
mas01mc@324 21 ELSE the database consists of:
mas01cr@498 22
mas01mc@324 23 * a header (see dbTableHeader struct definition);
mas01mc@324 24 * keyTable: list of keys of tracks
mas01mc@324 25 * trackTable: sizes of tracks
mas01mc@324 26 * featureTable: list of feature file names
mas01mc@324 27 * timesTable: list of times file names
mas01mc@324 28 * powerTable: list of power file names
mas01mc@324 29
mas01cr@239 30 */
mas01cr@239 31
mas01cr@498 32 adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim) {
mas01cr@498 33 int fd;
mas01cr@498 34 adb_header_t *header = 0;
mas01cr@498 35 off_t databytes, auxbytes;
mas01cr@498 36 if(datasize == 0) {
mas01cr@498 37 datasize = O2_DEFAULT_DATASIZE;
mas01cr@498 38 }
mas01cr@498 39 if(ntracks == 0) {
mas01cr@498 40 ntracks = O2_DEFAULT_NTRACKS;
mas01cr@498 41 }
mas01cr@498 42 if(datadim == 0) {
mas01cr@498 43 datadim = O2_DEFAULT_DATADIM;
mas01cr@498 44 }
mas01cr@239 45
mas01cr@498 46 if ((fd = open(path, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@498 47 goto error;
mas01cr@498 48 }
mas01cr@498 49 if (acquire_lock(fd, true)) {
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@498 59 header->magic = O2_MAGIC;
mas01cr@498 60 header->version = O2_FORMAT_VERSION;
mas01cr@498 61 header->numFiles = 0;
mas01cr@498 62 header->dim = 0;
mas01cr@498 63 header->flags = 0;
mas01cr@498 64 header->headerSize = O2_HEADERSIZE;
mas01cr@498 65 header->length = 0;
mas01cr@498 66 header->fileTableOffset = ALIGN_PAGE_UP(O2_HEADERSIZE);
mas01cr@498 67 header->trackTableOffset = ALIGN_PAGE_UP(header->fileTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@498 68 header->dataOffset = ALIGN_PAGE_UP(header->trackTableOffset + O2_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
mas01cr@498 73 /* FIXME: what's going on here? There are two distinct preprocessor
mas01cr@498 74 constants (O2_LSH_N_POINT_BITS, LSH_N_POINT_BITS); a third is
mas01cr@498 75 presumably some default (O2_DEFAULT_LSH_N_POINT_BITS), and then
mas01cr@498 76 there's this magic 28 bits [which needs to be the same as the 28
mas01cr@498 77 in audiodb_lsh_n_point_bits()]. Should this really be part of
mas01cr@498 78 the flags structure at all? Putting it elsewhere will of course
mas01cr@498 79 break backwards compatibility, unless 14 is the only value that's
mas01cr@498 80 been used anywhere... */
mas01cr@256 81
mas01mc@324 82 // For backward-compatibility, Record the point-encoding parameter for LSH indexing in the adb header
mas01mc@324 83 // If this value is 0 then it will be set to 14
mas01mc@324 84
mas01cr@498 85 #if LSH_N_POINT_BITS > 15
mas01mc@475 86 #error "AudioDB Compile ERROR: consistency check of O2_LSH_POINT_BITS failed (>31)"
mas01mc@475 87 #endif
mas01cr@498 88
mas01cr@498 89 header->flags |= LSH_N_POINT_BITS << 28;
mas01mc@324 90
mas01mc@324 91 // If database will fit in a single file the vectors are copied into the AudioDB instance
mas01mc@324 92 // Else all the vectors are left on the FileSystem and we use the dataOffset as storage
mas01mc@324 93 // for the location of the features, powers and times files (assuming that arbitrary keys are used for the fileTable)
mas01mc@324 94 if(ntracks<O2_LARGE_ADB_NTRACKS && datasize<O2_LARGE_ADB_SIZE){
mas01cr@498 95 header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + databytes);
mas01cr@498 96 header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + 2*auxbytes);
mas01cr@498 97 header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + auxbytes);
mas01cr@498 98 header->dbSize = ALIGN_PAGE_UP(header->l2normTableOffset + auxbytes);
mas01cr@498 99 } else { // Create LARGE_ADB, features and powers kept on filesystem
mas01cr@498 100 header->flags |= O2_FLAG_LARGE_ADB;
mas01cr@498 101 header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@498 102 header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@498 103 header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@498 104 header->dbSize = header->l2normTableOffset;
mas01mc@324 105 }
mas01cr@239 106
mas01cr@498 107 write_or_goto_error(fd, header, O2_HEADERSIZE);
mas01cr@239 108
mas01cr@239 109 // go to the location corresponding to the last byte
mas01cr@498 110 if (lseek (fd, header->dbSize - 1, SEEK_SET) == -1) {
mas01cr@498 111 goto error;
mas01cr@498 112 }
mas01cr@239 113
mas01cr@239 114 // write a dummy byte at the last location
mas01cr@498 115 write_or_goto_error(fd, "", 1);
mas01cr@239 116
mas01cr@498 117 free(header);
mas01cr@498 118 return audiodb_open(path, O_RDWR);
mas01cr@498 119
mas01cr@498 120 error:
mas01cr@498 121 if(header) {
mas01cr@498 122 free(header);
mas01cr@498 123 }
mas01cr@498 124 return NULL;
mas01cr@239 125 }