annotate create.cpp @ 498:342822c2d49a

Merge api-inversion branch (-r656:771, but I don't expect to return to that branch) into the trunk. I expect there to be minor performance regressions (e.g. in the SOAP server index cacheing, which I have forcibly removed) and minor unplugged memory leaks (e.g. in audioDB::query(), where I don't free up the datum). I hope that these leaks and performance regressions can be plugged in short order. I also expect that some (but maybe not all) of the issues currently addressed in the memory-leaks branch are superseded or fixed by this merge. There remains much work to be done; go forth and do it.
author mas01cr
date Sat, 10 Jan 2009 16:47:57 +0000
parents fd890d2b38da
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 }