1 | #include <stdio.h> |
---|
2 | #include <stdlib.h> |
---|
3 | #include <unistd.h> |
---|
4 | #include <string.h> |
---|
5 | #include <sys/stat.h> |
---|
6 | #include <sys/time.h> |
---|
7 | #include <PT_server.h> |
---|
8 | #include <PT_server_prototypes.h> |
---|
9 | #include "ptpan.h" |
---|
10 | #include "pt_prototypes.h" |
---|
11 | #include <arbdbt.h> |
---|
12 | #include <servercntrl.h> |
---|
13 | #include <server.h> |
---|
14 | #include <client.h> |
---|
15 | #include <struct_man.h> |
---|
16 | #define MAX_TRY 3 |
---|
17 | #define TIME_OUT 1000*60*60*24 |
---|
18 | |
---|
19 | /***************************************************************************** |
---|
20 | NEW STUFF |
---|
21 | *******************************************************************************/ |
---|
22 | |
---|
23 | /* /// "AllocPTPanGlobal()" */ |
---|
24 | struct PTPanGlobal * AllocPTPanGlobal(void) |
---|
25 | { |
---|
26 | struct PTPanGlobal *pg; |
---|
27 | ULONG cnt; |
---|
28 | ULONG pval; |
---|
29 | ULONG numbits; |
---|
30 | struct MismatchWeights *mw; |
---|
31 | |
---|
32 | /**** init server main struct ****/ |
---|
33 | printf("Init internal structs...\n"); |
---|
34 | |
---|
35 | pg = (struct PTPanGlobal *) calloc(1, sizeof(struct PTPanGlobal)); |
---|
36 | if(!pg) |
---|
37 | { |
---|
38 | printf("Error allocating PTPanGlobal!\n"); |
---|
39 | return(FALSE); |
---|
40 | } |
---|
41 | /* init some stuff and precalc tables */ |
---|
42 | NewList(&pg->pg_Species); |
---|
43 | NewList(&pg->pg_Partitions); |
---|
44 | pg->pg_AlphaSize = ALPHASIZE; |
---|
45 | |
---|
46 | /* calculate table of powers of alphabet size */ |
---|
47 | pval = 1; |
---|
48 | for(cnt = 0, pval = 1; cnt <= MAXCODEFITLONG; cnt++) |
---|
49 | { |
---|
50 | pg->pg_PowerTable[cnt] = pval; |
---|
51 | pval *= pg->pg_AlphaSize; |
---|
52 | } |
---|
53 | |
---|
54 | /* calculate table of bits used for code of size n */ |
---|
55 | pval = pg->pg_AlphaSize; |
---|
56 | numbits = 0; |
---|
57 | pg->pg_BitsUseTable[0] = 0; |
---|
58 | pg->pg_BitsMaskTable[0] = (1UL << (31-numbits)); |
---|
59 | for(cnt = 1; cnt <= MAXCODEFITLONG; cnt++) |
---|
60 | { |
---|
61 | while(pval > (1UL << numbits)) |
---|
62 | { |
---|
63 | numbits++; |
---|
64 | } |
---|
65 | pg->pg_BitsUseTable[cnt] = numbits; /* bits required for codesize */ |
---|
66 | pg->pg_BitsShiftTable[cnt] = 32 - numbits; /* how many bits to shift left */ |
---|
67 | pg->pg_BitsMaskTable[cnt] = (1UL << (31-numbits)); |
---|
68 | pval *= pg->pg_AlphaSize; |
---|
69 | } |
---|
70 | |
---|
71 | /* bits count table */ |
---|
72 | for(cnt = 0; cnt < 256; cnt++) |
---|
73 | { |
---|
74 | numbits = 0; |
---|
75 | pval = cnt; |
---|
76 | while(pval) |
---|
77 | { |
---|
78 | numbits += (pval & 1); |
---|
79 | pval >>= 1; |
---|
80 | } |
---|
81 | pg->pg_BitsCountTable[cnt] = numbits; |
---|
82 | } |
---|
83 | |
---|
84 | /* sequence compression tables */ |
---|
85 | /* due to calloc, this table is already set to SEQCODE_N for all other codes */ |
---|
86 | pg->pg_CompressTable[(UBYTE) 'a'] = SEQCODE_A; |
---|
87 | pg->pg_CompressTable[(UBYTE) 'A'] = SEQCODE_A; |
---|
88 | pg->pg_CompressTable[(UBYTE) 'c'] = SEQCODE_C; |
---|
89 | pg->pg_CompressTable[(UBYTE) 'C'] = SEQCODE_C; |
---|
90 | pg->pg_CompressTable[(UBYTE) 'g'] = SEQCODE_G; |
---|
91 | pg->pg_CompressTable[(UBYTE) 'G'] = SEQCODE_G; |
---|
92 | pg->pg_CompressTable[(UBYTE) 't'] = SEQCODE_T; |
---|
93 | pg->pg_CompressTable[(UBYTE) 'T'] = SEQCODE_T; |
---|
94 | pg->pg_CompressTable[(UBYTE) 'u'] = SEQCODE_T; |
---|
95 | pg->pg_CompressTable[(UBYTE) 'U'] = SEQCODE_T; |
---|
96 | pg->pg_CompressTable[(UBYTE) '-'] = SEQCODE_IGNORE; /* these chars don't go */ |
---|
97 | pg->pg_CompressTable[(UBYTE) '.'] = SEQCODE_IGNORE; /* into the tree */ |
---|
98 | pg->pg_CompressTable[0] = SEQCODE_IGNORE; /* terminal char, to optimize certain routines */ |
---|
99 | |
---|
100 | /* inverse table for decompressing */ |
---|
101 | pg->pg_DecompressTable[SEQCODE_N] = 'N'; |
---|
102 | pg->pg_DecompressTable[SEQCODE_A] = 'A'; |
---|
103 | pg->pg_DecompressTable[SEQCODE_C] = 'C'; |
---|
104 | pg->pg_DecompressTable[SEQCODE_G] = 'G'; |
---|
105 | pg->pg_DecompressTable[SEQCODE_T] = 'U'; |
---|
106 | |
---|
107 | /* table for creating the complement sequence */ |
---|
108 | pg->pg_ComplementTable[SEQCODE_N] = SEQCODE_N; |
---|
109 | pg->pg_ComplementTable[SEQCODE_A] = SEQCODE_T; |
---|
110 | pg->pg_ComplementTable[SEQCODE_C] = SEQCODE_G; |
---|
111 | pg->pg_ComplementTable[SEQCODE_G] = SEQCODE_C; |
---|
112 | pg->pg_ComplementTable[SEQCODE_T] = SEQCODE_A; |
---|
113 | |
---|
114 | /* counting table to avoid branches */ |
---|
115 | for(cnt = 0; cnt < 256; cnt++) |
---|
116 | { |
---|
117 | pg->pg_SeqCodeValidTable[cnt] = (pg->pg_CompressTable[cnt] == SEQCODE_IGNORE) ? 0 : 1; |
---|
118 | } |
---|
119 | |
---|
120 | pg->pg_FreeMem = GB_get_physical_memory(); |
---|
121 | #ifdef DEBUG |
---|
122 | printf("physical_memory=%lu k (%lu Mb)\n", pg->pg_FreeMem, pg->pg_FreeMem >> 10); |
---|
123 | #endif // DEBUG |
---|
124 | pg->pg_FreeMem <<= 10; |
---|
125 | |
---|
126 | /* initialize species cache handler */ |
---|
127 | pg->pg_SpeciesCache = AllocCacheHandler(); |
---|
128 | if(!pg->pg_SpeciesCache) |
---|
129 | { |
---|
130 | printf("Couldn't allocate species cache handler!\n"); |
---|
131 | free(pg); |
---|
132 | return(FALSE); |
---|
133 | } |
---|
134 | pg->pg_SpeciesCache->ch_UserData = pg; |
---|
135 | /* reserve about 10% of the memory for the species cache */ |
---|
136 | pg->pg_SpeciesCache->ch_MaxCapacity = (pg->pg_FreeMem / 10) * 1; |
---|
137 | pg->pg_SpeciesCache->ch_LoadFunc = (BOOL (*)(struct CacheHandler *, APTR)) CacheSpeciesLoad; |
---|
138 | pg->pg_SpeciesCache->ch_UnloadFunc = (BOOL (*)(struct CacheHandler *, APTR)) CacheSpeciesUnload; |
---|
139 | pg->pg_SpeciesCache->ch_SizeFunc = (ULONG (*)(struct CacheHandler *, APTR)) CacheSpeciesSize; |
---|
140 | |
---|
141 | /* initialize partitions cache handler */ |
---|
142 | pg->pg_PartitionCache = AllocCacheHandler(); |
---|
143 | if(!pg->pg_PartitionCache) |
---|
144 | { |
---|
145 | printf("Couldn't allocate partitions cache handler!\n"); |
---|
146 | FreeCacheHandler(pg->pg_SpeciesCache); |
---|
147 | free(pg); |
---|
148 | return(FALSE); |
---|
149 | } |
---|
150 | pg->pg_PartitionCache->ch_UserData = pg; |
---|
151 | /* reserve about 90% of the memory for the partition cache */ |
---|
152 | pg->pg_PartitionCache->ch_MaxCapacity = (pg->pg_FreeMem / 10) * 9; |
---|
153 | pg->pg_PartitionCache->ch_LoadFunc = (BOOL (*)(struct CacheHandler *, APTR)) CachePartitionLoad; |
---|
154 | pg->pg_PartitionCache->ch_UnloadFunc = (BOOL (*)(struct CacheHandler *, APTR)) CachePartitionUnload; |
---|
155 | pg->pg_PartitionCache->ch_SizeFunc = (ULONG (*)(struct CacheHandler *, APTR)) CachePartitionSize; |
---|
156 | |
---|
157 | /* default mismatch weights */ |
---|
158 | mw = &pg->pg_MismatchWeights; |
---|
159 | /* format: replace code1 (query) by code2 (database) adds x to the error value */ |
---|
160 | /* N A C G T (-> query) |
---|
161 | N 0.0 0.1 0.1 0.1 0.1 |
---|
162 | A * 0.0 1.0 1.0 1.0 |
---|
163 | C * 1.0 0.0 1.0 1.0 |
---|
164 | G * 1.0 1.0 0.0 1.0 |
---|
165 | T * 1.0 1.0 1.0 0.0 |
---|
166 | ins 2.0 2.0 2.0 2.0 2.0 |
---|
167 | del * 2.0 2.0 2.0 2.0 |
---|
168 | */ |
---|
169 | /* fill diagonal first (no mismatch) */ |
---|
170 | for(cnt = 0; cnt < ALPHASIZE; cnt++) |
---|
171 | { |
---|
172 | mw->mw_Replace[cnt * ALPHASIZE + cnt] = 0.0; |
---|
173 | } |
---|
174 | |
---|
175 | /* N is a joker, but setting it to slightly higher values might be sensible */ |
---|
176 | mw->mw_Replace[SEQCODE_A * ALPHASIZE + SEQCODE_N] = 0.1; |
---|
177 | mw->mw_Replace[SEQCODE_C * ALPHASIZE + SEQCODE_N] = 0.1; |
---|
178 | mw->mw_Replace[SEQCODE_G * ALPHASIZE + SEQCODE_N] = 0.1; |
---|
179 | mw->mw_Replace[SEQCODE_T * ALPHASIZE + SEQCODE_N] = 0.1; |
---|
180 | |
---|
181 | /* replacing N by A, C, G, T will not occur (search string may not contain N) */ |
---|
182 | mw->mw_Replace[SEQCODE_N * ALPHASIZE + SEQCODE_A] = 99999.0; |
---|
183 | mw->mw_Replace[SEQCODE_N * ALPHASIZE + SEQCODE_C] = 99999.0; |
---|
184 | mw->mw_Replace[SEQCODE_N * ALPHASIZE + SEQCODE_G] = 99999.0; |
---|
185 | mw->mw_Replace[SEQCODE_N * ALPHASIZE + SEQCODE_T] = 99999.0; |
---|
186 | |
---|
187 | /* other parts of the matrix (should be symmetrical, but doesn't need to) */ |
---|
188 | mw->mw_Replace[SEQCODE_A * ALPHASIZE + SEQCODE_C] = 1.1; |
---|
189 | mw->mw_Replace[SEQCODE_C * ALPHASIZE + SEQCODE_A] = 1.0; |
---|
190 | |
---|
191 | mw->mw_Replace[SEQCODE_A * ALPHASIZE + SEQCODE_G] = 0.2; |
---|
192 | mw->mw_Replace[SEQCODE_G * ALPHASIZE + SEQCODE_A] = 1.5; |
---|
193 | |
---|
194 | mw->mw_Replace[SEQCODE_A * ALPHASIZE + SEQCODE_T] = 1.1; |
---|
195 | mw->mw_Replace[SEQCODE_T * ALPHASIZE + SEQCODE_A] = 1.1; |
---|
196 | |
---|
197 | mw->mw_Replace[SEQCODE_C * ALPHASIZE + SEQCODE_G] = 1.1; |
---|
198 | mw->mw_Replace[SEQCODE_G * ALPHASIZE + SEQCODE_C] = 1.5; |
---|
199 | |
---|
200 | mw->mw_Replace[SEQCODE_C * ALPHASIZE + SEQCODE_T] = 0.6; |
---|
201 | mw->mw_Replace[SEQCODE_T * ALPHASIZE + SEQCODE_C] = 1.1; |
---|
202 | |
---|
203 | mw->mw_Replace[SEQCODE_G * ALPHASIZE + SEQCODE_T] = 1.5; |
---|
204 | mw->mw_Replace[SEQCODE_T * ALPHASIZE + SEQCODE_G] = 0.6; |
---|
205 | |
---|
206 | /* insert operations (to query string) */ |
---|
207 | mw->mw_Insert[SEQCODE_N] = 2.0; |
---|
208 | mw->mw_Insert[SEQCODE_A] = 2.0; |
---|
209 | mw->mw_Insert[SEQCODE_C] = 2.0; |
---|
210 | mw->mw_Insert[SEQCODE_G] = 2.0; |
---|
211 | mw->mw_Insert[SEQCODE_T] = 2.0; |
---|
212 | |
---|
213 | /* delete operations (from query string) */ |
---|
214 | mw->mw_Delete[SEQCODE_N] = 99999.0; /* should never happen */ |
---|
215 | mw->mw_Delete[SEQCODE_A] = 2.0; |
---|
216 | mw->mw_Delete[SEQCODE_C] = 2.0; |
---|
217 | mw->mw_Delete[SEQCODE_G] = 2.0; |
---|
218 | mw->mw_Delete[SEQCODE_T] = 2.0; |
---|
219 | |
---|
220 | /* init matrix for non-weighted stuff */ |
---|
221 | mw = &pg->pg_NoWeights; |
---|
222 | /* fill standard 1.0 values */ |
---|
223 | for(cnt = 0; cnt < (ALPHASIZE * ALPHASIZE); cnt++) |
---|
224 | { |
---|
225 | mw->mw_Replace[cnt] = 1.0; |
---|
226 | } |
---|
227 | /* fill diagonal first (no mismatch) and insert / delete */ |
---|
228 | for(cnt = 0; cnt < ALPHASIZE; cnt++) |
---|
229 | { |
---|
230 | mw->mw_Replace[cnt * ALPHASIZE] = 0.1; // N (joker) replacement |
---|
231 | mw->mw_Replace[cnt * ALPHASIZE + cnt] = 0.0; // diagonal |
---|
232 | mw->mw_Insert[cnt] = 2.0; |
---|
233 | mw->mw_Delete[cnt] = 2.0; |
---|
234 | } |
---|
235 | |
---|
236 | /* calculate maximum partition size (estimate 24 bytes per node) */ |
---|
237 | { |
---|
238 | ULONG partmem = pg->pg_FreeMem; |
---|
239 | /* tree building implementation is limited to max. 1 GB per partition */ |
---|
240 | if(partmem > (1UL<<30)) |
---|
241 | { |
---|
242 | partmem = 1UL<<30; |
---|
243 | } |
---|
244 | |
---|
245 | pg->pg_MaxPartitionSize = partmem / (((sizeof(struct SfxNode2Edges) * SMALLNODESPERCENT) + |
---|
246 | (sizeof(struct SfxNodeNEdges) * BIGNODESPERCENT)) / 100); |
---|
247 | } |
---|
248 | /* enable low memory mode */ |
---|
249 | pg->pg_LowMemoryMode = TRUE; |
---|
250 | |
---|
251 | gettimeofday(&pg->pg_Bench.ts_Init, NULL); |
---|
252 | pg->pg_Bench.ts_Last = pg->pg_Bench.ts_Init; |
---|
253 | |
---|
254 | /* init command line flags */ |
---|
255 | pg->pg_verbose = 0; |
---|
256 | |
---|
257 | return(pg); |
---|
258 | } |
---|
259 | /* \\\ */ |
---|
260 | |
---|
261 | /* /// "FreePTPanGlobal()" */ |
---|
262 | void FreePTPanGlobal(struct PTPanGlobal *pg) |
---|
263 | { |
---|
264 | FlushCache(pg->pg_SpeciesCache); |
---|
265 | FreeCacheHandler(pg->pg_SpeciesCache); |
---|
266 | FlushCache(pg->pg_PartitionCache); |
---|
267 | FreeCacheHandler(pg->pg_PartitionCache); |
---|
268 | free(pg); |
---|
269 | } |
---|
270 | /* \\\ */ |
---|
271 | |
---|
272 | /***************************************************************************** |
---|
273 | END OF NEW STUFF |
---|
274 | *******************************************************************************/ |
---|
275 | |
---|
276 | // *** FIXME *** see if we can get rid of this global structures |
---|
277 | |
---|
278 | struct PTPanGlobal *PTPanGlobalPtr = NULL; |
---|
279 | |
---|
280 | /***************************************************************************** |
---|
281 | Communication |
---|
282 | *******************************************************************************/ |
---|
283 | |
---|
284 | PT_main *aisc_main; /* muss so heissen */ |
---|
285 | |
---|
286 | extern "C" int server_shutdown(PT_main *, aisc_string passwd) |
---|
287 | { |
---|
288 | struct PTPanGlobal *pg = PTPanGlobalPtr; |
---|
289 | |
---|
290 | printf("EXTERN: server_shutdown\n"); |
---|
291 | /** passwdcheck **/ |
---|
292 | if(strcmp(passwd, "47@#34543df43%&3667gh")) |
---|
293 | { |
---|
294 | return 1; |
---|
295 | } |
---|
296 | printf("\nI got the shutdown message.\n"); |
---|
297 | /** shoot clients **/ |
---|
298 | aisc_broadcast(pg->pg_ComSocket, 0, |
---|
299 | "SERVER UPDATE BY ADMINISTRATOR!\n" |
---|
300 | "You'll get the latest version. Your on-screen\n" |
---|
301 | "information will be lost, sorry!"); |
---|
302 | /** shutdown **/ |
---|
303 | aisc_server_shutdown_and_exit(pg->pg_ComSocket, 0); |
---|
304 | return(0); |
---|
305 | } |
---|
306 | |
---|
307 | extern "C" int broadcast(PT_main *main, int) |
---|
308 | { |
---|
309 | struct PTPanGlobal *pg = PTPanGlobalPtr; |
---|
310 | |
---|
311 | printf("EXTERN: broadcast\n"); |
---|
312 | aisc_broadcast(pg->pg_ComSocket, main->m_type, main->m_text); |
---|
313 | return(0); |
---|
314 | } |
---|
315 | |
---|
316 | extern int aisc_core_on_error; |
---|
317 | |
---|
318 | int main(int argc, char *argv[]) |
---|
319 | { |
---|
320 | struct PTPanGlobal *pg; |
---|
321 | STRPTR commandflag; |
---|
322 | |
---|
323 | printf("\nTUM PeTer PAN SERVER (Chris Hodges) V0.12 18-Aug-04 (C) 2003-2004\n" |
---|
324 | "Complete rewrite of the original code by Oliver Strunk from 1993\n\n"); |
---|
325 | |
---|
326 | /* allocate the PTPanGlobal structure */ |
---|
327 | if(!(pg = AllocPTPanGlobal())) |
---|
328 | { |
---|
329 | exit(1); |
---|
330 | } |
---|
331 | |
---|
332 | /* argh! global variable! would be nice, if we could get rid of this -- |
---|
333 | it is only used by the AISC functions */ |
---|
334 | PTPanGlobalPtr = pg; |
---|
335 | |
---|
336 | /* aisc init */ |
---|
337 | GB_install_pid(0); /* not arb_clean able */ |
---|
338 | aisc_core_on_error = 0; |
---|
339 | pg->pg_AISC = create_PT_main(); |
---|
340 | |
---|
341 | GB_init_gb(); // nedded for PT_new_design |
---|
342 | |
---|
343 | /* set global variable -- sigh */ |
---|
344 | aisc_main = pg->pg_AISC; |
---|
345 | |
---|
346 | /* first get the parameters */ |
---|
347 | pg->pg_ArbParams = arb_trace_argv(&argc, argv); |
---|
348 | |
---|
349 | /* try to open com with any other pb server */ |
---|
350 | /* check command line syntax */ |
---|
351 | if((argc > 2) || |
---|
352 | ((argc < 2) && !pg->pg_ArbParams->db_server) || |
---|
353 | (argc >= 2 && strcmp(argv[1], "--help") == 0)) |
---|
354 | { |
---|
355 | printf("Syntax: %s [-look/-build/-kill/-QUERY] -Dfile.arb -TSocketid\n", argv[0]); |
---|
356 | exit(-1); |
---|
357 | } |
---|
358 | /* add default command flag */ |
---|
359 | if(argc == 2) |
---|
360 | { |
---|
361 | commandflag = argv[1]; |
---|
362 | } else { |
---|
363 | commandflag = (STRPTR) "-boot"; |
---|
364 | } |
---|
365 | |
---|
366 | /* get server host name */ |
---|
367 | if(!(pg->pg_ServerName = pg->pg_ArbParams->tcp)) |
---|
368 | { |
---|
369 | if(!(pg->pg_ServerName = (STRPTR) GBS_read_arb_tcp("ARB_PT_SERVER0"))) |
---|
370 | { |
---|
371 | GB_print_error(); /* no host name found */ |
---|
372 | exit(-1); |
---|
373 | } |
---|
374 | } |
---|
375 | |
---|
376 | /* generate tree filename */ |
---|
377 | pg->pg_DBName = pg->pg_ArbParams->db_server; |
---|
378 | pg->pg_IndexName = GBS_global_string_copy("%s.pan", pg->pg_DBName); |
---|
379 | |
---|
380 | /* check for other active servers */ |
---|
381 | { |
---|
382 | aisc_com *ptlink; |
---|
383 | T_PT_MAIN ptmain; |
---|
384 | ptlink = (aisc_com *) aisc_open(pg->pg_DBName, &ptmain, AISC_MAGIC_NUMBER); |
---|
385 | if(ptlink) |
---|
386 | { |
---|
387 | if(!strcasecmp(commandflag, "-look")) |
---|
388 | { |
---|
389 | exit(0); /* already another serther */ |
---|
390 | } |
---|
391 | printf("There is another active server. I'll try to terminate it violently...\n"); |
---|
392 | aisc_nput(ptlink, PT_MAIN, ptmain, MAIN_SHUTDOWN, "47@#34543df43%&3667gh", NULL); |
---|
393 | aisc_close(ptlink); |
---|
394 | } |
---|
395 | } |
---|
396 | if(!strcmp(commandflag, "-kill")) |
---|
397 | { |
---|
398 | exit(0); |
---|
399 | } |
---|
400 | |
---|
401 | if(!strncasecmp(commandflag, "-build", 6)) /* build command */ |
---|
402 | { |
---|
403 | ULONG val = atoi(&commandflag[6]); |
---|
404 | if(val) /* extra option */ |
---|
405 | { |
---|
406 | if(val > 100000) /* read out threshold */ |
---|
407 | { |
---|
408 | pg->pg_MaxPartitionSize = atoi(&commandflag[6]); |
---|
409 | printf("Forcing MaxPartitionSize = %ld.\n", pg->pg_MaxPartitionSize); |
---|
410 | } else { |
---|
411 | pg->pg_PruneLength = atoi(&commandflag[6]); |
---|
412 | printf("Forcing PruneLength = %d.\n", pg->pg_PruneLength); |
---|
413 | } |
---|
414 | } |
---|
415 | LoadSpecies(pg); |
---|
416 | if(!strncmp(commandflag, "-bUiLd", 6)) |
---|
417 | { |
---|
418 | pg->pg_UseStdSfxTree = TRUE; |
---|
419 | if(BuildStdSuffixTree(pg)) |
---|
420 | { |
---|
421 | printf("Suffix Tree index for database '%s' has been created.\n", pg->pg_DBName); |
---|
422 | BenchOutput(pg); |
---|
423 | exit(0); |
---|
424 | } else { |
---|
425 | printf("Unable to create Suffix Tree index for database '%s'!\n", pg->pg_DBName); |
---|
426 | exit(1); |
---|
427 | } |
---|
428 | } else { |
---|
429 | if(BuildPTPanIndex(pg)) |
---|
430 | { |
---|
431 | printf("PT_PAN index for database '%s' has been created.\n", pg->pg_DBName); |
---|
432 | BenchOutput(pg); |
---|
433 | exit(0); |
---|
434 | } else { |
---|
435 | printf("Unable to create PT_PAN index for database '%s'!\n", pg->pg_DBName); |
---|
436 | exit(1); |
---|
437 | } |
---|
438 | } |
---|
439 | } |
---|
440 | |
---|
441 | if(!strcasecmp(commandflag, "-QUERY")) |
---|
442 | { |
---|
443 | //enter_stage_3_load_tree(aisc_main, tname); /* now stage 3 */ |
---|
444 | exit(0); |
---|
445 | } |
---|
446 | |
---|
447 | /* Check if index is up2date */ |
---|
448 | { |
---|
449 | struct stat dbstat, idxstat; |
---|
450 | BOOL forcebuild = FALSE; |
---|
451 | if(stat(pg->pg_DBName, &dbstat)) |
---|
452 | { |
---|
453 | printf("PT_PAN: error while stat source %s\n", pg->pg_DBName); |
---|
454 | aisc_server_shutdown_and_exit(pg->pg_ComSocket, -1); |
---|
455 | } |
---|
456 | |
---|
457 | if(stat(pg->pg_IndexName, &idxstat)) |
---|
458 | { |
---|
459 | forcebuild = TRUE; /* there is no index at all! */ |
---|
460 | } else { |
---|
461 | if((dbstat.st_mtime > idxstat.st_mtime) || (idxstat.st_size == 0)) |
---|
462 | { |
---|
463 | /* so the index file was older or of zero size */ |
---|
464 | printf("PT_PAN: Database %s has been modified\n" |
---|
465 | "more recently than index %s.\n" |
---|
466 | "Forcing rebuilding of index...\n", |
---|
467 | pg->pg_DBName, pg->pg_IndexName); |
---|
468 | forcebuild = TRUE; |
---|
469 | } |
---|
470 | if(!LoadIndexHeader(pg)) |
---|
471 | { |
---|
472 | forcebuild = TRUE; /* an error occured while loading the index header */ |
---|
473 | } |
---|
474 | } |
---|
475 | if(forcebuild) |
---|
476 | { |
---|
477 | LoadSpecies(pg); |
---|
478 | if(BuildPTPanIndex(pg)) |
---|
479 | { |
---|
480 | printf("PT_PAN index for database '%s' has been created.\n", pg->pg_DBName); |
---|
481 | } else { |
---|
482 | printf("Unable to create PT_PAN index for database '%s'!\n", pg->pg_DBName); |
---|
483 | exit(1); |
---|
484 | } |
---|
485 | if(!LoadIndexHeader(pg)) |
---|
486 | { |
---|
487 | printf("Fatal error, couldn't load index even after creation attempt!\n"); |
---|
488 | exit(1); |
---|
489 | } |
---|
490 | } |
---|
491 | } |
---|
492 | |
---|
493 | /*if(!LoadAllPartitions(pg)) |
---|
494 | { |
---|
495 | printf("ERROR: Failed to load partitions into memory!\n"); |
---|
496 | exit(1); |
---|
497 | }*/ |
---|
498 | |
---|
499 | /* so much for the the init, now let's do some real work */ |
---|
500 | |
---|
501 | if(!strcasecmp(commandflag, "-v")) pg->pg_verbose = 1; |
---|
502 | if(!strcasecmp(commandflag, "-vv")) pg->pg_verbose = 2; |
---|
503 | if(!strcasecmp(commandflag, "-vvv")) pg->pg_verbose = 3; |
---|
504 | |
---|
505 | #if 0 |
---|
506 | { |
---|
507 | PT_exProb pep; |
---|
508 | pep.result = NULL; |
---|
509 | pep.restart = 1; |
---|
510 | pep.plength = 21; |
---|
511 | pep.numget = 100; |
---|
512 | PT_find_exProb(&pep); |
---|
513 | printf("%s\n", pep.result); |
---|
514 | } |
---|
515 | #endif |
---|
516 | |
---|
517 | /* open the socket connection */ |
---|
518 | printf("Opening connection...\n"); |
---|
519 | //sleep(1); |
---|
520 | { |
---|
521 | UWORD i; |
---|
522 | for(i = 0; i < MAX_TRY; i++) |
---|
523 | { |
---|
524 | if((pg->pg_ComSocket = open_aisc_server(pg->pg_ServerName, TIME_OUT, 0))) |
---|
525 | { |
---|
526 | break; |
---|
527 | } else { |
---|
528 | sleep(10); |
---|
529 | } |
---|
530 | } |
---|
531 | if(!pg->pg_ComSocket) |
---|
532 | { |
---|
533 | printf("PT_PAN: Gave up on opening the communication socket!\n"); |
---|
534 | exit(0); |
---|
535 | } |
---|
536 | } |
---|
537 | /****** all ok: main loop ********/ |
---|
538 | |
---|
539 | printf("ok, server is running.\n"); // do NOT change or remove! others depend on it |
---|
540 | fflush(stdout); |
---|
541 | |
---|
542 | aisc_accept_calls(pg->pg_ComSocket); |
---|
543 | aisc_server_shutdown_and_exit(pg->pg_ComSocket, 0); |
---|
544 | |
---|
545 | return(0); |
---|
546 | } |
---|
547 | |
---|
548 | |
---|