annotate create.cpp @ 398:443c2939e84b api-inversion

off_t in ABI structures is a bad thing. Why? Because its size depends on the compile-time environment. It was OK, ish, when the only off_t was at the end of the struct, because then we only stomped on uninitialized bits of memory; it is terrible when there is more than one off_t kind of field. Use uint64_t for those fields instead.
author mas01cr
date Thu, 27 Nov 2008 15:19:47 +0000
parents 78fed0d4c108
children a82a2d9b2451
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@239 5 /* Make a new database.
mas01cr@239 6
mas01mc@324 7 IF size(featuredata) < O2_LARGE_ADB_SIZE
mas01cr@239 8 The database consists of:
mas01cr@239 9
mas01cr@239 10 * a header (see dbTableHeader struct definition);
mas01cr@239 11 * keyTable: list of keys of tracks;
mas01cr@239 12 * trackTable: Maps implicit feature index to a feature vector
mas01cr@239 13 matrix (sizes of tracks)
mas01cr@239 14 * featureTable: Lots of doubles;
mas01cr@239 15 * timesTable: (start,end) time points for each feature vector;
mas01cr@239 16 * powerTable: associated power for each feature vector;
mas01cr@239 17 * l2normTable: squared l2norms for each feature vector.
mas01mc@324 18
mas01mc@324 19 ELSE the database consists of:
mas01mc@324 20
mas01mc@324 21 * a header (see dbTableHeader struct definition);
mas01mc@324 22 * keyTable: list of keys of tracks
mas01mc@324 23 * trackTable: sizes of tracks
mas01mc@324 24 * featureTable: list of feature file names
mas01mc@324 25 * timesTable: list of times file names
mas01mc@324 26 * powerTable: list of power file names
mas01mc@324 27
mas01cr@239 28 */
mas01cr@239 29
mas01cr@385 30 extern "C" {
mas01cr@385 31 adb_t *audiodb_create(const char *path, unsigned datasize, unsigned ntracks, unsigned datadim) {
mas01cr@385 32 int fd;
mas01cr@389 33 adb_header_t *header = 0;
mas01cr@389 34 off_t databytes, auxbytes;
mas01cr@385 35 if(datasize == 0) {
mas01cr@385 36 datasize = O2_DEFAULT_DATASIZE;
mas01cr@385 37 }
mas01cr@385 38 if(ntracks == 0) {
mas01cr@385 39 ntracks = O2_DEFAULT_NTRACKS;
mas01cr@385 40 }
mas01cr@385 41 if(datadim == 0) {
mas01cr@385 42 datadim = O2_DEFAULT_DATADIM;
mas01cr@385 43 }
mas01cr@239 44
mas01cr@385 45 if ((fd = open(path, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
mas01cr@389 46 goto error;
mas01cr@385 47 }
mas01cr@385 48 if (acquire_lock(fd, true)) {
mas01cr@389 49 goto error;
mas01cr@385 50 }
mas01cr@389 51
mas01cr@389 52 header = (adb_header_t *) malloc(sizeof(adb_header_t));
mas01cr@389 53 if(!header) {
mas01cr@389 54 goto error;
mas01cr@389 55 }
mas01cr@385 56
mas01cr@385 57 // Initialize header
mas01cr@389 58 header->magic = O2_MAGIC;
mas01cr@389 59 header->version = O2_FORMAT_VERSION;
mas01cr@389 60 header->numFiles = 0;
mas01cr@389 61 header->dim = 0;
mas01cr@389 62 header->flags = 0;
mas01cr@389 63 header->headerSize = O2_HEADERSIZE;
mas01cr@389 64 header->length = 0;
mas01cr@389 65 header->fileTableOffset = ALIGN_PAGE_UP(O2_HEADERSIZE);
mas01cr@389 66 header->trackTableOffset = ALIGN_PAGE_UP(header->fileTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@389 67 header->dataOffset = ALIGN_PAGE_UP(header->trackTableOffset + O2_TRACKTABLE_ENTRY_SIZE*ntracks);
mas01cr@385 68
mas01cr@389 69 databytes = ((off_t) datasize) * 1024 * 1024;
mas01cr@389 70 auxbytes = databytes / datadim;
mas01cr@389 71
mas01cr@389 72 /* FIXME: what's going on here? There are two distinct
mas01cr@389 73 preprocessor constants (O2_LSH_N_POINT_BITS, LSH_N_POINT_BITS);
mas01cr@389 74 a third is presumably some default
mas01cr@389 75 (O2_DEFAULT_LSH_N_POINT_BITS), and then there's this magic 28
mas01cr@389 76 bits. Should this really be part of the flags structure at
mas01cr@389 77 all? Putting it elsewhere will of course break backwards
mas01cr@389 78 compatibility, unless 14 is the only value that's been used
mas01cr@389 79 anywhere... */
mas01cr@385 80
mas01cr@385 81 // For backward-compatibility, Record the point-encoding parameter for LSH indexing in the adb header
mas01cr@385 82 // If this value is 0 then it will be set to 14
mas01cr@385 83
mas01mc@324 84 #if O2_LSH_N_POINT_BITS > 15
mas01mc@324 85 #error "AudioDB Compile ERROR: consistency check of O2_LSH_POINT_BITS failed (>15)"
mas01mc@324 86 #endif
mas01cr@385 87
mas01cr@389 88 header->flags |= LSH_N_POINT_BITS << 28;
mas01cr@385 89
mas01cr@385 90 // If database will fit in a single file the vectors are copied into the AudioDB instance
mas01cr@385 91 // Else all the vectors are left on the FileSystem and we use the dataOffset as storage
mas01cr@385 92 // for the location of the features, powers and times files (assuming that arbitrary keys are used for the fileTable)
mas01cr@385 93 if(ntracks<O2_LARGE_ADB_NTRACKS && datasize<O2_LARGE_ADB_SIZE){
mas01cr@389 94 header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + databytes);
mas01cr@389 95 header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + 2*auxbytes);
mas01cr@389 96 header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + auxbytes);
mas01cr@389 97 header->dbSize = ALIGN_PAGE_UP(header->l2normTableOffset + auxbytes);
mas01cr@385 98 } else { // Create LARGE_ADB, features and powers kept on filesystem
mas01cr@389 99 header->flags |= O2_FLAG_LARGE_ADB;
mas01cr@389 100 header->timesTableOffset = ALIGN_PAGE_UP(header->dataOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@389 101 header->powerTableOffset = ALIGN_PAGE_UP(header->timesTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@389 102 header->l2normTableOffset = ALIGN_PAGE_UP(header->powerTableOffset + O2_FILETABLE_ENTRY_SIZE*ntracks);
mas01cr@389 103 header->dbSize = header->l2normTableOffset;
mas01cr@385 104 }
mas01cr@385 105
mas01cr@389 106 if (write(fd, header, O2_HEADERSIZE) != O2_HEADERSIZE) {
mas01cr@389 107 goto error;
mas01cr@389 108 }
mas01cr@385 109
mas01cr@385 110 // go to the location corresponding to the last byte
mas01cr@389 111 if (lseek (fd, header->dbSize - 1, SEEK_SET) == -1) {
mas01cr@389 112 goto error;
mas01cr@389 113 }
mas01cr@389 114
mas01cr@385 115 // write a dummy byte at the last location
mas01cr@389 116 if (write (fd, "", 1) != 1) {
mas01cr@389 117 goto error;
mas01cr@389 118 }
mas01cr@389 119
mas01cr@390 120 free(header);
mas01cr@392 121 return audiodb_open(path, O_RDWR);
mas01cr@389 122
mas01cr@389 123 error:
mas01cr@389 124 if(header) {
mas01cr@389 125 free(header);
mas01cr@389 126 }
mas01cr@389 127 return NULL;
mas01mc@324 128 }
mas01cr@239 129 }