comparison open.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
children cc2b97d020b1
comparison
equal deleted inserted replaced
476:a7193678280b 498:342822c2d49a
1 #include "audioDB.h"
2 extern "C" {
3 #include "audioDB_API.h"
4 #include "audioDB-internals.h"
5 }
6
7 static bool audiodb_check_header(adb_header_t *header) {
8 /* FIXME: use syslog() or write to stderr or something to give the
9 poor user some diagnostics. */
10 if(header->magic == O2_OLD_MAGIC) {
11 return false;
12 }
13 if(header->magic != O2_MAGIC) {
14 return false;
15 }
16 if(header->version != O2_FORMAT_VERSION) {
17 return false;
18 }
19 if(header->headerSize != O2_HEADERSIZE) {
20 return false;
21 }
22 return true;
23 }
24
25 static int audiodb_collect_keys(adb_t *adb) {
26 char *key_table = 0;
27 size_t key_table_length = 0;
28
29 if(adb->header->length > 0) {
30 unsigned nfiles = adb->header->numFiles;
31 key_table_length = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE);
32 mmap_or_goto_error(char *, key_table, adb->header->fileTableOffset, key_table_length);
33 for (unsigned int k = 0; k < nfiles; k++) {
34 adb->keys->push_back(key_table + k*O2_FILETABLE_ENTRY_SIZE);
35 (*adb->keymap)[(key_table + k*O2_FILETABLE_ENTRY_SIZE)] = k;
36 }
37 munmap(key_table, key_table_length);
38 }
39
40 return 0;
41
42 error:
43 maybe_munmap(key_table, key_table_length);
44 return 1;
45 }
46
47 static int audiodb_collect_track_lengths(adb_t *adb) {
48 uint32_t *track_table = 0;
49 size_t track_table_length = 0;
50 if(adb->header->length > 0) {
51 unsigned nfiles = adb->header->numFiles;
52 track_table_length = ALIGN_PAGE_UP(nfiles * O2_TRACKTABLE_ENTRY_SIZE);
53 mmap_or_goto_error(uint32_t *, track_table, adb->header->trackTableOffset, track_table_length);
54 off_t offset = 0;
55 for (unsigned int k = 0; k < nfiles; k++) {
56 uint32_t track_length = track_table[k];
57 adb->track_lengths->push_back(track_length);
58 adb->track_offsets->push_back(offset);
59 offset += track_length * adb->header->dim * sizeof(double);
60 }
61 munmap(track_table, track_table_length);
62 }
63
64 return 0;
65
66 error:
67 maybe_munmap(track_table, track_table_length);
68 return 1;
69 }
70
71 adb_t *audiodb_open(const char *path, int flags) {
72 adb_t *adb = 0;
73 int fd = -1;
74
75 flags &= (O_RDONLY|O_RDWR);
76 fd = open(path, flags);
77 if(fd == -1) {
78 goto error;
79 }
80 if(acquire_lock(fd, flags == O_RDWR)) {
81 goto error;
82 }
83
84 adb = (adb_t *) calloc(1, sizeof(adb_t));
85 if(!adb) {
86 goto error;
87 }
88 adb->fd = fd;
89 adb->flags = flags;
90 adb->path = (char *) malloc(1+strlen(path));
91 if(!(adb->path)) {
92 goto error;
93 }
94 strcpy(adb->path, path);
95
96 adb->header = (adb_header_t *) malloc(sizeof(adb_header_t));
97 if(!(adb->header)) {
98 goto error;
99 }
100 if(read(fd, (char *) adb->header, O2_HEADERSIZE) != O2_HEADERSIZE) {
101 goto error;
102 }
103 if(!audiodb_check_header(adb->header)) {
104 goto error;
105 }
106
107 adb->keys = new std::vector<std::string>;
108 if(!adb->keys) {
109 goto error;
110 }
111 adb->keymap = new std::map<std::string,uint32_t>;
112 if(!adb->keymap) {
113 goto error;
114 }
115 if(audiodb_collect_keys(adb)) {
116 goto error;
117 }
118 adb->track_lengths = new std::vector<uint32_t>;
119 if(!adb->track_lengths) {
120 goto error;
121 }
122 adb->track_lengths->reserve(adb->header->numFiles);
123 adb->track_offsets = new std::vector<off_t>;
124 if(!adb->track_offsets) {
125 goto error;
126 }
127 adb->track_offsets->reserve(adb->header->numFiles);
128 if(audiodb_collect_track_lengths(adb)) {
129 goto error;
130 }
131 adb->cached_lsh = 0;
132 return adb;
133
134 error:
135 if(adb) {
136 if(adb->header) {
137 free(adb->header);
138 }
139 if(adb->path) {
140 free(adb->path);
141 }
142 if(adb->keys) {
143 delete adb->keys;
144 }
145 if(adb->keymap) {
146 delete adb->keymap;
147 }
148 if(adb->track_lengths) {
149 delete adb->track_lengths;
150 }
151 free(adb);
152 }
153 if(fd != -1) {
154 close(fd);
155 }
156 return NULL;
157 }