Mercurial > hg > audiodb
comparison audioDB.cpp @ 107:1521d46bc1ac audiodb-debian
Merge trunk changes -r96:122 to audiodb-debian branch.
(and new version in debian/changelog)
author | mas01cr |
---|---|
date | Fri, 05 Oct 2007 11:45:03 +0000 |
parents | a1d462d592dd |
children | ae045842d29f |
comparison
equal
deleted
inserted
replaced
80:a1d462d592dd | 107:1521d46bc1ac |
---|---|
1 #include "audioDB.h" | 1 #include "audioDB.h" |
2 | 2 |
3 #define O2_DEBUG | 3 #if defined(O2_DEBUG) |
4 void sigterm_action(int signal, siginfo_t *info, void *context) { | |
5 exit(128+signal); | |
6 } | |
7 | |
8 void sighup_action(int signal, siginfo_t *info, void *context) { | |
9 // FIXME: reread any configuration files | |
10 } | |
11 #endif | |
4 | 12 |
5 void audioDB::error(const char* a, const char* b, const char *sysFunc) { | 13 void audioDB::error(const char* a, const char* b, const char *sysFunc) { |
6 if(isServer) { | 14 if(isServer) { |
15 /* FIXME: I think this is leaky -- we never delete err. actually | |
16 deleting it is tricky, though; it gets placed into some | |
17 soap-internal struct with uncertain extent... -- CSR, | |
18 2007-10-01 */ | |
7 char *err = new char[256]; /* FIXME: overflows */ | 19 char *err = new char[256]; /* FIXME: overflows */ |
8 snprintf(err, 255, "%s: %s\n%s", a, b, sysFunc ? strerror(errno) : ""); | 20 snprintf(err, 255, "%s: %s\n%s", a, b, sysFunc ? strerror(errno) : ""); |
9 /* FIXME: actually we could usefully do with a properly structured | 21 /* FIXME: actually we could usefully do with a properly structured |
10 type, so that we can throw separate faultstring and details. | 22 type, so that we can throw separate faultstring and details. |
11 -- CSR, 2007-10-01 */ | 23 -- CSR, 2007-10-01 */ |
16 perror(sysFunc); | 28 perror(sysFunc); |
17 } | 29 } |
18 exit(1); | 30 exit(1); |
19 } | 31 } |
20 } | 32 } |
21 | |
22 #define O2_AUDIODB_INITIALIZERS \ | |
23 dim(0), \ | |
24 dbName(0), \ | |
25 inFile(0), \ | |
26 key(0), \ | |
27 trackFileName(0), \ | |
28 trackFile(0), \ | |
29 command(0), \ | |
30 timesFileName(0), \ | |
31 timesFile(0), \ | |
32 dbfid(0), \ | |
33 infid(0), \ | |
34 db(0), \ | |
35 indata(0), \ | |
36 dbH(0), \ | |
37 fileTable(0), \ | |
38 trackTable(0), \ | |
39 dataBuf(0), \ | |
40 l2normTable(0), \ | |
41 qNorm(0), \ | |
42 timesTable(0), \ | |
43 verbosity(1), \ | |
44 queryType(O2_FLAG_POINT_QUERY), \ | |
45 pointNN(O2_DEFAULT_POINTNN), \ | |
46 trackNN(O2_DEFAULT_TRACKNN), \ | |
47 sequenceLength(16), \ | |
48 sequenceHop(1), \ | |
49 queryPoint(0), \ | |
50 usingQueryPoint(0), \ | |
51 usingTimes(0), \ | |
52 isClient(0), \ | |
53 isServer(0), \ | |
54 port(0), \ | |
55 timesTol(0.1), \ | |
56 radius(0) | |
57 | 33 |
58 audioDB::audioDB(const unsigned argc, char* const argv[]): O2_AUDIODB_INITIALIZERS | 34 audioDB::audioDB(const unsigned argc, char* const argv[]): O2_AUDIODB_INITIALIZERS |
59 { | 35 { |
60 if(processArgs(argc, argv)<0){ | 36 if(processArgs(argc, argv)<0){ |
61 printf("No command found.\n"); | 37 printf("No command found.\n"); |
103 error("Unrecognized command",command); | 79 error("Unrecognized command",command); |
104 } | 80 } |
105 | 81 |
106 audioDB::audioDB(const unsigned argc, char* const argv[], adb__queryResult *adbQueryResult): O2_AUDIODB_INITIALIZERS | 82 audioDB::audioDB(const unsigned argc, char* const argv[], adb__queryResult *adbQueryResult): O2_AUDIODB_INITIALIZERS |
107 { | 83 { |
108 processArgs(argc, argv); | 84 try { |
109 isServer = 1; // FIXME: Hack | 85 processArgs(argc, argv); |
110 assert(O2_ACTION(COM_QUERY)); | 86 isServer = 1; // FIXME: Hack |
111 query(dbName, inFile, adbQueryResult); | 87 assert(O2_ACTION(COM_QUERY)); |
88 query(dbName, inFile, adbQueryResult); | |
89 } catch(char *err) { | |
90 cleanup(); | |
91 throw(err); | |
92 } | |
112 } | 93 } |
113 | 94 |
114 audioDB::audioDB(const unsigned argc, char* const argv[], adb__statusResult *adbStatusResult): O2_AUDIODB_INITIALIZERS | 95 audioDB::audioDB(const unsigned argc, char* const argv[], adb__statusResult *adbStatusResult): O2_AUDIODB_INITIALIZERS |
115 { | 96 { |
116 processArgs(argc, argv); | 97 try { |
117 isServer = 1; // FIXME: Hack | 98 processArgs(argc, argv); |
118 assert(O2_ACTION(COM_STATUS)); | 99 isServer = 1; // FIXME: Hack |
119 status(dbName, adbStatusResult); | 100 assert(O2_ACTION(COM_STATUS)); |
120 } | 101 status(dbName, adbStatusResult); |
121 | 102 } catch(char *err) { |
122 audioDB::~audioDB(){ | 103 cleanup(); |
123 // Clean up | 104 throw(err); |
105 } | |
106 } | |
107 | |
108 void audioDB::cleanup() { | |
124 if(indata) | 109 if(indata) |
125 munmap(indata,statbuf.st_size); | 110 munmap(indata,statbuf.st_size); |
126 if(db) | 111 if(db) |
127 munmap(db,O2_DEFAULTDBSIZE); | 112 munmap(db,O2_DEFAULTDBSIZE); |
128 if(dbfid>0) | 113 if(dbfid>0) |
131 close(infid); | 116 close(infid); |
132 if(dbH) | 117 if(dbH) |
133 delete dbH; | 118 delete dbH; |
134 } | 119 } |
135 | 120 |
121 audioDB::~audioDB(){ | |
122 cleanup(); | |
123 } | |
124 | |
136 int audioDB::processArgs(const unsigned argc, char* const argv[]){ | 125 int audioDB::processArgs(const unsigned argc, char* const argv[]){ |
137 | 126 |
138 if(argc<2){ | 127 if(argc<2){ |
139 cmdline_parser_print_version (); | 128 cmdline_parser_print_version (); |
140 if (strlen(gengetopt_args_info_purpose) > 0) | 129 if (strlen(gengetopt_args_info_purpose) > 0) |
177 command=COM_SERVER; | 166 command=COM_SERVER; |
178 port=args_info.SERVER_arg; | 167 port=args_info.SERVER_arg; |
179 if(port<100 || port > 100000) | 168 if(port<100 || port > 100000) |
180 error("port out of range"); | 169 error("port out of range"); |
181 isServer=1; | 170 isServer=1; |
171 #if defined(O2_DEBUG) | |
172 struct sigaction sa; | |
173 sa.sa_sigaction = sigterm_action; | |
174 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; | |
175 sigaction(SIGTERM, &sa, NULL); | |
176 sa.sa_sigaction = sighup_action; | |
177 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; | |
178 sigaction(SIGHUP, &sa, NULL); | |
179 #endif | |
182 return 0; | 180 return 0; |
183 } | 181 } |
184 | 182 |
185 // No return on client command, find database command | 183 // No return on client command, find database command |
186 if(args_info.client_given){ | 184 if(args_info.client_given){ |
187 command=COM_CLIENT; | 185 command=COM_CLIENT; |
188 hostport=args_info.client_arg; | 186 hostport=args_info.client_arg; |
189 isClient=1; | 187 isClient=1; |
190 } | 188 } |
191 | 189 |
192 if(args_info.NEW_given){ | 190 if(args_info.NEW_given){ |
193 command=COM_CREATE; | 191 command=COM_CREATE; |
194 dbName=args_info.database_arg; | 192 dbName=args_info.database_arg; |
195 return 0; | 193 return 0; |
196 } | 194 } |
197 | 195 |
198 if(args_info.STATUS_given){ | 196 if(args_info.STATUS_given){ |
199 command=COM_STATUS; | 197 command=COM_STATUS; |
200 dbName=args_info.database_arg; | 198 dbName=args_info.database_arg; |
201 return 0; | 199 return 0; |
202 } | 200 } |
203 | 201 |
204 if(args_info.DUMP_given){ | 202 if(args_info.DUMP_given){ |
205 command=COM_DUMP; | 203 command=COM_DUMP; |
206 dbName=args_info.database_arg; | 204 dbName=args_info.database_arg; |
207 return 0; | 205 return 0; |
208 } | 206 } |
209 | 207 |
210 if(args_info.L2NORM_given){ | 208 if(args_info.L2NORM_given){ |
211 command=COM_L2NORM; | 209 command=COM_L2NORM; |
212 dbName=args_info.database_arg; | 210 dbName=args_info.database_arg; |
213 return 0; | 211 return 0; |
214 } | 212 } |
215 | 213 |
216 if(args_info.INSERT_given){ | 214 if(args_info.INSERT_given){ |
217 command=COM_INSERT; | 215 command=COM_INSERT; |
218 dbName=args_info.database_arg; | 216 dbName=args_info.database_arg; |
219 inFile=args_info.features_arg; | 217 inFile=args_info.features_arg; |
220 if(args_info.key_given) | 218 if(args_info.key_given) |
221 key=args_info.key_arg; | 219 key=args_info.key_arg; |
222 if(args_info.times_given){ | 220 if(args_info.times_given){ |
223 timesFileName=args_info.times_arg; | 221 timesFileName=args_info.times_arg; |
224 if(strlen(timesFileName)>0){ | 222 if(strlen(timesFileName)>0){ |
225 if(!(timesFile = new ifstream(timesFileName,ios::in))) | 223 if(!(timesFile = new ifstream(timesFileName,ios::in))) |
226 error("Could not open times file for reading", timesFileName); | 224 error("Could not open times file for reading", timesFileName); |
227 usingTimes=1; | 225 usingTimes=1; |
228 } | 226 } |
229 } | 227 } |
230 return 0; | 228 return 0; |
231 } | 229 } |
232 | 230 |
233 if(args_info.BATCHINSERT_given){ | 231 if(args_info.BATCHINSERT_given){ |
234 command=COM_BATCHINSERT; | 232 command=COM_BATCHINSERT; |
235 dbName=args_info.database_arg; | 233 dbName=args_info.database_arg; |
236 inFile=args_info.featureList_arg; | 234 inFile=args_info.featureList_arg; |
237 if(args_info.keyList_given) | 235 if(args_info.keyList_given) |
238 key=args_info.keyList_arg; // INCONSISTENT NO CHECK | 236 key=args_info.keyList_arg; // INCONSISTENT NO CHECK |
239 | 237 |
240 /* TO DO: REPLACE WITH | 238 /* TO DO: REPLACE WITH |
241 if(args_info.keyList_given){ | 239 if(args_info.keyList_given){ |
242 trackFileName=args_info.keyList_arg; | 240 trackFileName=args_info.keyList_arg; |
243 if(strlen(trackFileName)>0 && !(trackFile = new ifstream(trackFileName,ios::in))) | 241 if(strlen(trackFileName)>0 && !(trackFile = new ifstream(trackFileName,ios::in))) |
244 error("Could not open keyList file for reading",trackFileName); | 242 error("Could not open keyList file for reading",trackFileName); |
245 } | 243 } |
246 AND UPDATE BATCHINSERT() | 244 AND UPDATE BATCHINSERT() |
247 */ | 245 */ |
248 | 246 |
249 if(args_info.timesList_given){ | 247 if(args_info.timesList_given){ |
250 timesFileName=args_info.timesList_arg; | 248 timesFileName=args_info.timesList_arg; |
251 if(strlen(timesFileName)>0){ | 249 if(strlen(timesFileName)>0){ |
252 if(!(timesFile = new ifstream(timesFileName,ios::in))) | 250 if(!(timesFile = new ifstream(timesFileName,ios::in))) |
253 error("Could not open timesList file for reading", timesFileName); | 251 error("Could not open timesList file for reading", timesFileName); |
254 usingTimes=1; | 252 usingTimes=1; |
255 } | 253 } |
256 } | 254 } |
257 return 0; | 255 return 0; |
258 } | 256 } |
259 | 257 |
260 // Query command and arguments | 258 // Query command and arguments |
261 if(args_info.QUERY_given){ | 259 if(args_info.QUERY_given){ |
262 command=COM_QUERY; | 260 command=COM_QUERY; |
263 dbName=args_info.database_arg; | 261 dbName=args_info.database_arg; |
264 inFile=args_info.features_arg; | 262 inFile=args_info.features_arg; |
265 | 263 |
266 if(args_info.keyList_given){ | 264 if(args_info.keyList_given){ |
267 trackFileName=args_info.keyList_arg; | 265 trackFileName=args_info.keyList_arg; |
268 if(strlen(trackFileName)>0 && !(trackFile = new ifstream(trackFileName,ios::in))) | 266 if(strlen(trackFileName)>0 && !(trackFile = new ifstream(trackFileName,ios::in))) |
269 error("Could not open keyList file for reading",trackFileName); | 267 error("Could not open keyList file for reading",trackFileName); |
270 } | 268 } |
271 | 269 |
272 if(args_info.times_given){ | 270 if(args_info.times_given){ |
273 timesFileName=args_info.times_arg; | 271 timesFileName=args_info.times_arg; |
274 if(strlen(timesFileName)>0){ | 272 if(strlen(timesFileName)>0){ |
275 if(!(timesFile = new ifstream(timesFileName,ios::in))) | 273 if(!(timesFile = new ifstream(timesFileName,ios::in))) |
276 error("Could not open times file for reading", timesFileName); | 274 error("Could not open times file for reading", timesFileName); |
277 usingTimes=1; | 275 usingTimes=1; |
278 } | 276 } |
279 } | 277 } |
280 | 278 |
281 // query type | 279 // query type |
282 if(strncmp(args_info.QUERY_arg, "track", MAXSTR)==0) | 280 if(strncmp(args_info.QUERY_arg, "track", MAXSTR)==0) |
283 queryType=O2_FLAG_TRACK_QUERY; | 281 queryType=O2_TRACK_QUERY; |
284 else if(strncmp(args_info.QUERY_arg, "point", MAXSTR)==0) | 282 else if(strncmp(args_info.QUERY_arg, "point", MAXSTR)==0) |
285 queryType=O2_FLAG_POINT_QUERY; | 283 queryType=O2_POINT_QUERY; |
286 else if(strncmp(args_info.QUERY_arg, "sequence", MAXSTR)==0) | 284 else if(strncmp(args_info.QUERY_arg, "sequence", MAXSTR)==0) |
287 queryType=O2_FLAG_SEQUENCE_QUERY; | 285 queryType=O2_SEQUENCE_QUERY; |
288 else | 286 else |
289 error("unsupported query type",args_info.QUERY_arg); | 287 error("unsupported query type",args_info.QUERY_arg); |
290 | 288 |
291 if(!args_info.exhaustive_flag){ | 289 if(!args_info.exhaustive_flag){ |
292 queryPoint = args_info.qpoint_arg; | 290 queryPoint = args_info.qpoint_arg; |
293 usingQueryPoint=1; | 291 usingQueryPoint=1; |
294 if(queryPoint<0 || queryPoint >10000) | 292 if(queryPoint<0 || queryPoint >10000) |
295 error("queryPoint out of range: 0 <= queryPoint <= 10000"); | 293 error("queryPoint out of range: 0 <= queryPoint <= 10000"); |
296 } | 294 } |
297 | 295 |
298 | 296 pointNN = args_info.pointnn_arg; |
299 pointNN=args_info.pointnn_arg; | 297 if(pointNN < 1 || pointNN > 1000) { |
300 if(pointNN<1 || pointNN >1000) | 298 error("pointNN out of range: 1 <= pointNN <= 1000"); |
301 error("pointNN out of range: 1 <= pointNN <= 1000"); | 299 } |
302 | 300 trackNN = args_info.resultlength_arg; |
303 | 301 if(trackNN < 1 || trackNN > 1000) { |
304 | 302 error("resultlength out of range: 1 <= resultlength <= 1000"); |
305 trackNN=args_info.resultlength_arg; | 303 } |
306 if(trackNN<1 || trackNN >10000) | 304 sequenceLength = args_info.sequencelength_arg; |
307 error("resultlength out of range: 1 <= resultlength <= 1000"); | 305 if(sequenceLength < 1 || sequenceLength > 1000) { |
308 | 306 error("seqlen out of range: 1 <= seqlen <= 1000"); |
309 | 307 } |
310 sequenceLength=args_info.sequencelength_arg; | 308 sequenceHop = args_info.sequencehop_arg; |
311 if(sequenceLength<1 || sequenceLength >1000) | 309 if(sequenceHop < 1 || sequenceHop > 1000) { |
312 error("seqlen out of range: 1 <= seqlen <= 1000"); | 310 error("seqhop out of range: 1 <= seqhop <= 1000"); |
313 | 311 } |
314 sequenceHop=args_info.sequencehop_arg; | 312 return 0; |
315 if(sequenceHop<1 || sequenceHop >1000) | 313 } |
316 error("seqhop out of range: 1 <= seqhop <= 1000"); | 314 return -1; // no command found |
317 | |
318 return 0; | |
319 } | |
320 return -1; // no command found | |
321 } | 315 } |
322 | 316 |
323 /* Make a new database | 317 /* Make a new database |
324 | 318 |
325 The database consists of: | 319 The database consists of: |
332 | 326 |
333 keyTable : list of keys of tracks | 327 keyTable : list of keys of tracks |
334 -------------------------------------------------------------------------- | 328 -------------------------------------------------------------------------- |
335 | key 256 bytes | | 329 | key 256 bytes | |
336 -------------------------------------------------------------------------- | 330 -------------------------------------------------------------------------- |
337 O2_MAXFILES*02_FILENAMELENGTH | 331 O2_MAXFILES*O2_FILENAMELENGTH |
338 | 332 |
339 trackTable : Maps implicit feature index to a feature vector matrix | 333 trackTable : Maps implicit feature index to a feature vector matrix |
340 -------------------------------------------------------------------------- | 334 -------------------------------------------------------------------------- |
341 | numVectors (4 bytes) | | 335 | numVectors (4 bytes) | |
342 -------------------------------------------------------------------------- | 336 -------------------------------------------------------------------------- |
343 O2_MAXFILES * 02_MEANNUMFEATURES * sizeof(INT) | 337 O2_MAXFILES * O2_MEANNUMFEATURES * sizeof(INT) |
344 | 338 |
345 featureTable | 339 featureTable |
346 -------------------------------------------------------------------------- | 340 -------------------------------------------------------------------------- |
347 | v1 v2 v3 ... vd (double) | | 341 | v1 v2 v3 ... vd (double) | |
348 -------------------------------------------------------------------------- | 342 -------------------------------------------------------------------------- |
349 O2_MAXFILES * 02_MEANNUMFEATURES * DIM * sizeof(DOUBLE) | 343 O2_MAXFILES * O2_MEANNUMFEATURES * DIM * sizeof(DOUBLE) |
350 | 344 |
351 timesTable | 345 timesTable |
352 -------------------------------------------------------------------------- | 346 -------------------------------------------------------------------------- |
353 | timestamp (double) | | 347 | timestamp (double) | |
354 -------------------------------------------------------------------------- | 348 -------------------------------------------------------------------------- |
355 O2_MAXFILES * 02_MEANNUMFEATURES * sizeof(DOUBLE) | 349 O2_MAXFILES * O2_MEANNUMFEATURES * sizeof(DOUBLE) |
356 | 350 |
357 l2normTable | 351 l2normTable |
358 -------------------------------------------------------------------------- | 352 -------------------------------------------------------------------------- |
359 | nm (double) | | 353 | nm (double) | |
360 -------------------------------------------------------------------------- | 354 -------------------------------------------------------------------------- |
361 O2_MAXFILES * 02_MEANNUMFEATURES * sizeof(DOUBLE) | 355 O2_MAXFILES * O2_MEANNUMFEATURES * sizeof(DOUBLE) |
362 | 356 |
363 */ | 357 */ |
364 | 358 |
365 void audioDB::get_lock(int fd, bool exclusive) { | 359 void audioDB::get_lock(int fd, bool exclusive) { |
366 struct flock lock; | 360 struct flock lock; |
444 | 438 |
445 } | 439 } |
446 | 440 |
447 // initTables - memory map files passed as arguments | 441 // initTables - memory map files passed as arguments |
448 // Precondition: database has already been created | 442 // Precondition: database has already been created |
449 void audioDB::initTables(const char* dbName, bool forWrite, const char* inFile=0){ | 443 void audioDB::initTables(const char* dbName, bool forWrite, const char* inFile = 0) { |
450 if ((dbfid = open (dbName, forWrite ? O_RDWR : O_RDONLY)) < 0) | 444 if ((dbfid = open(dbName, forWrite ? O_RDWR : O_RDONLY)) < 0) { |
451 error("Can't open database file", dbName, "open"); | 445 error("Can't open database file", dbName, "open"); |
446 } | |
452 get_lock(dbfid, forWrite); | 447 get_lock(dbfid, forWrite); |
453 | 448 |
454 // open the input file | 449 // open the input file |
455 if (inFile && (infid = open (inFile, O_RDONLY)) < 0) | 450 if (inFile && (infid = open(inFile, O_RDONLY)) < 0) { |
456 error("can't open input file for reading", inFile, "open"); | 451 error("can't open input file for reading", inFile, "open"); |
457 | 452 } |
458 // find size of input file | 453 // find size of input file |
459 if (inFile && fstat (infid,&statbuf) < 0) | 454 if (inFile && fstat(infid, &statbuf) < 0) { |
460 error("fstat error finding size of input", "", "fstat"); | 455 error("fstat error finding size of input", inFile, "fstat"); |
461 | 456 } |
462 // Get the database header info | 457 // Get the database header info |
463 dbH = new dbTableHeaderT(); | 458 dbH = new dbTableHeaderT(); |
464 assert(dbH); | 459 assert(dbH); |
465 | 460 |
466 if(read(dbfid,(char*)dbH,sizeof(dbTableHeaderT))!=sizeof(dbTableHeaderT)) | 461 if(read(dbfid, (char *) dbH, O2_HEADERSIZE) != O2_HEADERSIZE) { |
467 error("error reading db header"); | 462 error("error reading db header", dbName, "read"); |
463 } | |
468 | 464 |
469 fileTableOffset = O2_HEADERSIZE; | 465 fileTableOffset = O2_HEADERSIZE; |
470 trackTableOffset = fileTableOffset + O2_FILETABLESIZE*O2_MAXFILES; | 466 trackTableOffset = fileTableOffset + O2_FILETABLESIZE*O2_MAXFILES; |
471 dataoffset = trackTableOffset + O2_TRACKTABLESIZE*O2_MAXFILES; | 467 dataoffset = trackTableOffset + O2_TRACKTABLESIZE*O2_MAXFILES; |
472 l2normTableOffset = O2_DEFAULTDBSIZE - O2_MAXFILES*O2_MEANNUMVECTORS*sizeof(double); | 468 l2normTableOffset = O2_DEFAULTDBSIZE - O2_MAXFILES*O2_MEANNUMVECTORS*sizeof(double); |
473 timesTableOffset = l2normTableOffset - O2_MAXFILES*O2_MEANNUMVECTORS*sizeof(double); | 469 timesTableOffset = l2normTableOffset - O2_MAXFILES*O2_MEANNUMVECTORS*sizeof(double); |
474 | 470 |
475 if(dbH->magic!=O2_MAGIC){ | 471 if(dbH->magic != O2_MAGIC) { |
476 cerr << "expected: " << O2_MAGIC << ", got:" << dbH->magic << endl; | 472 cerr << "expected: " << O2_MAGIC << ", got: " << dbH->magic << endl; |
477 error("database file has incorrect header",dbName); | 473 error("database file has incorrect header",dbName); |
478 } | 474 } |
479 | 475 |
480 if(inFile) | 476 if(inFile) |
481 if(dbH->dim==0 && dbH->length==0) // empty database | 477 if(dbH->dim == 0 && dbH->length == 0) // empty database |
482 read(infid,&dbH->dim,sizeof(unsigned)); // initialize with input dimensionality | 478 // initialize with input dimensionality |
479 read(infid, &dbH->dim, sizeof(unsigned)); | |
483 else { | 480 else { |
484 unsigned test; | 481 unsigned test; |
485 read(infid,&test,sizeof(unsigned)); | 482 read(infid, &test, sizeof(unsigned)); |
486 if(dbH->dim!=test){ | 483 if(dbH->dim != test) { |
487 cerr << "error: expected dimension: " << dbH->dim << ", got :" << test <<endl; | 484 cerr << "error: expected dimension: " << dbH->dim << ", got : " << test <<endl; |
488 error("feature dimensions do not match database table dimensions"); | 485 error("feature dimensions do not match database table dimensions"); |
489 } | 486 } |
490 } | 487 } |
491 | 488 |
492 // mmap the input file | 489 // mmap the input file |
493 if (inFile && (indata = (char*)mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, infid, 0)) | 490 if (inFile && (indata = (char*)mmap (0, statbuf.st_size, PROT_READ, MAP_SHARED, infid, 0)) |
494 == (caddr_t) -1) | 491 == (caddr_t) -1) |
495 error("mmap error for input", "", "mmap"); | 492 error("mmap error for input", inFile, "mmap"); |
496 | 493 |
497 // mmap the database file | 494 // mmap the database file |
498 if ((db = (char*) mmap(0, O2_DEFAULTDBSIZE, PROT_READ | (forWrite ? PROT_WRITE : 0), | 495 if ((db = (char*) mmap(0, O2_DEFAULTDBSIZE, PROT_READ | (forWrite ? PROT_WRITE : 0), |
499 MAP_SHARED, dbfid, 0)) == (caddr_t) -1) | 496 MAP_SHARED, dbfid, 0)) == (caddr_t) -1) |
500 error("mmap error for initting tables of database", "", "mmap"); | 497 error("mmap error for initting tables of database", "", "mmap"); |
503 fileTable= (char*)(db+fileTableOffset); | 500 fileTable= (char*)(db+fileTableOffset); |
504 trackTable = (unsigned*)(db+trackTableOffset); | 501 trackTable = (unsigned*)(db+trackTableOffset); |
505 dataBuf = (double*)(db+dataoffset); | 502 dataBuf = (double*)(db+dataoffset); |
506 l2normTable = (double*)(db+l2normTableOffset); | 503 l2normTable = (double*)(db+l2normTableOffset); |
507 timesTable = (double*)(db+timesTableOffset); | 504 timesTable = (double*)(db+timesTableOffset); |
508 | |
509 } | 505 } |
510 | 506 |
511 void audioDB::insert(const char* dbName, const char* inFile){ | 507 void audioDB::insert(const char* dbName, const char* inFile){ |
512 | 508 |
513 initTables(dbName, 1, inFile); | 509 initTables(dbName, 1, inFile); |
942 | 938 |
943 | 939 |
944 | 940 |
945 void audioDB::query(const char* dbName, const char* inFile, adb__queryResult *adbQueryResult){ | 941 void audioDB::query(const char* dbName, const char* inFile, adb__queryResult *adbQueryResult){ |
946 switch(queryType){ | 942 switch(queryType){ |
947 case O2_FLAG_POINT_QUERY: | 943 case O2_POINT_QUERY: |
948 pointQuery(dbName, inFile, adbQueryResult); | 944 pointQuery(dbName, inFile, adbQueryResult); |
949 break; | 945 break; |
950 case O2_FLAG_SEQUENCE_QUERY: | 946 case O2_SEQUENCE_QUERY: |
951 if(radius==0) | 947 if(radius==0) |
952 trackSequenceQueryNN(dbName, inFile, adbQueryResult); | 948 trackSequenceQueryNN(dbName, inFile, adbQueryResult); |
953 else | 949 else |
954 trackSequenceQueryRad(dbName, inFile, adbQueryResult); | 950 trackSequenceQueryRad(dbName, inFile, adbQueryResult); |
955 break; | 951 break; |
956 case O2_FLAG_TRACK_QUERY: | 952 case O2_TRACK_QUERY: |
957 trackPointQuery(dbName, inFile, adbQueryResult); | 953 trackPointQuery(dbName, inFile, adbQueryResult); |
958 break; | 954 break; |
959 default: | 955 default: |
960 error("unrecognized queryType in query()"); | 956 error("unrecognized queryType in query()"); |
961 | 957 |
1108 } | 1104 } |
1109 } | 1105 } |
1110 } | 1106 } |
1111 } | 1107 } |
1112 else{ // Process Web Services Query | 1108 else{ // Process Web Services Query |
1113 int listLen = pointNN; | 1109 int listLen; |
1110 for(k = 0; k < pointNN; k++) { | |
1111 if(distances[k] == -DBL_MAX) | |
1112 break; | |
1113 } | |
1114 listLen = k; | |
1115 | |
1114 adbQueryResult->__sizeRlist=listLen; | 1116 adbQueryResult->__sizeRlist=listLen; |
1115 adbQueryResult->__sizeDist=listLen; | 1117 adbQueryResult->__sizeDist=listLen; |
1116 adbQueryResult->__sizeQpos=listLen; | 1118 adbQueryResult->__sizeQpos=listLen; |
1117 adbQueryResult->__sizeSpos=listLen; | 1119 adbQueryResult->__sizeSpos=listLen; |
1118 adbQueryResult->Rlist= new char*[listLen]; | 1120 adbQueryResult->Rlist= new char*[listLen]; |
1119 adbQueryResult->Dist = new double[listLen]; | 1121 adbQueryResult->Dist = new double[listLen]; |
1120 adbQueryResult->Qpos = new int[listLen]; | 1122 adbQueryResult->Qpos = new unsigned int[listLen]; |
1121 adbQueryResult->Spos = new int[listLen]; | 1123 adbQueryResult->Spos = new unsigned int[listLen]; |
1122 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ | 1124 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ |
1123 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; | 1125 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; |
1124 adbQueryResult->Dist[k]=distances[k]; | 1126 adbQueryResult->Dist[k]=distances[k]; |
1125 adbQueryResult->Qpos[k]=qIndexes[k]; | 1127 adbQueryResult->Qpos[k]=qIndexes[k]; |
1126 unsigned cumTrack=0; | 1128 unsigned cumTrack=0; |
1370 adbQueryResult->__sizeDist=listLen; | 1372 adbQueryResult->__sizeDist=listLen; |
1371 adbQueryResult->__sizeQpos=listLen; | 1373 adbQueryResult->__sizeQpos=listLen; |
1372 adbQueryResult->__sizeSpos=listLen; | 1374 adbQueryResult->__sizeSpos=listLen; |
1373 adbQueryResult->Rlist= new char*[listLen]; | 1375 adbQueryResult->Rlist= new char*[listLen]; |
1374 adbQueryResult->Dist = new double[listLen]; | 1376 adbQueryResult->Dist = new double[listLen]; |
1375 adbQueryResult->Qpos = new int[listLen]; | 1377 adbQueryResult->Qpos = new unsigned int[listLen]; |
1376 adbQueryResult->Spos = new int[listLen]; | 1378 adbQueryResult->Spos = new unsigned int[listLen]; |
1377 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ | 1379 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ |
1378 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; | 1380 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; |
1379 adbQueryResult->Dist[k]=trackDistances[k]; | 1381 adbQueryResult->Dist[k]=trackDistances[k]; |
1380 adbQueryResult->Qpos[k]=trackQIndexes[k]; | 1382 adbQueryResult->Qpos[k]=trackQIndexes[k]; |
1381 adbQueryResult->Spos[k]=trackSIndexes[k]; | 1383 adbQueryResult->Spos[k]=trackSIndexes[k]; |
1868 adbQueryResult->__sizeDist=listLen; | 1870 adbQueryResult->__sizeDist=listLen; |
1869 adbQueryResult->__sizeQpos=listLen; | 1871 adbQueryResult->__sizeQpos=listLen; |
1870 adbQueryResult->__sizeSpos=listLen; | 1872 adbQueryResult->__sizeSpos=listLen; |
1871 adbQueryResult->Rlist= new char*[listLen]; | 1873 adbQueryResult->Rlist= new char*[listLen]; |
1872 adbQueryResult->Dist = new double[listLen]; | 1874 adbQueryResult->Dist = new double[listLen]; |
1873 adbQueryResult->Qpos = new int[listLen]; | 1875 adbQueryResult->Qpos = new unsigned int[listLen]; |
1874 adbQueryResult->Spos = new int[listLen]; | 1876 adbQueryResult->Spos = new unsigned int[listLen]; |
1875 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ | 1877 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ |
1876 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; | 1878 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; |
1877 adbQueryResult->Dist[k]=trackDistances[k]; | 1879 adbQueryResult->Dist[k]=trackDistances[k]; |
1878 adbQueryResult->Qpos[k]=trackQIndexes[k]; | 1880 adbQueryResult->Qpos[k]=trackQIndexes[k]; |
1879 adbQueryResult->Spos[k]=trackSIndexes[k]; | 1881 adbQueryResult->Spos[k]=trackSIndexes[k]; |
2344 adbQueryResult->__sizeDist=listLen; | 2346 adbQueryResult->__sizeDist=listLen; |
2345 adbQueryResult->__sizeQpos=listLen; | 2347 adbQueryResult->__sizeQpos=listLen; |
2346 adbQueryResult->__sizeSpos=listLen; | 2348 adbQueryResult->__sizeSpos=listLen; |
2347 adbQueryResult->Rlist= new char*[listLen]; | 2349 adbQueryResult->Rlist= new char*[listLen]; |
2348 adbQueryResult->Dist = new double[listLen]; | 2350 adbQueryResult->Dist = new double[listLen]; |
2349 adbQueryResult->Qpos = new int[listLen]; | 2351 adbQueryResult->Qpos = new unsigned int[listLen]; |
2350 adbQueryResult->Spos = new int[listLen]; | 2352 adbQueryResult->Spos = new unsigned int[listLen]; |
2351 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ | 2353 for(k=0; k<(unsigned)adbQueryResult->__sizeRlist; k++){ |
2352 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; | 2354 adbQueryResult->Rlist[k]=new char[O2_MAXFILESTR]; |
2353 adbQueryResult->Dist[k]=trackDistances[k]; | 2355 adbQueryResult->Dist[k]=trackDistances[k]; |
2354 adbQueryResult->Qpos[k]=trackQIndexes[k]; | 2356 adbQueryResult->Qpos[k]=trackQIndexes[k]; |
2355 adbQueryResult->Spos[k]=trackSIndexes[k]; | 2357 adbQueryResult->Spos[k]=trackSIndexes[k]; |
2447 } | 2449 } |
2448 */ | 2450 */ |
2449 X+=dim; | 2451 X+=dim; |
2450 } | 2452 } |
2451 unsigned offset; | 2453 unsigned offset; |
2452 if(append) | 2454 if(append) { |
2453 offset=dbH->length/(dbH->dim*sizeof(double)); // number of vectors | 2455 // FIXME: a hack, a very palpable hack: the vectors have already |
2454 else | 2456 // been inserted, and dbH->length has already been updated. We |
2457 // need to subtract off again the number of vectors that we've | |
2458 // inserted this time... | |
2459 offset=(dbH->length/(dbH->dim*sizeof(double)))-n; // number of vectors | |
2460 } else { | |
2455 offset=0; | 2461 offset=0; |
2462 } | |
2456 memcpy(l2normTable+offset, l2buf, n*sizeof(double)); | 2463 memcpy(l2normTable+offset, l2buf, n*sizeof(double)); |
2457 if(l2buf) | 2464 if(l2buf) |
2458 delete[] l2buf; | 2465 delete[] l2buf; |
2459 if(verbosity>2) { | 2466 if(verbosity>2) { |
2460 cerr << "done..." << endl; | 2467 cerr << "done..." << endl; |
2465 // Start an audioDB server on the host | 2472 // Start an audioDB server on the host |
2466 void audioDB::startServer(){ | 2473 void audioDB::startServer(){ |
2467 struct soap soap; | 2474 struct soap soap; |
2468 int m, s; // master and slave sockets | 2475 int m, s; // master and slave sockets |
2469 soap_init(&soap); | 2476 soap_init(&soap); |
2477 // FIXME: largely this use of SO_REUSEADDR is to make writing (and | |
2478 // running) test cases more convenient, so that multiple test runs | |
2479 // in close succession don't fail because of a bin() error. | |
2480 // Investigate whether there are any potential drawbacks in this, | |
2481 // and also whether there's a better way to write the tests. -- | |
2482 // CSR, 2007-10-03 | |
2483 soap.bind_flags |= SO_REUSEADDR; | |
2470 m = soap_bind(&soap, NULL, port, 100); | 2484 m = soap_bind(&soap, NULL, port, 100); |
2471 if (m < 0) | 2485 if (m < 0) |
2472 soap_print_fault(&soap, stderr); | 2486 soap_print_fault(&soap, stderr); |
2473 else | 2487 else |
2474 { | 2488 { |
2513 | 2527 |
2514 int adb__query(struct soap* soap, xsd__string dbName, xsd__string qKey, xsd__string keyList, xsd__string timesFileName, xsd__int qType, xsd__int qPos, xsd__int pointNN, xsd__int trackNN, xsd__int seqLen, adb__queryResult &adbQueryResult){ | 2528 int adb__query(struct soap* soap, xsd__string dbName, xsd__string qKey, xsd__string keyList, xsd__string timesFileName, xsd__int qType, xsd__int qPos, xsd__int pointNN, xsd__int trackNN, xsd__int seqLen, adb__queryResult &adbQueryResult){ |
2515 char queryType[256]; | 2529 char queryType[256]; |
2516 for(int k=0; k<256; k++) | 2530 for(int k=0; k<256; k++) |
2517 queryType[k]='\0'; | 2531 queryType[k]='\0'; |
2518 if(qType == O2_FLAG_POINT_QUERY) | 2532 if(qType == O2_POINT_QUERY) |
2519 strncpy(queryType, "point", strlen("point")); | 2533 strncpy(queryType, "point", strlen("point")); |
2520 else if (qType == O2_FLAG_SEQUENCE_QUERY) | 2534 else if (qType == O2_SEQUENCE_QUERY) |
2521 strncpy(queryType, "sequence", strlen("sequence")); | 2535 strncpy(queryType, "sequence", strlen("sequence")); |
2522 else if(qType == O2_FLAG_TRACK_QUERY) | 2536 else if(qType == O2_TRACK_QUERY) |
2523 strncpy(queryType,"track", strlen("track")); | 2537 strncpy(queryType,"track", strlen("track")); |
2524 else | 2538 else |
2525 strncpy(queryType, "", strlen("")); | 2539 strncpy(queryType, "", strlen("")); |
2526 | 2540 |
2527 if(pointNN==0) | 2541 if(pointNN==0) |
2573 } | 2587 } |
2574 | 2588 |
2575 int main(const unsigned argc, char* const argv[]){ | 2589 int main(const unsigned argc, char* const argv[]){ |
2576 audioDB(argc, argv); | 2590 audioDB(argc, argv); |
2577 } | 2591 } |
2592 |