annotate create.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 913a95f06998
children
rev   line source
mas01cr@239 1 #include "audioDB.h"
mas01cr@385 2 extern "C" {
mas01cr@385 3 #include "audioDB_API.h"
mas01cr@385 4 }
mas01cr@410 5 #include "audioDB-internals.h"
mas01cr@410 6
mas01cr@239 7 /* Make a new database.
mas01cr@239 8
mas01cr@407 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@407 20
mas01mc@324 21 ELSE the database consists of:
mas01cr@407 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@407 32 adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim) {
mas01cr@407 33 int fd;
mas01cr@407 34 adb_header_t *header = 0;
mas01cr@407 35 off_t databytes, auxbytes;
mas01cr@407 36 if(datasize == 0) {
mas01cr@407 37 datasize = O2_DEFAULT_DATASIZE;
mas01cr@407 38 }
mas01cr@407 39 if(ntracks == 0) {
mas01cr@407 40 ntracks = O2_DEFAULT_NTRACKS;
mas01cr@407 41 }
mas01cr@407 42 if(datadim == 0) {
mas01cr@407 43 datadim = O2_DEFAULT_DATADIM;
mas01cr@407 44 }
mas01cr@239 45
mas01cr@407 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@407 47 goto error;
mas01cr@407 48 }
mas01cr@407 49 if (acquire_lock(fd, true)) {
mas01cr@407 50 goto error;
mas01cr@407 51 }
mas01cr@389 52
mas01cr@407 53 header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@407 54 if(!header) {
mas01cr@407 55 goto error;
mas01cr@407 56 }
mas01cr@389 57
mas01cr@407 58 // Initialize header
mas01cr@407 59 header->magic = O2_MAGIC;
mas01cr@407 60 header->version = O2_FORMAT_VERSION;
mas01cr@407 61 header->numFiles = 0;
mas01cr@407 62 header->dim = 0;
mas01cr@407 63 header->flags = 0;
mas01cr@407 64 header->headerSize = O2_HEADERSIZE;
mas01cr@407 65 header->length = 0;
mas01cr@407 66 header->fileTableOffset = ALIGN_PAGE_UP(O2_HEADERSIZE);
mas01cr@407 67 header->trackTableOffset = ALIGN_PAGE_UP(header->fileTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@407 68 header->dataOffset = ALIGN_PAGE_UP(header->trackTableOffset + O2_TRACKTABLE_ENTRY_SIZE*ntracks);
mas01cr@407 69
mas01cr@407 70 databytes = ((off_t) datasize) * 1024 * 1024;
mas01cr@407 71 auxbytes = databytes / datadim;
mas01cr@407 72
mas01cr@458 73 /* FIXME: what's going on here? There are two distinct preprocessor
mas01cr@458 74 constants (O2_LSH_N_POINT_BITS, LSH_N_POINT_BITS); a third is
mas01cr@458 75 presumably some default (O2_DEFAULT_LSH_N_POINT_BITS), and then
mas01cr@458 76 there's this magic 28 bits [which needs to be the same as the 28
mas01cr@458 77 in audiodb_lsh_n_point_bits()]. Should this really be part of
mas01cr@458 78 the flags structure at all? Putting it elsewhere will of course
mas01cr@458 79 break backwards compatibility, unless 14 is the only value that's
mas01cr@458 80 been used anywhere... */
mas01cr@407 81
mas01cr@407 82 // For backward-compatibility, Record the point-encoding parameter for LSH indexing in the adb header
mas01cr@407 83 // If this value is 0 then it will be set to 14
mas01cr@407 84
mas01mc@324 85 #if O2_LSH_N_POINT_BITS > 15
mas01mc@324 86 #error "AudioDB Compile ERROR: consistency check of O2_LSH_POINT_BITS failed (>15)"
mas01mc@324 87 #endif
mas01cr@407 88
mas01cr@407 89 header->flags |= LSH_N_POINT_BITS << 28;
mas01cr@407 90
mas01cr@407 91 // If database will fit in a single file the vectors are copied into the AudioDB instance
mas01cr@407 92 // Else all the vectors are left on the FileSystem and we use the dataOffset as storage
mas01cr@407 93 // for the location of the features, powers and times files (assuming that arbitrary keys are used for the fileTable)
mas01cr@407 94 if(ntracks<O2_LARGE_ADB_NTRACKS && datasize<O2_LARGE_ADB_SIZE){
mas01cr@407 95 header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + databytes);
mas01cr@407 96 header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + 2*auxbytes);
mas01cr@407 97 header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + auxbytes);
mas01cr@407 98 header->dbSize = ALIGN_PAGE_UP(header->l2normTableOffset + auxbytes);
mas01cr@407 99 } else { // Create LARGE_ADB, features and powers kept on filesystem
mas01cr@407 100 header->flags |= O2_FLAG_LARGE_ADB;
mas01cr@407 101 header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@407 102 header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@407 103 header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@407 104 header->dbSize = header->l2normTableOffset;
mas01cr@407 105 }
mas01cr@407 106
mas01cr@410 107 write_or_goto_error(fd, header, O2_HEADERSIZE);
mas01cr@407 108
mas01cr@407 109 // go to the location corresponding to the last byte
mas01cr@407 110 if (lseek (fd, header->dbSize - 1, SEEK_SET) == -1) {
mas01cr@407 111 goto error;
mas01cr@407 112 }
mas01cr@407 113
mas01cr@407 114 // write a dummy byte at the last location
mas01cr@410 115 write_or_goto_error(fd, "", 1);
mas01cr@389 116
mas01cr@407 117 free(header);
mas01cr@407 118 return audiodb_open(path, O_RDWR);
mas01cr@389 119
mas01cr@407 120 error:
mas01cr@407 121 if(header) {
mas01cr@390 122 free(header);
mas01mc@324 123 }
mas01cr@407 124 return NULL;
mas01cr@239 125 }