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