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