mas01cr@0
|
1 #include "audioDB.h"
|
mas01cr@0
|
2
|
mas01mc@308
|
3 LSH* SERVER_LSH_INDEX_SINGLETON;
|
mas01mc@324
|
4 char* SERVER_ADB_ROOT;
|
mas01mc@324
|
5 char* SERVER_ADB_FEATURE_ROOT;
|
mas01mc@308
|
6
|
mas01mc@292
|
7 PointPair::PointPair(Uns32T a, Uns32T b, Uns32T c):trackID(a),qpos(b),spos(c){};
|
mas01mc@292
|
8
|
mas01mc@292
|
9 bool operator<(const PointPair& a, const PointPair& b){
|
mas01mc@324
|
10 return ( (a.trackID<b.trackID) ||
|
mas01mc@324
|
11 ( (a.trackID==b.trackID) &&
|
mas01mc@324
|
12 ( (a.spos<b.spos) || ( (a.spos==b.spos) && (a.qpos < b.qpos) )) ) );
|
mas01mc@292
|
13 }
|
mas01mc@292
|
14
|
mas01mc@292
|
15 bool operator>(const PointPair& a, const PointPair& b){
|
mas01mc@324
|
16 return ( (a.trackID>b.trackID) ||
|
mas01mc@324
|
17 ( (a.trackID==b.trackID) &&
|
mas01mc@324
|
18 ( (a.spos>b.spos) || ( (a.spos==b.spos) && (a.qpos > b.qpos) )) ) );
|
mas01mc@292
|
19 }
|
mas01mc@292
|
20
|
mas01mc@292
|
21 bool operator==(const PointPair& a, const PointPair& b){
|
mas01mc@292
|
22 return ( (a.trackID==b.trackID) && (a.qpos==b.qpos) && (a.spos==b.spos) );
|
mas01mc@292
|
23 }
|
mas01mc@292
|
24
|
mas01cr@345
|
25 audioDB::audioDB(const unsigned argc, const char *const argv[]): O2_AUDIODB_INITIALIZERS
|
mas01cr@76
|
26 {
|
mas01cr@0
|
27 if(processArgs(argc, argv)<0){
|
mas01cr@0
|
28 printf("No command found.\n");
|
mas01cr@0
|
29 cmdline_parser_print_version ();
|
mas01cr@0
|
30 if (strlen(gengetopt_args_info_purpose) > 0)
|
mas01cr@0
|
31 printf("%s\n", gengetopt_args_info_purpose);
|
mas01cr@0
|
32 printf("%s\n", gengetopt_args_info_usage);
|
mas01cr@0
|
33 printf("%s\n", gengetopt_args_info_help[1]);
|
mas01cr@0
|
34 printf("%s\n", gengetopt_args_info_help[2]);
|
mas01cr@0
|
35 printf("%s\n", gengetopt_args_info_help[0]);
|
mas01cr@151
|
36 error("No command found");
|
mas01cr@0
|
37 }
|
mas01cr@77
|
38
|
mas01mc@324
|
39 // Perform database prefix substitution
|
mas01mc@328
|
40 if(dbName && adb_root)
|
mas01mc@324
|
41 prefix_name((char** const)&dbName, adb_root);
|
mas01mc@324
|
42
|
mas01cr@0
|
43 if(O2_ACTION(COM_SERVER))
|
mas01cr@0
|
44 startServer();
|
mas01cr@0
|
45
|
mas01cr@0
|
46 else if(O2_ACTION(COM_CREATE))
|
mas01cr@0
|
47 create(dbName);
|
mas01cr@0
|
48
|
mas01cr@0
|
49 else if(O2_ACTION(COM_INSERT))
|
mas01cr@0
|
50 insert(dbName, inFile);
|
mas01cr@0
|
51
|
mas01cr@0
|
52 else if(O2_ACTION(COM_BATCHINSERT))
|
mas01cr@0
|
53 batchinsert(dbName, inFile);
|
mas01cr@0
|
54
|
mas01cr@0
|
55 else if(O2_ACTION(COM_QUERY))
|
mas01mc@307
|
56 if(isClient){
|
mas01mc@329
|
57 if(query_from_key){
|
mas01mc@332
|
58 VERB_LOG(1, "Calling web services query %s on database %s, query=%s\n", radius>0?"(Radius)":"(NN)", dbName, (key&&strlen(key))?key:inFile);
|
mas01mc@328
|
59 ws_query_by_key(dbName, key, inFile, (char*)hostport);
|
mas01mc@329
|
60 }
|
mas01mc@329
|
61 else{
|
mas01mc@332
|
62 VERB_LOG(1, "Calling web services query on database %s, query=%s\n", dbName, (key&&strlen(key))?key:inFile);
|
mas01mc@307
|
63 ws_query(dbName, inFile, (char*)hostport);
|
mas01mc@329
|
64 }
|
mas01mc@307
|
65 }
|
mas01cr@0
|
66 else
|
mas01cr@76
|
67 query(dbName, inFile);
|
mas01cr@0
|
68
|
mas01cr@0
|
69 else if(O2_ACTION(COM_STATUS))
|
mas01cr@0
|
70 if(isClient)
|
mas01cr@0
|
71 ws_status(dbName,(char*)hostport);
|
mas01cr@0
|
72 else
|
mas01cr@0
|
73 status(dbName);
|
mas01cr@280
|
74
|
mas01cr@280
|
75 else if(O2_ACTION(COM_SAMPLE))
|
mas01cr@280
|
76 sample(dbName);
|
mas01cr@0
|
77
|
mas01cr@0
|
78 else if(O2_ACTION(COM_L2NORM))
|
mas01cr@0
|
79 l2norm(dbName);
|
mas01cr@0
|
80
|
mas01cr@193
|
81 else if(O2_ACTION(COM_POWER))
|
mas01cr@193
|
82 power_flag(dbName);
|
mas01cr@193
|
83
|
mas01cr@0
|
84 else if(O2_ACTION(COM_DUMP))
|
mas01cr@0
|
85 dump(dbName);
|
mas01mc@292
|
86
|
mas01mc@334
|
87 else if(O2_ACTION(COM_LISZT))
|
mas01mc@334
|
88 if(isClient)
|
mas01mc@334
|
89 ws_liszt(dbName, (char*) hostport);
|
mas01mc@334
|
90 else
|
mas01mc@334
|
91 liszt(dbName, lisztOffset, lisztLength);
|
mas01mc@334
|
92
|
mas01mc@292
|
93 else if(O2_ACTION(COM_INDEX))
|
mas01mc@292
|
94 index_index_db(dbName);
|
mas01cr@0
|
95
|
mas01cr@0
|
96 else
|
mas01cr@0
|
97 error("Unrecognized command",command);
|
mas01cr@0
|
98 }
|
mas01cr@0
|
99
|
mas01cr@345
|
100 audioDB::audioDB(const unsigned argc, const char *const argv[], adb__queryResponse *adbQueryResponse): O2_AUDIODB_INITIALIZERS
|
mas01cr@76
|
101 {
|
mas01cr@97
|
102 try {
|
mas01mc@338
|
103 isServer = 1; // Set to make errors report over SOAP
|
mas01cr@97
|
104 processArgs(argc, argv);
|
mas01mc@324
|
105 // Perform database prefix substitution
|
mas01mc@328
|
106 if(dbName && adb_root)
|
mas01mc@324
|
107 prefix_name((char** const)&dbName, adb_root);
|
mas01cr@97
|
108 assert(O2_ACTION(COM_QUERY));
|
mas01cr@133
|
109 query(dbName, inFile, adbQueryResponse);
|
mas01cr@97
|
110 } catch(char *err) {
|
mas01cr@97
|
111 cleanup();
|
mas01cr@97
|
112 throw(err);
|
mas01cr@97
|
113 }
|
mas01cr@76
|
114 }
|
mas01cr@76
|
115
|
mas01cr@345
|
116 audioDB::audioDB(const unsigned argc, const char* const argv[], adb__statusResponse *adbStatusResponse): O2_AUDIODB_INITIALIZERS
|
mas01cr@76
|
117 {
|
mas01cr@97
|
118 try {
|
mas01mc@338
|
119 isServer = 1; // Set to make errors report over SOAP
|
mas01cr@97
|
120 processArgs(argc, argv);
|
mas01mc@324
|
121 // Perform database prefix substitution
|
mas01mc@328
|
122 if(dbName && adb_root)
|
mas01mc@324
|
123 prefix_name((char** const)&dbName, adb_root);
|
mas01cr@97
|
124 assert(O2_ACTION(COM_STATUS));
|
mas01cr@133
|
125 status(dbName, adbStatusResponse);
|
mas01cr@97
|
126 } catch(char *err) {
|
mas01cr@97
|
127 cleanup();
|
mas01cr@97
|
128 throw(err);
|
mas01cr@97
|
129 }
|
mas01cr@76
|
130 }
|
mas01cr@76
|
131
|
mas01cr@345
|
132 audioDB::audioDB(const unsigned argc, const char *const argv[], adb__lisztResponse *adbLisztResponse): O2_AUDIODB_INITIALIZERS
|
mas01mc@334
|
133 {
|
mas01mc@334
|
134 try {
|
mas01mc@338
|
135 isServer = 1; // Set to make errors report over SOAP
|
mas01mc@338
|
136 processArgs(argc, argv);
|
mas01mc@334
|
137 // Perform database prefix substitution
|
mas01mc@334
|
138 if(dbName && adb_root)
|
mas01mc@334
|
139 prefix_name((char** const)&dbName, adb_root);
|
mas01mc@334
|
140 assert(O2_ACTION(COM_LISZT));
|
mas01mc@334
|
141 liszt(dbName, lisztOffset, lisztLength, adbLisztResponse);
|
mas01mc@334
|
142 } catch(char *err) {
|
mas01mc@334
|
143 cleanup();
|
mas01mc@334
|
144 throw(err);
|
mas01mc@334
|
145 }
|
mas01mc@334
|
146 }
|
mas01mc@334
|
147
|
mas01cr@97
|
148 void audioDB::cleanup() {
|
mas01cr@122
|
149 cmdline_parser_free(&args_info);
|
mas01cr@0
|
150 if(indata)
|
mas01cr@0
|
151 munmap(indata,statbuf.st_size);
|
mas01cr@0
|
152 if(db)
|
mas01cr@196
|
153 munmap(db,getpagesize());
|
mas01cr@196
|
154 if(fileTable)
|
mas01cr@196
|
155 munmap(fileTable, fileTableLength);
|
mas01cr@196
|
156 if(trackTable)
|
mas01cr@196
|
157 munmap(trackTable, trackTableLength);
|
mas01cr@196
|
158 if(dataBuf)
|
mas01cr@196
|
159 munmap(dataBuf, dataBufLength);
|
mas01cr@196
|
160 if(timesTable)
|
mas01cr@196
|
161 munmap(timesTable, timesTableLength);
|
mas01mc@314
|
162 if(powerTable)
|
mas01mc@314
|
163 munmap(powerTable, powerTableLength);
|
mas01cr@196
|
164 if(l2normTable)
|
mas01cr@196
|
165 munmap(l2normTable, l2normTableLength);
|
mas01mc@324
|
166 if(featureFileNameTable)
|
mas01mc@324
|
167 munmap(featureFileNameTable, fileTableLength);
|
mas01mc@324
|
168 if(timesFileNameTable)
|
mas01mc@324
|
169 munmap(timesFileNameTable, fileTableLength);
|
mas01mc@324
|
170 if(powerFileNameTable)
|
mas01mc@324
|
171 munmap(powerFileNameTable, fileTableLength);
|
mas01mc@292
|
172 if(trackOffsetTable)
|
mas01mc@292
|
173 delete trackOffsetTable;
|
mas01mc@292
|
174 if(reporter)
|
mas01mc@292
|
175 delete reporter;
|
mas01mc@292
|
176 if(exact_evaluation_queue)
|
mas01mc@292
|
177 delete exact_evaluation_queue;
|
mas01cr@284
|
178 if(rng)
|
mas01cr@284
|
179 gsl_rng_free(rng);
|
mas01mc@292
|
180 if(vv)
|
mas01mc@292
|
181 delete vv;
|
mas01cr@0
|
182 if(dbfid>0)
|
mas01cr@0
|
183 close(dbfid);
|
mas01cr@0
|
184 if(infid>0)
|
mas01cr@0
|
185 close(infid);
|
mas01cr@0
|
186 if(dbH)
|
mas01cr@0
|
187 delete dbH;
|
mas01mc@308
|
188 if(lsh!=SERVER_LSH_INDEX_SINGLETON)
|
mas01mc@308
|
189 delete lsh;
|
mas01cr@0
|
190 }
|
mas01cr@0
|
191
|
mas01cr@97
|
192 audioDB::~audioDB(){
|
mas01cr@97
|
193 cleanup();
|
mas01cr@97
|
194 }
|
mas01cr@97
|
195
|
mas01cr@345
|
196 int audioDB::processArgs(const unsigned argc, const char *const argv[]){
|
mas01cr@0
|
197
|
mas01cr@0
|
198 if(argc<2){
|
mas01cr@0
|
199 cmdline_parser_print_version ();
|
mas01cr@0
|
200 if (strlen(gengetopt_args_info_purpose) > 0)
|
mas01cr@0
|
201 printf("%s\n", gengetopt_args_info_purpose);
|
mas01cr@0
|
202 printf("%s\n", gengetopt_args_info_usage);
|
mas01cr@0
|
203 printf("%s\n", gengetopt_args_info_help[1]);
|
mas01cr@0
|
204 printf("%s\n", gengetopt_args_info_help[2]);
|
mas01cr@0
|
205 printf("%s\n", gengetopt_args_info_help[0]);
|
mas01cr@0
|
206 exit(0);
|
mas01cr@0
|
207 }
|
mas01cr@0
|
208
|
mas01cr@345
|
209 /* KLUDGE: gengetopt generates a function which is not completely
|
mas01cr@345
|
210 const-clean in its declaration. We cast argv here to keep the
|
mas01cr@345
|
211 compiler happy. -- CSR, 2008-10-08 */
|
mas01cr@345
|
212 if (cmdline_parser (argc, (char *const *) argv, &args_info) != 0)
|
mas01cr@151
|
213 error("Error parsing command line");
|
mas01cr@0
|
214
|
mas01cr@0
|
215 if(args_info.help_given){
|
mas01cr@0
|
216 cmdline_parser_print_help();
|
mas01cr@0
|
217 exit(0);
|
mas01cr@0
|
218 }
|
mas01cr@0
|
219
|
mas01cr@0
|
220 if(args_info.verbosity_given){
|
mas01cr@239
|
221 verbosity = args_info.verbosity_arg;
|
mas01cr@239
|
222 if(verbosity < 0 || verbosity > 10){
|
mas01cr@239
|
223 std::cerr << "Warning: verbosity out of range, setting to 1" << std::endl;
|
mas01cr@239
|
224 verbosity = 1;
|
mas01cr@0
|
225 }
|
mas01cr@0
|
226 }
|
mas01cr@0
|
227
|
mas01cr@129
|
228 if(args_info.size_given) {
|
mas01cr@256
|
229 if(args_info.datasize_given) {
|
mas01cr@256
|
230 error("both --size and --datasize given", "");
|
mas01cr@256
|
231 }
|
mas01cr@256
|
232 if(args_info.ntracks_given) {
|
mas01cr@256
|
233 error("both --size and --ntracks given", "");
|
mas01cr@256
|
234 }
|
mas01cr@256
|
235 if(args_info.datadim_given) {
|
mas01cr@256
|
236 error("both --size and --datadim given", "");
|
mas01cr@256
|
237 }
|
mas01cr@196
|
238 if (args_info.size_arg < 50 || args_info.size_arg > 32000) {
|
mas01cr@129
|
239 error("Size out of range", "");
|
mas01cr@129
|
240 }
|
mas01cr@256
|
241 double ratio = (double) args_info.size_arg * 1000000 / ((double) O2_DEFAULTDBSIZE);
|
mas01cr@256
|
242 /* FIXME: what's the safe way of doing this? */
|
mas01cr@256
|
243 datasize = (unsigned int) ceil(datasize * ratio);
|
mas01cr@256
|
244 ntracks = (unsigned int) ceil(ntracks * ratio);
|
mas01cr@256
|
245 } else {
|
mas01cr@256
|
246 if(args_info.datasize_given) {
|
mas01cr@256
|
247 datasize = args_info.datasize_arg;
|
mas01cr@256
|
248 }
|
mas01cr@256
|
249 if(args_info.ntracks_given) {
|
mas01cr@256
|
250 ntracks = args_info.ntracks_arg;
|
mas01cr@256
|
251 }
|
mas01cr@256
|
252 if(args_info.datadim_given) {
|
mas01cr@256
|
253 datadim = args_info.datadim_arg;
|
mas01cr@256
|
254 }
|
mas01cr@129
|
255 }
|
mas01cr@129
|
256
|
mas01cr@239
|
257 if(args_info.radius_given) {
|
mas01cr@239
|
258 radius = args_info.radius_arg;
|
mas01mc@307
|
259 if(radius < 0 || radius > 1000000000) {
|
mas01cr@77
|
260 error("radius out of range");
|
mas01cr@239
|
261 } else {
|
mas01cr@239
|
262 VERB_LOG(3, "Setting radius to %f\n", radius);
|
mas01mc@17
|
263 }
|
mas01mc@17
|
264 }
|
mas01mc@17
|
265
|
mas01mc@292
|
266 sequenceLength = args_info.sequencelength_arg;
|
mas01mc@292
|
267 if(sequenceLength < 1 || sequenceLength > 1000) {
|
mas01mc@292
|
268 error("seqlen out of range: 1 <= seqlen <= 1000");
|
mas01mc@292
|
269 }
|
mas01mc@292
|
270 sequenceHop = args_info.sequencehop_arg;
|
mas01mc@292
|
271 if(sequenceHop < 1 || sequenceHop > 1000) {
|
mas01mc@292
|
272 error("seqhop out of range: 1 <= seqhop <= 1000");
|
mas01mc@292
|
273 }
|
mas01mc@292
|
274
|
mas01mc@292
|
275 if (args_info.absolute_threshold_given) {
|
mas01mc@292
|
276 if (args_info.absolute_threshold_arg >= 0) {
|
mas01mc@292
|
277 error("absolute threshold out of range: should be negative");
|
mas01mc@292
|
278 }
|
mas01mc@292
|
279 use_absolute_threshold = true;
|
mas01mc@292
|
280 absolute_threshold = args_info.absolute_threshold_arg;
|
mas01mc@292
|
281 }
|
mas01mc@292
|
282 if (args_info.relative_threshold_given) {
|
mas01mc@292
|
283 use_relative_threshold = true;
|
mas01mc@292
|
284 relative_threshold = args_info.relative_threshold_arg;
|
mas01mc@292
|
285 }
|
mas01mc@292
|
286
|
mas01mc@324
|
287 if (args_info.adb_root_given){
|
mas01mc@324
|
288 adb_root = args_info.adb_root_arg;
|
mas01mc@324
|
289 }
|
mas01mc@324
|
290
|
mas01mc@324
|
291 if (args_info.adb_feature_root_given){
|
mas01mc@324
|
292 adb_feature_root = args_info.adb_feature_root_arg;
|
mas01mc@324
|
293 }
|
mas01mc@324
|
294
|
mas01mc@324
|
295 // perform dbName path prefix SERVER-side subsitution
|
mas01mc@324
|
296 if(SERVER_ADB_ROOT && !adb_root)
|
mas01mc@324
|
297 adb_root = SERVER_ADB_ROOT;
|
mas01mc@324
|
298 if(SERVER_ADB_FEATURE_ROOT && !adb_feature_root)
|
mas01mc@324
|
299 adb_feature_root = SERVER_ADB_FEATURE_ROOT;
|
mas01mc@339
|
300
|
mas01cr@0
|
301 if(args_info.SERVER_given){
|
mas01cr@0
|
302 command=COM_SERVER;
|
mas01cr@0
|
303 port=args_info.SERVER_arg;
|
mas01cr@0
|
304 if(port<100 || port > 100000)
|
mas01cr@0
|
305 error("port out of range");
|
mas01cr@105
|
306 #if defined(O2_DEBUG)
|
mas01cr@104
|
307 struct sigaction sa;
|
mas01cr@104
|
308 sa.sa_sigaction = sigterm_action;
|
mas01cr@104
|
309 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
|
mas01cr@104
|
310 sigaction(SIGTERM, &sa, NULL);
|
mas01cr@104
|
311 sa.sa_sigaction = sighup_action;
|
mas01cr@104
|
312 sa.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
|
mas01cr@104
|
313 sigaction(SIGHUP, &sa, NULL);
|
mas01cr@105
|
314 #endif
|
mas01mc@308
|
315 if(args_info.load_index_given){
|
mas01mc@308
|
316 if(!args_info.database_given)
|
mas01mc@308
|
317 error("load_index requires a --database argument");
|
mas01mc@308
|
318 else
|
mas01mc@308
|
319 dbName=args_info.database_arg;
|
mas01mc@308
|
320 if(!args_info.radius_given)
|
mas01mc@308
|
321 error("load_index requires a --radius argument");
|
mas01mc@308
|
322 if(!args_info.sequencelength_given)
|
mas01mc@308
|
323 error("load_index requires a --sequenceLength argument");
|
mas01mc@308
|
324 WS_load_index = true;
|
mas01mc@308
|
325 }
|
mas01cr@0
|
326 return 0;
|
mas01cr@0
|
327 }
|
mas01cr@0
|
328
|
mas01cr@0
|
329 // No return on client command, find database command
|
mas01cr@105
|
330 if(args_info.client_given){
|
mas01cr@105
|
331 command=COM_CLIENT;
|
mas01cr@105
|
332 hostport=args_info.client_arg;
|
mas01cr@105
|
333 isClient=1;
|
mas01cr@105
|
334 }
|
mas01cr@0
|
335
|
mas01cr@105
|
336 if(args_info.NEW_given){
|
mas01cr@105
|
337 command=COM_CREATE;
|
mas01cr@105
|
338 dbName=args_info.database_arg;
|
mas01cr@105
|
339 return 0;
|
mas01cr@105
|
340 }
|
mas01cr@0
|
341
|
mas01cr@105
|
342 if(args_info.STATUS_given){
|
mas01cr@105
|
343 command=COM_STATUS;
|
mas01cr@105
|
344 dbName=args_info.database_arg;
|
mas01cr@105
|
345 return 0;
|
mas01cr@105
|
346 }
|
mas01cr@0
|
347
|
mas01cr@280
|
348 if(args_info.SAMPLE_given) {
|
mas01cr@280
|
349 command = COM_SAMPLE;
|
mas01cr@280
|
350 dbName = args_info.database_arg;
|
mas01cr@280
|
351 sequenceLength = args_info.sequencelength_arg;
|
mas01cr@280
|
352 if(sequenceLength < 1 || sequenceLength > 1000) {
|
mas01cr@280
|
353 error("seqlen out of range: 1 <= seqlen <= 1000");
|
mas01cr@280
|
354 }
|
mas01cr@280
|
355 nsamples = args_info.nsamples_arg;
|
mas01cr@280
|
356 return 0;
|
mas01cr@280
|
357 }
|
mas01cr@280
|
358
|
mas01cr@105
|
359 if(args_info.DUMP_given){
|
mas01cr@105
|
360 command=COM_DUMP;
|
mas01cr@105
|
361 dbName=args_info.database_arg;
|
mas01cr@131
|
362 output = args_info.output_arg;
|
mas01cr@105
|
363 return 0;
|
mas01cr@105
|
364 }
|
mas01cr@0
|
365
|
mas01cr@105
|
366 if(args_info.L2NORM_given){
|
mas01cr@105
|
367 command=COM_L2NORM;
|
mas01cr@105
|
368 dbName=args_info.database_arg;
|
mas01cr@105
|
369 return 0;
|
mas01cr@105
|
370 }
|
mas01cr@0
|
371
|
mas01cr@193
|
372 if(args_info.POWER_given){
|
mas01cr@193
|
373 command=COM_POWER;
|
mas01cr@193
|
374 dbName=args_info.database_arg;
|
mas01cr@193
|
375 return 0;
|
mas01cr@193
|
376 }
|
mas01cr@193
|
377
|
mas01cr@105
|
378 if(args_info.INSERT_given){
|
mas01cr@105
|
379 command=COM_INSERT;
|
mas01cr@105
|
380 dbName=args_info.database_arg;
|
mas01cr@105
|
381 inFile=args_info.features_arg;
|
mas01cr@105
|
382 if(args_info.key_given)
|
mas01mc@292
|
383 if(!args_info.features_given)
|
mas01mc@292
|
384 error("INSERT: '-k key' argument depends on '-f features'");
|
mas01mc@292
|
385 else
|
mas01mc@292
|
386 key=args_info.key_arg;
|
mas01cr@105
|
387 if(args_info.times_given){
|
mas01cr@105
|
388 timesFileName=args_info.times_arg;
|
mas01cr@105
|
389 if(strlen(timesFileName)>0){
|
mas01cr@239
|
390 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
|
mas01cr@105
|
391 error("Could not open times file for reading", timesFileName);
|
mas01cr@105
|
392 usingTimes=1;
|
mas01cr@105
|
393 }
|
mas01cr@105
|
394 }
|
mas01cr@193
|
395 if (args_info.power_given) {
|
mas01cr@193
|
396 powerFileName = args_info.power_arg;
|
mas01cr@193
|
397 if (strlen(powerFileName) > 0) {
|
mas01cr@193
|
398 if (!(powerfd = open(powerFileName, O_RDONLY))) {
|
mas01cr@193
|
399 error("Could not open power file for reading", powerFileName, "open");
|
mas01cr@193
|
400 }
|
mas01cr@193
|
401 usingPower = 1;
|
mas01cr@193
|
402 }
|
mas01cr@193
|
403 }
|
mas01cr@105
|
404 return 0;
|
mas01cr@105
|
405 }
|
mas01cr@105
|
406
|
mas01cr@105
|
407 if(args_info.BATCHINSERT_given){
|
mas01cr@105
|
408 command=COM_BATCHINSERT;
|
mas01cr@105
|
409 dbName=args_info.database_arg;
|
mas01cr@105
|
410 inFile=args_info.featureList_arg;
|
mas01cr@105
|
411 if(args_info.keyList_given)
|
mas01tc@298
|
412 if(!args_info.featureList_given)
|
mas01tc@300
|
413 error("BATCHINSERT: '-K keyList' argument depends on '-F featureList'");
|
mas01mc@292
|
414 else
|
mas01cr@304
|
415 key=args_info.keyList_arg; // INCONSISTENT NO CHECK
|
mas01cr@0
|
416
|
mas01cr@105
|
417 /* TO DO: REPLACE WITH
|
mas01cr@0
|
418 if(args_info.keyList_given){
|
mas01mc@18
|
419 trackFileName=args_info.keyList_arg;
|
mas01cr@239
|
420 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
|
mas01mc@18
|
421 error("Could not open keyList file for reading",trackFileName);
|
mas01cr@0
|
422 }
|
mas01cr@0
|
423 AND UPDATE BATCHINSERT()
|
mas01cr@105
|
424 */
|
mas01cr@105
|
425
|
mas01cr@105
|
426 if(args_info.timesList_given){
|
mas01cr@105
|
427 timesFileName=args_info.timesList_arg;
|
mas01cr@105
|
428 if(strlen(timesFileName)>0){
|
mas01cr@239
|
429 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
|
mas01cr@105
|
430 error("Could not open timesList file for reading", timesFileName);
|
mas01cr@105
|
431 usingTimes=1;
|
mas01cr@105
|
432 }
|
mas01cr@105
|
433 }
|
mas01cr@193
|
434 if(args_info.powerList_given){
|
mas01cr@193
|
435 powerFileName=args_info.powerList_arg;
|
mas01cr@193
|
436 if(strlen(powerFileName)>0){
|
mas01cr@239
|
437 if(!(powerFile = new std::ifstream(powerFileName,std::ios::in)))
|
mas01cr@193
|
438 error("Could not open powerList file for reading", powerFileName);
|
mas01cr@193
|
439 usingPower=1;
|
mas01cr@193
|
440 }
|
mas01cr@193
|
441 }
|
mas01cr@105
|
442 return 0;
|
mas01cr@105
|
443 }
|
mas01mc@292
|
444
|
mas01mc@292
|
445 // Set no_unit_norm flag
|
mas01mc@292
|
446 no_unit_norming = args_info.no_unit_norming_flag;
|
mas01mc@292
|
447 lsh_use_u_functions = args_info.lsh_use_u_functions_flag;
|
mas01mc@292
|
448
|
mas01mc@292
|
449 // LSH Index Command
|
mas01mc@292
|
450 if(args_info.INDEX_given){
|
mas01mc@292
|
451 if(radius <= 0 )
|
mas01mc@292
|
452 error("INDEXing requires a Radius argument");
|
mas01mc@292
|
453 if(!(sequenceLength>0 && sequenceLength <= O2_MAXSEQLEN))
|
mas01mc@292
|
454 error("INDEXing requires 1 <= sequenceLength <= 1000");
|
mas01mc@292
|
455 command=COM_INDEX;
|
mas01mc@337
|
456 if(!args_info.database_given)
|
mas01mc@337
|
457 error("INDEXing requires a database");
|
mas01mc@292
|
458 dbName=args_info.database_arg;
|
mas01mc@292
|
459
|
mas01mc@292
|
460 // Whether to store LSH hash tables for query in core (FORMAT2)
|
mas01mc@297
|
461 lsh_in_core = !args_info.lsh_on_disk_flag; // This flag is set to 0 if on_disk requested
|
mas01mc@292
|
462
|
mas01mc@292
|
463 lsh_param_w = args_info.lsh_w_arg;
|
mas01mc@292
|
464 if(!(lsh_param_w>0 && lsh_param_w<=O2_SERIAL_MAX_BINWIDTH))
|
mas01mc@292
|
465 error("Indexing parameter w out of range (0.0 < w <= 100.0)");
|
mas01mc@292
|
466
|
mas01mc@292
|
467 lsh_param_k = args_info.lsh_k_arg;
|
mas01mc@292
|
468 if(!(lsh_param_k>0 && lsh_param_k<=O2_SERIAL_MAX_FUNS))
|
mas01mc@292
|
469 error("Indexing parameter k out of range (1 <= k <= 100)");
|
mas01mc@292
|
470
|
mas01mc@292
|
471 lsh_param_m = args_info.lsh_m_arg;
|
mas01mc@292
|
472 if(!(lsh_param_m>0 && lsh_param_m<= (1 + (sqrt(1 + O2_SERIAL_MAX_TABLES*8.0)))/2.0))
|
mas01mc@292
|
473 error("Indexing parameter m out of range (1 <= m <= 20)");
|
mas01mc@292
|
474
|
mas01mc@292
|
475 lsh_param_N = args_info.lsh_N_arg;
|
mas01mc@292
|
476 if(!(lsh_param_N>0 && lsh_param_N<=O2_SERIAL_MAX_ROWS))
|
mas01mc@292
|
477 error("Indexing parameter N out of range (1 <= N <= 1000000)");
|
mas01mc@292
|
478
|
mas01mc@292
|
479 lsh_param_b = args_info.lsh_b_arg;
|
mas01mc@292
|
480 if(!(lsh_param_b>0 && lsh_param_b<=O2_SERIAL_MAX_TRACKBATCH))
|
mas01mc@292
|
481 error("Indexing parameter b out of range (1 <= b <= 10000)");
|
mas01mc@292
|
482
|
mas01mc@296
|
483 lsh_param_ncols = args_info.lsh_ncols_arg;
|
mas01mc@296
|
484 if(lsh_in_core) // We don't want to block rows with FORMAT2 indexing
|
mas01mc@296
|
485 lsh_param_ncols = O2_SERIAL_MAX_COLS;
|
mas01mc@292
|
486 if( !(lsh_param_ncols>0 && lsh_param_ncols<=O2_SERIAL_MAX_COLS))
|
mas01mc@292
|
487 error("Indexing parameter ncols out of range (1 <= ncols <= 1000");
|
mas01mc@292
|
488
|
mas01mc@292
|
489 return 0;
|
mas01mc@292
|
490 }
|
mas01mc@292
|
491
|
mas01cr@105
|
492 // Query command and arguments
|
mas01cr@105
|
493 if(args_info.QUERY_given){
|
mas01cr@105
|
494 command=COM_QUERY;
|
mas01cr@105
|
495 dbName=args_info.database_arg;
|
mas01mc@292
|
496 // XOR features and key search
|
mas01mc@292
|
497 if(!args_info.features_given && !args_info.key_given || (args_info.features_given && args_info.key_given))
|
mas01mc@292
|
498 error("QUERY requires exactly one of either -f features or -k key");
|
mas01mc@292
|
499 if(args_info.features_given)
|
mas01mc@292
|
500 inFile=args_info.features_arg; // query from file
|
mas01mc@292
|
501 else{
|
mas01mc@292
|
502 query_from_key = true;
|
mas01mc@292
|
503 key=args_info.key_arg; // query from key
|
mas01mc@292
|
504 }
|
mas01mc@292
|
505
|
mas01cr@105
|
506 if(args_info.keyList_given){
|
mas01cr@105
|
507 trackFileName=args_info.keyList_arg;
|
mas01cr@239
|
508 if(strlen(trackFileName)>0 && !(trackFile = new std::ifstream(trackFileName,std::ios::in)))
|
mas01cr@105
|
509 error("Could not open keyList file for reading",trackFileName);
|
mas01cr@105
|
510 }
|
mas01cr@105
|
511
|
mas01cr@105
|
512 if(args_info.times_given){
|
mas01cr@105
|
513 timesFileName=args_info.times_arg;
|
mas01cr@105
|
514 if(strlen(timesFileName)>0){
|
mas01cr@239
|
515 if(!(timesFile = new std::ifstream(timesFileName,std::ios::in)))
|
mas01cr@105
|
516 error("Could not open times file for reading", timesFileName);
|
mas01cr@105
|
517 usingTimes=1;
|
mas01cr@105
|
518 }
|
mas01cr@105
|
519 }
|
mas01cr@193
|
520
|
mas01cr@193
|
521 if(args_info.power_given){
|
mas01cr@193
|
522 powerFileName=args_info.power_arg;
|
mas01cr@193
|
523 if(strlen(powerFileName)>0){
|
mas01cr@193
|
524 if (!(powerfd = open(powerFileName, O_RDONLY))) {
|
mas01cr@193
|
525 error("Could not open power file for reading", powerFileName, "open");
|
mas01cr@193
|
526 }
|
mas01cr@193
|
527 usingPower = 1;
|
mas01cr@193
|
528 }
|
mas01cr@193
|
529 }
|
mas01cr@105
|
530
|
mas01cr@105
|
531 // query type
|
mas01cr@105
|
532 if(strncmp(args_info.QUERY_arg, "track", MAXSTR)==0)
|
mas01cr@105
|
533 queryType=O2_TRACK_QUERY;
|
mas01cr@105
|
534 else if(strncmp(args_info.QUERY_arg, "point", MAXSTR)==0)
|
mas01cr@105
|
535 queryType=O2_POINT_QUERY;
|
mas01cr@105
|
536 else if(strncmp(args_info.QUERY_arg, "sequence", MAXSTR)==0)
|
mas01cr@105
|
537 queryType=O2_SEQUENCE_QUERY;
|
mas01mc@248
|
538 else if(strncmp(args_info.QUERY_arg, "nsequence", MAXSTR)==0)
|
mas01mc@248
|
539 queryType=O2_N_SEQUENCE_QUERY;
|
mas01mc@263
|
540 else if(strncmp(args_info.QUERY_arg, "onetoonensequence", MAXSTR)==0)
|
mas01mc@263
|
541 queryType=O2_ONE_TO_ONE_N_SEQUENCE_QUERY;
|
mas01cr@105
|
542 else
|
mas01cr@105
|
543 error("unsupported query type",args_info.QUERY_arg);
|
mas01cr@105
|
544
|
mas01cr@105
|
545 if(!args_info.exhaustive_flag){
|
mas01cr@105
|
546 queryPoint = args_info.qpoint_arg;
|
mas01cr@105
|
547 usingQueryPoint=1;
|
mas01cr@105
|
548 if(queryPoint<0 || queryPoint >10000)
|
mas01cr@105
|
549 error("queryPoint out of range: 0 <= queryPoint <= 10000");
|
mas01cr@105
|
550 }
|
mas01mc@292
|
551
|
mas01mc@296
|
552 // Whether to pre-load LSH hash tables for query (default on, if flag set then off)
|
mas01mc@297
|
553 lsh_in_core = !args_info.lsh_on_disk_flag;
|
mas01mc@292
|
554
|
mas01mc@292
|
555 // Whether to perform exact evaluation of points returned by LSH
|
mas01mc@292
|
556 lsh_exact = args_info.lsh_exact_flag;
|
mas01mc@292
|
557
|
mas01cr@105
|
558 pointNN = args_info.pointnn_arg;
|
mas01mc@263
|
559 if(pointNN < 1 || pointNN > O2_MAXNN) {
|
mas01mc@263
|
560 error("pointNN out of range: 1 <= pointNN <= 1000000");
|
mas01cr@105
|
561 }
|
mas01cr@105
|
562 trackNN = args_info.resultlength_arg;
|
mas01mc@263
|
563 if(trackNN < 1 || trackNN > O2_MAXNN) {
|
mas01mc@263
|
564 error("resultlength out of range: 1 <= resultlength <= 1000000");
|
mas01cr@105
|
565 }
|
mas01cr@105
|
566 return 0;
|
mas01cr@105
|
567 }
|
mas01mc@334
|
568
|
mas01mc@334
|
569 if(args_info.LISZT_given){
|
mas01mc@334
|
570 command = COM_LISZT;
|
mas01mc@334
|
571 dbName=args_info.database_arg;
|
mas01mc@334
|
572 lisztOffset = args_info.lisztOffset_arg;
|
mas01mc@334
|
573 lisztLength = args_info.lisztLength_arg;
|
mas01mc@334
|
574 if(args_info.lisztOffset_arg<0) // check upper bound later when database is opened
|
mas01mc@334
|
575 error("lisztOffset cannot be negative");
|
mas01mc@334
|
576 if(args_info.lisztLength_arg<0)
|
mas01mc@334
|
577 error("lisztLength cannot be negative");
|
mas01mc@334
|
578 if(lisztLength >1000000)
|
mas01mc@334
|
579 error("lisztLength too large (>1000000)");
|
mas01mc@334
|
580 return 0;
|
mas01mc@334
|
581 }
|
mas01mc@334
|
582
|
mas01cr@105
|
583 return -1; // no command found
|
mas01cr@0
|
584 }
|
mas01cr@0
|
585
|
mas01cr@133
|
586 void audioDB::status(const char* dbName, adb__statusResponse *adbStatusResponse){
|
mas01cr@0
|
587 if(!dbH)
|
mas01cr@196
|
588 initTables(dbName, 0);
|
mas01cr@0
|
589
|
mas01cr@0
|
590 unsigned dudCount=0;
|
mas01cr@0
|
591 unsigned nullCount=0;
|
mas01cr@0
|
592 for(unsigned k=0; k<dbH->numFiles; k++){
|
mas01mc@18
|
593 if(trackTable[k]<sequenceLength){
|
mas01cr@0
|
594 dudCount++;
|
mas01mc@18
|
595 if(!trackTable[k])
|
mas01cr@76
|
596 nullCount++;
|
mas01cr@0
|
597 }
|
mas01cr@0
|
598 }
|
mas01cr@76
|
599
|
mas01cr@133
|
600 if(adbStatusResponse == 0) {
|
mas01cr@76
|
601
|
mas01cr@76
|
602 // Update Header information
|
mas01cr@239
|
603 std::cout << "num files:" << dbH->numFiles << std::endl;
|
mas01cr@239
|
604 std::cout << "data dim:" << dbH->dim <<std::endl;
|
mas01cr@76
|
605 if(dbH->dim>0){
|
mas01cr@239
|
606 std::cout << "total vectors:" << dbH->length/(sizeof(double)*dbH->dim)<<std::endl;
|
mas01mc@324
|
607 if(dbH->flags & O2_FLAG_LARGE_ADB)
|
mas01mc@324
|
608 std::cout << "vectors available:" << O2_MAX_VECTORS - (dbH->length / (sizeof(double)*dbH->dim)) << std::endl;
|
mas01mc@324
|
609 else
|
mas01mc@324
|
610 std::cout << "vectors available:" << (dbH->timesTableOffset-(dbH->dataOffset+dbH->length))/(sizeof(double)*dbH->dim) << std::endl;
|
mas01cr@76
|
611 }
|
mas01mc@324
|
612 if( ! (dbH->flags & O2_FLAG_LARGE_ADB) ){
|
mas01mc@324
|
613 std::cout << "total bytes:" << dbH->length << " (" << (100.0*dbH->length)/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
|
mas01mc@324
|
614 std::cout << "bytes available:" << dbH->timesTableOffset-(dbH->dataOffset+dbH->length) << " (" <<
|
mas01mc@324
|
615 (100.0*(dbH->timesTableOffset-(dbH->dataOffset+dbH->length)))/(dbH->timesTableOffset-dbH->dataOffset) << "%)" << std::endl;
|
mas01mc@324
|
616 }
|
mas01mc@301
|
617 std::cout << "flags:" << " l2norm[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_L2NORM)
|
mas01mc@301
|
618 << "] minmax[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_MINMAX)
|
mas01mc@301
|
619 << "] power[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_POWER)
|
mas01mc@324
|
620 << "] times[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_TIMES)
|
mas01mc@324
|
621 << "] largeADB[" << DISPLAY_FLAG(dbH->flags&O2_FLAG_LARGE_ADB)
|
mas01mc@324
|
622 << "]" << endl;
|
mas01mc@324
|
623
|
mas01cr@239
|
624 std::cout << "null count: " << nullCount << " small sequence count " << dudCount-nullCount << std::endl;
|
mas01cr@76
|
625 } else {
|
mas01cr@133
|
626 adbStatusResponse->result.numFiles = dbH->numFiles;
|
mas01cr@133
|
627 adbStatusResponse->result.dim = dbH->dim;
|
mas01cr@133
|
628 adbStatusResponse->result.length = dbH->length;
|
mas01cr@133
|
629 adbStatusResponse->result.dudCount = dudCount;
|
mas01cr@133
|
630 adbStatusResponse->result.nullCount = nullCount;
|
mas01cr@133
|
631 adbStatusResponse->result.flags = dbH->flags;
|
mas01cr@76
|
632 }
|
mas01cr@0
|
633 }
|
mas01cr@0
|
634
|
mas01cr@196
|
635 void audioDB::l2norm(const char* dbName) {
|
mas01cr@196
|
636 forWrite = true;
|
mas01cr@196
|
637 initTables(dbName, 0);
|
mas01mc@324
|
638 if( !(dbH->flags & O2_FLAG_LARGE_ADB ) && (dbH->length>0) ){
|
mas01cr@196
|
639 /* FIXME: should probably be uint64_t */
|
mas01cr@0
|
640 unsigned numVectors = dbH->length/(sizeof(double)*dbH->dim);
|
mas01cr@196
|
641 CHECKED_MMAP(double *, dataBuf, dbH->dataOffset, dataBufLength);
|
mas01cr@0
|
642 unitNormAndInsertL2(dataBuf, dbH->dim, numVectors, 0); // No append
|
mas01cr@0
|
643 }
|
mas01cr@0
|
644 // Update database flags
|
mas01cr@0
|
645 dbH->flags = dbH->flags|O2_FLAG_L2NORM;
|
mas01cr@0
|
646 memcpy (db, dbH, O2_HEADERSIZE);
|
mas01cr@0
|
647 }
|
mas01cr@193
|
648
|
mas01cr@193
|
649 void audioDB::power_flag(const char *dbName) {
|
mas01cr@196
|
650 forWrite = true;
|
mas01mc@324
|
651 initTables(dbName, 0);
|
mas01mc@324
|
652 if( !(dbH->flags & O2_FLAG_LARGE_ADB ) && (dbH->length>0) ){
|
mas01cr@193
|
653 error("cannot turn on power storage for non-empty database", dbName);
|
mas01cr@193
|
654 }
|
mas01cr@193
|
655 dbH->flags |= O2_FLAG_POWER;
|
mas01cr@193
|
656 memcpy(db, dbH, O2_HEADERSIZE);
|
mas01cr@193
|
657 }
|
mas01cr@193
|
658
|
mas01cr@239
|
659 // Unit norm block of features
|
mas01cr@0
|
660
|
mas01cr@239
|
661 /* FIXME: in fact this does not unit norm a block of features, it just
|
mas01cr@239
|
662 records the L2 norms somewhere. unitNorm() does in fact unit norm
|
mas01cr@239
|
663 a block of features. */
|
mas01cr@0
|
664 void audioDB::unitNormAndInsertL2(double* X, unsigned dim, unsigned n, unsigned append=0){
|
mas01cr@0
|
665 unsigned d;
|
mas01cr@59
|
666 double *p;
|
mas01cr@0
|
667 unsigned nn = n;
|
mas01cr@0
|
668
|
mas01cr@0
|
669 assert(l2normTable);
|
mas01cr@0
|
670
|
mas01mc@324
|
671 if( !(dbH->flags & O2_FLAG_LARGE_ADB) && !append && (dbH->flags & O2_FLAG_L2NORM) )
|
mas01cr@0
|
672 error("Database is already L2 normed", "automatic norm on insert is enabled");
|
mas01cr@0
|
673
|
mas01cr@239
|
674 VERB_LOG(2, "norming %u vectors...", n);
|
mas01cr@0
|
675
|
mas01cr@0
|
676 double* l2buf = new double[n];
|
mas01cr@0
|
677 double* l2ptr = l2buf;
|
mas01cr@0
|
678 assert(l2buf);
|
mas01cr@0
|
679 assert(X);
|
mas01cr@0
|
680
|
mas01cr@0
|
681 while(nn--){
|
mas01cr@0
|
682 p=X;
|
mas01cr@0
|
683 *l2ptr=0.0;
|
mas01cr@0
|
684 d=dim;
|
mas01cr@0
|
685 while(d--){
|
mas01cr@0
|
686 *l2ptr+=*p**p;
|
mas01cr@0
|
687 p++;
|
mas01cr@0
|
688 }
|
mas01mc@17
|
689 l2ptr++;
|
mas01mc@17
|
690 X+=dim;
|
mas01cr@0
|
691 }
|
mas01cr@0
|
692 unsigned offset;
|
mas01cr@84
|
693 if(append) {
|
mas01cr@84
|
694 // FIXME: a hack, a very palpable hack: the vectors have already
|
mas01cr@84
|
695 // been inserted, and dbH->length has already been updated. We
|
mas01cr@84
|
696 // need to subtract off again the number of vectors that we've
|
mas01cr@84
|
697 // inserted this time...
|
mas01cr@84
|
698 offset=(dbH->length/(dbH->dim*sizeof(double)))-n; // number of vectors
|
mas01cr@84
|
699 } else {
|
mas01cr@0
|
700 offset=0;
|
mas01cr@84
|
701 }
|
mas01cr@0
|
702 memcpy(l2normTable+offset, l2buf, n*sizeof(double));
|
mas01cr@0
|
703 if(l2buf)
|
mas01mc@17
|
704 delete[] l2buf;
|
mas01cr@239
|
705 VERB_LOG(2, " done.");
|
mas01cr@193
|
706 }
|
mas01cr@193
|
707
|
mas01mc@308
|
708 // This entry point is visited once per instance
|
mas01mc@308
|
709 // so it is a good place to set any global state variables
|
mas01cr@0
|
710 int main(const unsigned argc, char* const argv[]){
|
mas01mc@308
|
711 SERVER_LSH_INDEX_SINGLETON = 0; // Initialize global variables
|
mas01mc@324
|
712 SERVER_ADB_ROOT = 0; // Server-side database root prefix
|
mas01mc@324
|
713 SERVER_ADB_FEATURE_ROOT = 0; // Server-side features root prefix
|
mas01cr@0
|
714 audioDB(argc, argv);
|
mas01cr@0
|
715 }
|