Mercurial > hg > audiodb
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 |