annotate create.cpp @ 410:d7e590d58c85 api-inversion

Pavlovian response to compiler warnings... ... attempt to squash them. For now we can get most of the way by writing a simple write_or_goto_error() macro for write(), and the equivalent for read(). One of the warnings, for the return value of chdir(), is silly, because we're already in an error case, and we really can't do anything sensible if the chdir fails. Try to deal with it anyway.
author mas01cr
date Thu, 11 Dec 2008 08:54:01 +0000
parents a82a2d9b2451
children 913a95f06998
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@407 73 /* FIXME: what's going on here? There are two distinct
mas01cr@407 74 preprocessor constants (O2_LSH_N_POINT_BITS, LSH_N_POINT_BITS);
mas01cr@407 75 a third is presumably some default
mas01cr@407 76 (O2_DEFAULT_LSH_N_POINT_BITS), and then there's this magic 28
mas01cr@407 77 bits. Should this really be part of the flags structure at
mas01cr@407 78 all? Putting it elsewhere will of course break backwards
mas01cr@407 79 compatibility, unless 14 is the only value that's been used
mas01cr@407 80 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 }