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