Implemented automatic EXPLAIN database maintenance.
[idzebra-moved-to-github.git] / index / zebraapi.c
1 /*
2  * Copyright (C) 1995-1998, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: zebraapi.c,v $
7  * Revision 1.2  1998-05-20 10:12:19  adam
8  * Implemented automatic EXPLAIN database maintenance.
9  * Modified Zebra to work with ASN.1 compiled version of YAZ.
10  *
11  * Revision 1.1  1998/03/05 08:45:13  adam
12  * New result set model and modular ranking system. Moved towards
13  * descent server API. System information stored as "SGML" records.
14  *
15  */
16
17 #include <stdio.h>
18 #ifdef WINDOWS
19 #include <io.h>
20 #include <process.h>
21 #else
22 #include <unistd.h>
23 #endif
24
25 #include "zserver.h"
26
27 static int zebra_register_lock (ZebraHandle zh)
28 {
29     time_t lastChange;
30     int state = zebra_server_lock_get_state(zh, &lastChange);
31
32     switch (state)
33     {
34     case 'c':
35         state = 1;
36         break;
37     default:
38         state = 0;
39     }
40     zebra_server_lock (zh, state);
41 #if USE_TIMES
42     times (&zh->tms1);
43 #endif
44     if (zh->registerState == state)
45     {
46         if (zh->registerChange >= lastChange)
47             return 0;
48         logf (LOG_LOG, "Register completely updated since last access");
49     }
50     else if (zh->registerState == -1)
51         logf (LOG_LOG, "Reading register using state %d pid=%ld", state,
52               (long) getpid());
53     else
54         logf (LOG_LOG, "Register has changed state from %d to %d",
55               zh->registerState, state);
56     zh->registerChange = lastChange;
57     if (zh->records)
58     {
59         zebraExplain_close (zh->zei, 0, 0);
60         dict_close (zh->dict);
61         sortIdx_close (zh->sortIdx);
62         if (zh->isam)
63             is_close (zh->isam);
64         if (zh->isamc)
65             isc_close (zh->isamc);
66         rec_close (&zh->records);
67     }
68     bf_cache (zh->bfs, state ? res_get (zh->res, "shadow") : NULL);
69     zh->registerState = state;
70     zh->records = rec_open (zh->bfs, 0);
71     if (!(zh->dict = dict_open (zh->bfs, FNAME_DICT, 40, 0)))
72         return -1;
73     if (!(zh->sortIdx = sortIdx_open (zh->bfs, 0)))
74         return -1;
75     zh->isam = NULL;
76     zh->isamc = NULL;
77     if (!res_get_match (zh->res, "isam", "i", NULL))
78     {
79         if (!(zh->isamc = isc_open (zh->bfs, FNAME_ISAMC,
80                                     0, key_isamc_m(zh->res))))
81             return -1;
82
83     }
84     else
85     {
86         if (!(zh->isam = is_open (zh->bfs, FNAME_ISAM, key_compare, 0,
87                                   sizeof (struct it_key), zh->res)))
88             return -1;
89     }
90     zh->zei = zebraExplain_open (zh->records, zh->dh, zh->res, 0, 0, 0);
91
92     return 0;
93 }
94
95 static void zebra_register_unlock (ZebraHandle zh)
96 {
97     static int waitSec = -1;
98
99 #if USE_TIMES
100     times (&zh->tms2);
101     logf (LOG_LOG, "user/system: %ld/%ld",
102                         (long) (zh->tms2.tms_utime - zh->tms1.tms_utime),
103                         (long) (zh->tms2.tms_stime - zh->tms1.tms_stime));
104 #endif
105     if (waitSec == -1)
106     {
107         char *s = res_get (zh->res, "debugRequestWait");
108         if (s)
109             waitSec = atoi (s);
110         else
111             waitSec = 0;
112     }
113 #ifdef WINDOWS
114 #else
115     if (waitSec > 0)
116         sleep (waitSec);
117 #endif
118     if (zh->registerState != -1)
119         zebra_server_unlock (zh, zh->registerState);
120 }
121
122 ZebraHandle zebra_open (const char *host, const char *configName)
123 {
124     ZebraHandle zh = xmalloc (sizeof(*zh));
125
126     if (!(zh->res = res_open (configName)))
127     {
128         logf (LOG_WARN, "Failed to read resources `%s'", configName);
129         return NULL;
130     }
131     zebra_server_lock_init (zh);
132     zh->dh = data1_create ();
133     zh->bfs = bfs_create (res_get (zh->res, "register"));
134     bf_lockDir (zh->bfs, res_get (zh->res, "lockDir"));
135     data1_set_tabpath (zh->dh, res_get(zh->res, "profilePath"));
136     zh->sets = NULL;
137     zh->registerState = -1;  /* trigger open of registers! */
138     zh->registerChange = 0;
139     
140     zh->records = NULL;
141     zh->zebra_maps = zebra_maps_open (zh->res);
142     zh->rank_classes = NULL;
143     
144     zebraRankInstall (zh, rank1_class);
145     return zh;
146 }
147
148 void zebra_close (ZebraHandle zh)
149 {
150     if (zh->records)
151     {
152         resultSetDestroy (zh);
153         zebraExplain_close (zh->zei, 0, 0);
154         dict_close (zh->dict);
155         sortIdx_close (zh->sortIdx);
156         if (zh->isam)
157             is_close (zh->isam);
158         if (zh->isamc)
159             isc_close (zh->isamc);
160         rec_close (&zh->records);
161         zebra_register_unlock (zh);
162     }
163     zebra_maps_close (zh->zebra_maps);
164     zebraRankDestroy (zh);
165     bfs_destroy (zh->bfs);
166     data1_destroy (zh->dh);
167     zebra_server_lock_destroy (zh);
168
169     res_close (zh->res);
170     xfree (zh);
171 }
172
173 void zebra_search_rpn (ZebraHandle zh, ODR stream,
174                        Z_RPNQuery *query, int num_bases, char **basenames, 
175                        const char *setname)
176 {
177     zebra_register_lock (zh);
178     zh->errCode = 0;
179     zh->errString = NULL;
180     zh->hits = 0;
181     rpn_search (zh, stream, query, num_bases, basenames, setname);
182     zebra_register_unlock (zh);
183 }
184
185 void zebra_records_retrieve (ZebraHandle zh, ODR stream,
186                              const char *setname, Z_RecordComposition *comp,
187                              oid_value input_format, int num_recs,
188                              ZebraRetrievalRecord *recs)
189 {
190     ZebraPosSet poset;
191     int i, *pos_array;
192
193     pos_array = xmalloc (sizeof(*pos_array));
194     for (i = 0; i<num_recs; i++)
195         pos_array[i] = recs[i].position;
196
197     zebra_register_lock (zh);
198
199     poset = zebraPosSetCreate (zh, setname, num_recs, pos_array);
200     if (!poset)
201     {
202         logf (LOG_DEBUG, "zebraPosSetCreate error");
203         zh->errCode = 13;
204     }
205     else
206     {
207         for (i = 0; i<num_recs; i++)
208         {
209             if (!poset[i].sysno)
210             {
211                 zh->errCode = 13;
212                 logf (LOG_DEBUG, "Out of range. pos=%d", pos_array[i]);
213             }
214             else
215             {
216                 zh->errCode =
217                     zebra_record_fetch (zh, poset[i].sysno, poset[i].score,
218                                         stream, input_format, comp,
219                                         &recs[i].format, &recs[i].buf,
220                                         &recs[i].len,
221                                         &recs[i].base);
222             }
223         }
224         zebraPosSetDestroy (zh, poset, num_recs);
225     }
226     zebra_register_unlock (zh);
227     xfree (pos_array);
228 }
229
230 void zebra_scan (ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt,
231                  oid_value attributeset,
232                  int num_bases, char **basenames,
233                  int *position, int *num_entries, ZebraScanEntry **entries,
234                  int *is_partial)
235 {
236     zebra_register_lock (zh);
237     rpn_scan (zh, stream, zapt, attributeset,
238               num_bases, basenames, position,
239               num_entries, entries, is_partial);
240     zebra_register_unlock (zh);
241 }
242
243 void zebra_sort (ZebraHandle zh, ODR stream,
244                  int num_input_setnames, char **input_setnames,
245                  char *output_setname, Z_SortKeySpecList *sort_sequence,
246                  int *sort_status)
247 {
248     zebra_register_lock (zh);
249     resultSetSort (zh, stream, num_input_setnames, input_setnames,
250                    output_setname, sort_sequence, sort_status);
251     zebra_register_unlock (zh);
252 }
253
254 void zebra_setDB (ZebraHandle zh, int num_bases, char **basenames)
255 {
256
257 }
258
259 void zebra_setRecordType (ZebraHandle zh, const char *type)
260 {
261
262 }
263
264 void zebra_setGroup (ZebraHandle zh, const char *group)
265 {
266
267 }
268
269 void zebra_admin (ZebraHandle zh, const char *command)
270 {
271
272 }