source: trunk/gsdl/src/colservr/mgq.c@ 334

Last change on this file since 334 was 334, checked in by rjmcnab, 25 years ago

Changes for better reporting of number documents which match a query. Changes
should still work as before with older versions of mg.

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 19.5 KB
Line 
1/**********************************************************************
2 *
3 * mgq.c -- cut-down version of mgquery
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * PUT COPYRIGHT NOTICE HERE
7 *
8 * $Id: mgq.c 334 1999-07-01 09:29:21Z rjmcnab $
9 *
10 *********************************************************************/
11
12/*
13 $Log$
14 Revision 1.7 1999/07/01 09:29:18 rjmcnab
15 Changes for better reporting of number documents which match a query. Changes
16 should still work as before with older versions of mg.
17
18 Revision 1.6 1999/07/01 03:52:05 rjmcnab
19 Added a function to get the equivalent terms of a query term. I also
20 fixed a small bug that was causing massive slowdown :-^
21
22 Revision 1.5 1999/06/30 04:04:11 rjmcnab
23 made stemming functions available from mgsearch and made the stems
24 for the query terms available in queryinfo
25
26 Revision 1.4 1999/06/28 08:56:29 rjmcnab
27 A bit of hacking to remove the restriction that the index to get
28 a document must be a level 2 index. Now both level 2 and level 3
29 indexes can be used to get the text of a document.
30
31 Revision 1.3 1999/01/19 01:38:16 rjmcnab
32
33 Made the source more portable.
34
35 Revision 1.2 1999/01/12 01:51:02 rjmcnab
36
37 Standard header.
38
39 Revision 1.1 1999/01/08 09:02:22 rjmcnab
40
41 Moved from src/library.
42
43 */
44
45
46#include "mgq.h"
47
48
49#include <stdio.h>
50#include <string.h>
51/* #include <io.h> */
52#include <fcntl.h>
53
54#ifdef __cplusplus
55extern "C" {
56#endif
57
58#include "sysfuncs.h"
59
60#include "messages.h"
61#include "memlib.h"
62
63#include "invf.h"
64#include "text.h"
65#include "lists.h"
66#include "backend.h"
67#include "environment.h"
68#include "globals.h"
69#include "mg_errors.h"
70#include "commands.h"
71#include "text_get.h"
72#include "term_lists.h"
73#include "local_strings.h"
74
75#include "words.h"
76#include "stemmer.h"
77#include "stem_search.h"
78
79#ifdef __cplusplus
80}
81#endif
82
83
84#include "mgq.h"
85
86/* get a reasonable database cache size */
87#ifndef MAXNUMDATABASEINFO
88# ifdef GSDLSERVER
89# define MAXNUMDATABASEINFO 10
90# else
91# define MAXNUMDATABASEINFO 2
92# endif
93#endif
94
95#define MAXCOLLECTIONLEN 16
96#define MAXMGDIRLEN 256
97#define MAXGENSUFFIXLEN 256
98#define MAXTEXTSUFFIXLEN 256
99
100typedef struct DatabaseInfo {
101 int accessnum; /* -1 = invalid record */
102 char collection[MAXCOLLECTIONLEN];
103 char mgdir[MAXMGDIRLEN];
104 char gensuffix[MAXGENSUFFIXLEN];
105 char textsuffix[MAXTEXTSUFFIXLEN];
106 query_data *qd;
107} DatabaseInfo;
108
109
110/* globals needed by some vague part of mg... */
111FILE *OutFile = NULL, *InFile = NULL;
112int OutPipe = 0, InPipe = 0;
113int Quitting = 0;
114
115/* globals needed to handle loading of databases */
116static int cur_cachenum = -1;
117
118/* globals needed by the database cache */
119static DatabaseInfo dbcache[MAXNUMDATABASEINFO];
120static int cache_nextaccessnum = 0;
121static int cache_numloaded = 0;
122
123
124
125#if defined(PARADOCNUM) || defined(NZDL)
126static int GetDocNumFromParaNum(query_data *qd, int paranum) {
127 int Documents = qd->td->cth.num_of_docs;
128 int *Paragraph = qd->paragraph;
129 int low = 1, high = Documents;
130 int mid = (low+high)/2;
131
132 while ((mid = (low+high)/2) >=1 && mid <= Documents)
133 {
134 if (paranum > Paragraph[mid])
135 low = mid+1;
136 else if (paranum <= Paragraph[mid-1])
137 high = mid-1;
138 else
139 return mid;
140 }
141 FatalError(1, "Bad paragraph number.\n");
142 return 0;
143}
144
145static int GetParaNumFromDocNum(query_data *qd, int docnum) {
146 int Documents = qd->td->cth.num_of_docs;
147 int *Paragraph = qd->paragraph;
148
149 if (docnum > 0 && docnum <= Documents)
150 return Paragraph[docnum-1]+1;
151 return 0;
152}
153#endif
154
155
156/*****************************************************************************/
157
158static void MGQError(char *emsg)
159{
160 fprintf(stderr,"Fatal error: %s\n", emsg);
161 exit(1);
162}
163
164static int ProcessDocs (query_data * qd, int skip, int howmany,
165 enum result_kinds kind,
166 int (*sender)(char *,int,int,float,void *), void *ptr) {
167 int max_buf = 0, output_failure = 0;
168 int DocCount = 0;
169 int need_text = (kind == result_docs);
170
171 /* skip the requested number of documents */
172 while (skip > 0) {
173 if (!NextDoc(qd)) return 0;
174 skip--;
175 }
176
177 /* find out the maximum size for the text buffer */
178 if (need_text) max_buf = atoi (GetDefEnv ("buffer", "1048576"));
179
180 /* process each document */
181 do {
182 u_char *UDoc = NULL;
183 unsigned long ULen=0;
184
185#if defined(PARADOCNUM) || defined(NZDL)
186 /* adjust the document number for paragraph level result_docs */
187 /* this is a bit of a hack ... */
188 if (kind==result_docs && qd->id->ifh.InvfLevel == 3 &&
189 qd->DL != NULL && (int)qd->doc_pos < (int)qd->DL->num)
190 qd->DL->DE[qd->doc_pos].DocNum = GetParaNumFromDocNum(qd, qd->DL->DE[qd->doc_pos].DocNum);
191#endif
192
193 if (need_text) {
194 /* load the compressed text */
195 if (LoadCompressedText (qd, max_buf))
196 MGQError("Unable to load compressed text(memory?).");
197
198 /* uncompress the loaded text */
199 UDoc = GetDocText (qd, &ULen);
200 if (UDoc == NULL) MGQError("UDoc is unexpectedly NULL");
201 }
202
203 if (UDoc != NULL || kind == result_docnums) {
204 int docnum = GetDocNum(qd);
205#if defined(PARADOCNUM) || defined(NZDL)
206 if (qd->id->ifh.InvfLevel == 3) docnum = GetDocNumFromParaNum(qd, docnum);
207#endif
208 switch (kind) {
209 case result_docnums:
210 if (sender != NULL)
211 output_failure = (*sender)("",0,docnum,GetDocWeight(qd),ptr);
212 break;
213 case result_docs:
214 if (sender != NULL)
215 output_failure = (*sender)((char *)UDoc,ULen,docnum,GetDocWeight(qd),ptr);
216 break;
217 default:
218 break;
219 }
220 }
221 DocCount++;
222
223 } while (NextDoc (qd) && output_failure == 0 && --howmany > 0);
224
225 /* if (need_text) FreeTextBuffer (qd);*/
226
227 return (DocCount);
228}
229
230
231static void send_query_term_freqs(QueryTermList *qtl,
232 int (*sender)(char *,int,int,float,void *), void *ptr)
233{
234 int i = 0;
235 for (i = 0; i < qtl->num; i++)
236 if (sender != NULL) {
237 /* word = word2str(qtl->QTE[i].Term);
238 (* sender)(word, strlen(word), qtl->QTE[i].Count, (float)0.0, ptr); */
239 (* sender)((char *)(qtl->QTE[i].Term+1), qtl->QTE[i].Term[0],
240 qtl->QTE[i].Count, (float)0.0, ptr);
241 }
242}
243
244
245static void send_terms (TermList * qtl,
246 int (*sender)(char *,int,int,float,void *), void *ptr)
247{
248 int i = 0;
249 if (sender == NULL) return;
250 for (i = 0; i < qtl->num; i++)
251 {
252 /* word = word2str(qtl->TE[i].Word);
253 (* sender)(word, strlen(word), qtl->TE[i].Count, (float)0.0, ptr);*/
254 (* sender)((char *)(qtl->TE[i].Word+1), qtl->TE[i].Word[0],
255 qtl->TE[i].Count, (float)0.0, ptr);
256 }
257}
258
259
260/* MoreDocs () */
261/* Displays all documents in list DocList. */
262/* Documents are fetched, then decompressed and displayed according to the */
263/* format implied in FormString(). */
264
265static void
266MoreDocs (query_data * qd, enum result_kinds kind,
267 int skip, int howmany,
268 int (*sender)(char *,int,int,float,void *), void *ptr)
269{
270 qd->num_of_ans = qd->DL->num;
271 switch (kind) {
272 case result_docs:
273 case result_docnums:
274 if (qd->num_of_ans > 0)
275 ProcessDocs (qd, skip, howmany, kind, sender, ptr);
276 break;
277 case result_termfreqs:
278 send_query_term_freqs(qd->QTL, sender, ptr);
279 break;
280 case result_terms:
281 send_terms(qd->TL, sender, ptr);
282 break;
283 }
284}
285
286
287
288
289
290
291/******************************************
292 * functions to handle the database cache *
293 ******************************************/
294
295/* init_dbcache should be called at the start of each */
296/* function which deals with the database cache */
297static void init_dbcache (void) {
298 static int dbcacheinited = 0;
299 int i = 0;
300
301 if (dbcacheinited) return;
302
303 cache_numloaded = 0;
304
305 for (i=0; i<MAXNUMDATABASEINFO; i++) {
306 dbcache[i].accessnum = -1;
307 dbcache[i].collection[0] = '\0';
308 dbcache[i].mgdir[0] = '\0';
309 dbcache[i].gensuffix[0] = '\0';
310 dbcache[i].textsuffix[0] = '\0';
311 dbcache[i].qd = NULL;
312 }
313
314 dbcacheinited = 1;
315}
316
317/* returns the next cache access number and increments it */
318static int get_next_accessnum (void) {
319 return cache_nextaccessnum++;
320}
321
322/* get_free_dbcache returns the cache number which */
323/* was used the longest time ago */
324/* init_dbcache should be called before this function */
325static int get_free_dbcache (void) {
326 int i = 0;
327 int minaccessnum = cache_nextaccessnum; /* the current max */
328 int minpos = 0;
329
330 for (i=0; i<MAXNUMDATABASEINFO; i++) {
331 if (dbcache[i].accessnum < minaccessnum) {
332 minaccessnum = dbcache[i].accessnum;
333 minpos = i;
334 }
335 }
336
337 return minpos;
338}
339
340/* search_collect will search for an index which */
341/* belongs to a certain collection It returns -1 if none could be found. */
342/* init_dbcache should be called before this function */
343static int search_collect (char *collection) {
344 int i = 0;
345
346 for (i=0; i<MAXNUMDATABASEINFO; i++) {
347 if ((dbcache[i].accessnum >= 0) &&
348 (dbcache[i].qd != NULL) &&
349 (strcmp (collection, dbcache[i].collection) == 0)
350 /* && (dbcache[i].qd->id->ifh.InvfLevel == 2)*/
351 ) {
352 dbcache[i].accessnum = get_next_accessnum ();
353 return i;
354 }
355 }
356
357 return -1;
358}
359
360/* search_gensuffix will search for an index which */
361/* has a certain gensuffix. It returns -1 if none could be found. */
362/* init_dbcache should be called before this function */
363static int search_gensuffix (char *gensuffix) {
364 int i = 0;
365
366 for (i=0; i<MAXNUMDATABASEINFO; i++) {
367 if ((dbcache[i].accessnum >= 0) &&
368 (dbcache[i].qd != NULL) &&
369 (strcmp (gensuffix, dbcache[i].gensuffix) == 0)) {
370 dbcache[i].accessnum = get_next_accessnum ();
371 return i;
372 }
373 }
374
375 return -1;
376}
377
378/* unload_database will unload a certain entry within */
379/* the database cache, clearing it for furture use. */
380static void unload_database (int i) {
381 /* check to see if it contains anything */
382 if (dbcache[i].accessnum < 0 || dbcache[i].qd == NULL)
383 return;
384
385 /* unload all the query information */
386 FinishQuerySystem(dbcache[i].qd);
387
388 /* reset all the db info */
389 dbcache[i].accessnum = -1;
390 dbcache[i].collection[0] = '\0';
391 dbcache[i].mgdir[0] = '\0';
392 dbcache[i].gensuffix[0] = '\0';
393 dbcache[i].textsuffix[0] = '\0';
394 dbcache[i].qd = NULL;
395
396 cache_numloaded--;
397 if (cache_numloaded < 0) cache_numloaded = 0;
398}
399
400/* cache_database will store the information about */
401/* a database in the database cache. */
402static void cache_database (int i, char *collection, char *mgdir, char *gensuffix,
403 char *textsuffix, query_data *qd) {
404 /* make sure this entry has been unloaded first */
405 if (dbcache[i].accessnum >= 0 && dbcache[i].qd != NULL)
406 unload_database (i);
407
408 /* store the db info */
409 dbcache[i].accessnum = get_next_accessnum ();
410 strcpy (dbcache[i].collection, collection);
411 strcpy (dbcache[i].mgdir, mgdir);
412 strcpy (dbcache[i].gensuffix, gensuffix);
413 strcpy (dbcache[i].textsuffix, textsuffix);
414 dbcache[i].qd = qd;
415
416 cache_numloaded++;
417}
418
419static void make_current (int i) {
420 /* see if it is the current index */
421 if (i == cur_cachenum) return;
422
423 /* unload the old index */
424 if (cur_cachenum >= 0) UninitEnv ();
425 cur_cachenum = -1;
426
427 /* make sure the new one is ok */
428 if (i < 0 || dbcache[i].accessnum < 0 || dbcache[i].qd == NULL)
429 return;
430
431 /* load the new one */
432
433 /* Initialise the environment with default values */
434 InitEnv ();
435
436 SetEnv("mgdir",dbcache[i].mgdir,NULL);
437 SetEnv("mgname",dbcache[i].gensuffix,NULL);
438 SetEnv("textname",dbcache[i].textsuffix,NULL);
439
440 PushEnv ();
441
442 cur_cachenum = i;
443}
444
445
446
447/********************
448 * public functions *
449 ********************/
450
451int mgq_ask(char *line)
452{
453 query_data *qd = (query_data *)NULL;
454 char QueryType = QUERY_BOOLEAN;
455 char OutputType = QUERY_DOCNUMS;
456 char *LinePtr = (char *)NULL;
457
458 if (cur_cachenum == -1) return 0;
459 qd = dbcache[cur_cachenum].qd;
460 if (qd == NULL) return 0;
461
462 ResetFileStats (qd);
463 qd->max_mem_in_use = qd->mem_in_use = 0;
464 qd->tot_hops_taken += qd->hops_taken;
465 qd->tot_num_of_ptrs += qd->num_of_ptrs;
466 qd->tot_num_of_accum += qd->num_of_accum;
467 qd->tot_num_of_terms += qd->num_of_terms;
468 qd->tot_num_of_ans += qd->num_of_ans;
469 qd->tot_text_idx_lookups += qd->text_idx_lookups;
470 qd->hops_taken = qd->num_of_ptrs = 0;
471 qd->num_of_accum = qd->num_of_ans = qd->num_of_terms = 0;
472 qd->text_idx_lookups = 0;
473
474 LinePtr = ProcessCommands (line, qd);
475 if (CommandsErrorStr) {
476 fprintf (stderr, "%s\n", CommandsErrorStr);
477 return 0;
478 }
479 if (*LinePtr == '\0') return 1;
480
481 FreeQueryDocs (qd);
482
483 QueryType = get_query_type ();
484 OutputType = get_output_type ();
485 /* No point in hiliting words on a docnum query */
486 if (OutputType == OUTPUT_HILITE && QueryType == QUERY_DOCNUMS)
487 OutputType = OUTPUT_TEXT;
488
489 switch (QueryType)
490 {
491 case QUERY_BOOLEAN:
492 {
493 char *maxdocs = (char *)NULL;
494 BooleanQueryInfo bqi;
495 maxdocs = GetDefEnv ("maxdocs", "all");
496 bqi.MaxDocsToRetrieve = strcmp (maxdocs, "all") ? atoi (maxdocs) : -1;
497 if (qd->sd->sdh.indexed)
498 BooleanQuery (qd, line, &bqi, (BooleanEnv (GetEnv ("casefold"), 0) |
499 (BooleanEnv (GetEnv ("stem"), 0) << 1)));
500 else
501 BooleanQuery (qd, line, &bqi, qd->sd->sdh.stem_method);
502 /* if (qd->sd->sdh.indexed) BooleanQuery (qd, line, &bqi, 3);
503 else BooleanQuery (qd, line, &bqi, qd->sd->sdh.stem_method); */
504 break;
505 }
506 case QUERY_APPROX:
507 case QUERY_RANKED:
508 {
509 char *maxdocs = (char *)NULL;
510 char *maxterms = (char *)NULL;
511 char *maxaccum = (char *)NULL;
512 RankedQueryInfo rqi;
513 maxdocs = GetDefEnv ("maxdocs", "all");
514 maxterms = GetDefEnv ("max_terms", "all");
515 maxaccum = GetDefEnv ("max_accumulators", "all");
516 rqi.Sort = BooleanEnv (GetEnv ("sorted_terms"), 0);
517 rqi.QueryFreqs = BooleanEnv (GetEnv ("qfreq"), 1);
518 rqi.Exact = QueryType == QUERY_RANKED;
519 rqi.MaxDocsToRetrieve = strcmp (maxdocs, "all") ? atoi (maxdocs) : -1;
520 rqi.MaxTerms = strcmp (maxterms, "all") ? atoi (maxterms) : -1;
521 rqi.MaxParasToRetrieve = rqi.MaxDocsToRetrieve;
522 if (qd->id->ifh.InvfLevel == 3 && GetEnv ("maxparas"))
523 rqi.MaxParasToRetrieve = atoi (GetEnv ("maxparas"));
524 rqi.AccumMethod = toupper (*GetDefEnv ("accumulator_method", "A"));
525 rqi.MaxAccums = strcmp (maxaccum, "all") ? atoi (maxaccum) : -1;
526 rqi.HashTblSize = IntEnv (GetEnv ("hash_tbl_size"), 1000);
527 rqi.StopAtMaxAccum = BooleanEnv (GetEnv ("stop_at_max_accum"), 0);
528 rqi.skip_dump = GetEnv ("skip_dump");
529 RankedQuery (qd, line, &rqi);
530 break;
531 }
532 case QUERY_DOCNUMS:
533 {
534 DocnumsQuery (qd, line);
535 break;
536 }
537 }
538
539 return 1;
540}
541
542int mgq_numdocs(void)
543{
544 query_data *qd = NULL;
545 if (cur_cachenum == -1) return 0;
546 qd = dbcache[cur_cachenum].qd;
547 if (qd == NULL) return 0;
548
549 if (qd->DL) return qd->DL->num;
550 else return 0;
551}
552
553int mgq_numterms(void)
554{
555 query_data *qd = NULL;
556 if (cur_cachenum == -1) return 0;
557 qd = dbcache[cur_cachenum].qd;
558 if (qd == NULL) return 0;
559
560 if (qd->QTL) return qd->QTL->num;
561 else return 0;
562}
563
564int mgq_results(enum result_kinds kind,int skip,int howmany, int (*sender)(char *, int, int, float, void *), void *ptr)
565{
566 query_data *qd = NULL;
567 if (cur_cachenum == -1) return 0;
568 qd = dbcache[cur_cachenum].qd;
569 if (qd == NULL) return 0;
570
571 if (qd->DL) {
572 qd->doc_pos = 0;
573 MoreDocs(qd, kind, skip, howmany, sender, ptr);
574 }
575 return 0;
576}
577
578/* get all the terms that match wordstem using the current stemmer and */
579/* stemming method. The callback is the same style used by mgq_results */
580int mgq_equivterms (unsigned char *wordstem, int (*sender)(char *, int, int, float, void *),
581 void *ptr) {
582 int stem_method = 0;
583 query_data *qd = NULL;
584 TermList *equivterms = NULL; /* used for equivalent terms */
585
586 if (cur_cachenum == -1) return 0;
587 qd = dbcache[cur_cachenum].qd;
588 if (qd == NULL || wordstem == NULL || sender == NULL) return 0;
589
590 if (qd->sd->sdh.indexed) {
591 stem_method = BooleanEnv(GetEnv("casefold"),0) | (BooleanEnv(GetEnv("stem"),0) << 1);
592 } else {
593 stem_method = qd->sd->sdh.stem_method;
594 }
595
596 /* make the term list */
597 equivterms = MakeTermList (0);
598
599 /* expand out this word */
600 if (FindWords (qd->sd, wordstem, stem_method, &equivterms) > 0) {
601 int i;
602 for (i=0; i < equivterms->num; i++) {
603 (* sender)((char *)(equivterms->TE[i].Word+1), equivterms->TE[i].Word[0],
604 equivterms->TE[i].Count, (float)0.0, ptr);
605 }
606 }
607
608 /* free the term list */
609 if (equivterms != NULL) FreeTermList (&equivterms);
610
611 return 0;
612}
613
614/* gets the total number of documents retrieved. If this is not available */
615/* it will set total_retrieved to 0 (even when it obviously isn't) */
616int mgq_docsretrieved (int *total_retrieved, int *is_approx) {
617 query_data *qd = NULL;
618
619 if (cur_cachenum == -1) return 0;
620 qd = dbcache[cur_cachenum].qd;
621 if (qd == NULL || total_retrieved == NULL || is_approx == NULL) return 0;
622
623 /* set default values */
624 *total_retrieved = 0;
625 *is_approx = 0;
626
627 if (qd->DL == NULL) return 0;
628
629 *total_retrieved = qd->DL->total_retrieved;
630 *is_approx = qd->DL->is_approx;
631
632 return 0;
633}
634
635
636/* use mgq_getmaxstemlen to determine the length of the word stems to pass */
637/* to mgq_stemword */
638int mgq_getmaxstemlen () {
639 return MAXSTEMLEN;
640}
641
642/* note: the stemming method and the stemmer come from the last query */
643/* "word" should be at least maxstemlen+1 long and it is a string that */
644/* starts with the string length */
645void mgq_stemword (unsigned char *word) {
646 int stem_method = 0;
647 query_data *qd = NULL;
648
649 if (cur_cachenum == -1) return;
650 qd = dbcache[cur_cachenum].qd;
651 if (qd == NULL || word == NULL) return;
652
653 if (qd->sd->sdh.indexed) {
654 stem_method = BooleanEnv(GetEnv("casefold"),0) | (BooleanEnv(GetEnv("stem"),0) << 1);
655 } else {
656 stem_method = qd->sd->sdh.stem_method;
657 }
658
659 stemmer (stem_method, qd->sd->sdh.stemmer_num, word);
660}
661
662
663
664int is_dbcache_full (void) {
665 init_dbcache ();
666 if (cache_numloaded >= MAXNUMDATABASEINFO) return 1;
667 return 0;
668}
669
670int load_database (char *collection, char *mgdir,
671 char *gensuffix, char *textsuffix) {
672 int i = 0;
673 query_data *qd = NULL;
674 /* FILE *deb = NULL; */
675 init_dbcache ();
676
677 /* print out some debug information */
678/* deb = fopen ("/home/rjmcnab/gsdl/etc/deb.txt", "a");
679 fprintf (deb, "\ncache_nextaccessnum: %i\n", cache_nextaccessnum);
680 fprintf (deb, "cache_numloaded: %i\n", cache_numloaded);
681 fprintf (deb, "cur_cachenum: %i\n", cur_cachenum);
682 fprintf (deb, "MAXNUMDATABASEINFO: %i\n\n", MAXNUMDATABASEINFO);
683 for (i=0; i<MAXNUMDATABASEINFO; i++) {
684 fprintf (deb, "Entry %i\n", i);
685 fprintf (deb, " accessnum: %i\n", dbcache[i].accessnum);
686 fprintf (deb, " collection: %s\n", dbcache[i].collection);
687 fprintf (deb, " mgdir: %s\n", dbcache[i].mgdir);
688 fprintf (deb, " gensuffix: %s\n", dbcache[i].gensuffix);
689 fprintf (deb, " textsuffix: %s\n", dbcache[i].textsuffix);
690 fprintf (deb, " qd: %x\n", (int)(dbcache[i].qd));
691 }
692 fclose (deb); */
693
694 /* search for the index */
695 i = search_gensuffix (gensuffix);
696 if (i >= 0) {
697 make_current (i);
698 return 1;
699 }
700
701 /* if there was a current database then the */
702 /* environment needs uninitialising */
703 make_current (-1);
704
705 /* get a free cache number */
706 i = get_free_dbcache ();
707 unload_database (i);
708
709 /* load the index */
710 qd = InitQuerySystem (mgdir, gensuffix, textsuffix, NULL);
711 if (qd == NULL) return 0;
712
713 /* cache this index */
714 cache_database (i, collection, mgdir, gensuffix, textsuffix, qd);
715
716 /* make this index current */
717 make_current (i);
718
719 return 1;
720}
721
722/* load_text_database tries to make an index of the */
723/* specified collection current */
724int load_text_database (char *collection) {
725 int i = 0;
726 init_dbcache ();
727
728 /* search for the index */
729 i = search_collect (collection);
730
731 /* return if none were found */
732 if (i < 0) return 0;
733
734 /* make this index current */
735 make_current (i);
736 return 1;
737}
738
739void close_all_databases (void) {
740 int i = 0;
741 init_dbcache ();
742
743 /* unload all active databases */
744 for (i=0; i<MAXNUMDATABASEINFO; i++) {
745 unload_database (i);
746 }
747
748 /* if there was a current database then the */
749 /* environment needs uninitialising */
750 make_current (-1);
751}
752
753
754
Note: See TracBrowser for help on using the repository browser.