d4438633d361c4e81972f9e2895068adfd3c7fdf
[idzebra-moved-to-github.git] / index / zinfo.c
1 /*
2  * Copyright (C) 1994-1997, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: zinfo.c,v $
7  * Revision 1.6  1998-02-17 10:29:27  adam
8  * Moved towards 'automatic' EXPLAIN database.
9  *
10  * Revision 1.5  1997/10/27 14:33:05  adam
11  * Moved towards generic character mapping depending on "structure"
12  * field in abstract syntax file. Fixed a few memory leaks. Fixed
13  * bug with negative integers when doing searches with relational
14  * operators.
15  *
16  * Revision 1.4  1997/09/25 14:57:08  adam
17  * Added string.h.
18  *
19  * Revision 1.3  1996/05/22 08:21:59  adam
20  * Added public ZebDatabaseInfo structure.
21  *
22  * Revision 1.2  1996/05/14 06:16:41  adam
23  * Compact use/set bytes used in search service.
24  *
25  * Revision 1.1  1996/05/13 14:23:07  adam
26  * Work on compaction of set/use bytes in dictionary.
27  *
28  */
29
30 #include <stdlib.h>
31 #include <assert.h>
32 #include <string.h>
33
34 #include "zinfo.h"
35
36 struct zebSUInfo {
37     int set;
38     int use;
39     int ordinal;
40 };
41
42 struct zebSUInfoB {
43     struct zebSUInfo info;
44     struct zebSUInfoB *next;
45 };
46
47 struct zebDatabaseInfoB {
48     struct zebSUInfoB *SUInfo;
49     char *databaseName;
50     int sysno;
51     int readFlag;
52     int dirty;
53     struct zebDatabaseInfo info;
54     struct zebDatabaseInfoB *next;
55 };
56
57 struct zebTargetInfo {
58     int  dictNum;
59     int  dirty;
60     Records records;
61     struct zebDatabaseInfoB *databaseInfo;
62     struct zebDatabaseInfoB *curDatabaseInfo;
63 };
64
65 void zebTargetInfo_close (ZebTargetInfo *zti, int writeFlag)
66 {
67     struct zebDatabaseInfoB *zdi, *zdi1;
68     
69     if (writeFlag)
70     {
71         char p0[4096], *p = p0;
72
73         memcpy (p, &zti->dictNum, sizeof(zti->dictNum));
74         p += sizeof(zti->dictNum);
75         for (zdi = zti->databaseInfo; zdi; zdi=zdi->next)
76         {
77             if (zdi->dirty)
78             {
79                 char q0[4096], *q = q0;
80                 struct zebSUInfoB *zsui;
81                 Record drec;
82                 int no = 0;
83                 
84                 if (zdi->sysno)
85                     drec = rec_get (zti->records, zdi->sysno);
86                 else
87                 {
88                     drec = rec_new (zti->records);
89                     
90                     drec->info[recInfo_fileType] =
91                         rec_strdup ("grs.explain.databaseInfo",
92                                     &drec->size[recInfo_fileType]);
93
94                     drec->info[recInfo_databaseName] =
95                         rec_strdup ("IR-Explain-1",
96                                     &drec->size[recInfo_databaseName]); 
97                     zdi->sysno = drec->sysno;
98                 }
99                 assert (drec);
100                 for (zsui = zdi->SUInfo; zsui; zsui=zsui->next)
101                     no++;
102                 memcpy (q, &zdi->info, sizeof(zdi->info));
103                 q += sizeof(zdi->info);
104                 memcpy (q, &no, sizeof(no));
105                 q += sizeof(no);
106                 for (zsui = zdi->SUInfo; zsui; zsui=zsui->next)
107                 {
108                     memcpy (q, &zsui->info, sizeof(zsui->info));
109                     q += sizeof(zsui->info);
110                 }
111                 xfree (drec->info[recInfo_storeData]);
112                 drec->size[recInfo_storeData] = q-q0;
113                 drec->info[recInfo_storeData] = xmalloc (drec->size[recInfo_storeData]);
114                 memcpy (drec->info[recInfo_storeData], q0, drec->size[recInfo_storeData]);
115                 rec_put (zti->records, &drec);
116             }
117             strcpy (p, zdi->databaseName);
118             p += strlen(p)+1;
119             memcpy (p, &zdi->sysno, sizeof(zdi->sysno));
120             p += sizeof(zdi->sysno);
121         }
122         *p++ = '\0';
123         if (zti->dirty)
124         {
125             Record grec = rec_get (zti->records, 1);
126
127             assert (grec);
128             xfree (grec->info[recInfo_storeData]);
129             grec->size[recInfo_storeData] = p-p0;
130             grec->info[recInfo_storeData] = xmalloc (grec->size[recInfo_storeData]);
131             memcpy (grec->info[recInfo_storeData], p0, grec->size[recInfo_storeData]);
132             rec_put (zti->records, &grec);
133         }
134     }
135     for (zdi = zti->databaseInfo; zdi; zdi = zdi1)
136     {
137         struct zebSUInfoB *zsui, *zsui1;
138
139         zdi1 = zdi->next;
140         for (zsui = zdi->SUInfo; zsui; zsui = zsui1)
141         {
142             zsui1 = zsui->next;
143             xfree (zsui);
144         }
145         xfree (zdi->databaseName);
146         xfree (zdi);
147     }
148     xfree (zti);
149 }
150
151 ZebTargetInfo *zebTargetInfo_open (Records records, int writeFlag)
152 {
153     Record trec;
154     ZebTargetInfo *zti;
155     struct zebDatabaseInfoB **zdi;
156
157     zti = xmalloc (sizeof(*zti));
158     zti->dirty = 0;
159     zti->curDatabaseInfo = NULL;
160     zti->records = records;
161
162     zdi = &zti->databaseInfo;
163     
164     trec = rec_get (records, 1);
165     if (trec)
166     {
167         const char *p;
168
169         p = trec->info[recInfo_storeData];
170
171         memcpy (&zti->dictNum, p, sizeof(zti->dictNum));
172         p += sizeof(zti->dictNum);
173         while (*p)
174         {
175             *zdi = xmalloc (sizeof(**zdi));
176             (*zdi)->SUInfo = NULL;
177             (*zdi)->databaseName = xstrdup (p);
178             p += strlen(p)+1;
179             memcpy (&(*zdi)->sysno, p, sizeof((*zdi)->sysno));
180             p += sizeof((*zdi)->sysno);
181             (*zdi)->readFlag = 1;
182             (*zdi)->dirty = 0;
183             zdi = &(*zdi)->next;
184         }
185         assert (p - trec->info[recInfo_storeData] == trec->size[recInfo_storeData]-1);
186     }
187     else
188     {
189         zti->dictNum = 1;
190         if (writeFlag)
191         {
192             trec = rec_new (records);
193
194             trec->info[recInfo_fileType] =
195                 rec_strdup ("grs.explain.targetInfo",
196                             &trec->size[recInfo_fileType]); 
197             trec->info[recInfo_databaseName] =
198                 rec_strdup ("IR-Explain-1",
199                             &trec->size[recInfo_databaseName]); 
200             trec->info[recInfo_databaseName] = xstrdup ("IR-Explain-1");
201             trec->info[recInfo_storeData] = xmalloc (1+sizeof(zti->dictNum));
202             memcpy (trec->info[recInfo_storeData], &zti->dictNum, sizeof(zti->dictNum));
203             trec->info[recInfo_storeData][sizeof(zti->dictNum)] = '\0';
204             trec->size[recInfo_storeData] = sizeof(zti->dictNum)+1;
205             rec_put (records, &trec);
206         }
207     }
208     *zdi = NULL;
209     rec_rm (&trec);
210     return zti;
211 }
212
213 static void zebTargetInfo_readDatabase (ZebTargetInfo *zti,
214                                         struct zebDatabaseInfoB *zdi)
215 {
216     const char *p;
217     struct zebSUInfoB **zsuip = &zdi->SUInfo;
218     int i, no;
219     Record rec;
220
221     rec = rec_get (zti->records, zdi->sysno);
222     assert (rec);
223     p = rec->info[recInfo_storeData];
224     memcpy (&zdi->info, p, sizeof(zdi->info));
225     p += sizeof(zdi->info);
226     memcpy (&no, p, sizeof(no));
227     p += sizeof(no);
228     for (i = 0; i<no; i++)
229     {
230         *zsuip = xmalloc (sizeof(**zsuip));
231         memcpy (&(*zsuip)->info, p, sizeof((*zsuip)->info));
232         p += sizeof((*zsuip)->info);
233         zsuip = &(*zsuip)->next;
234     }
235     *zsuip = NULL;
236     zdi->readFlag = 0;
237     rec_rm (&rec);
238 }
239
240 int zebTargetInfo_curDatabase (ZebTargetInfo *zti, const char *database)
241 {
242     struct zebDatabaseInfoB *zdi;
243     
244     assert (zti);
245     if (zti->curDatabaseInfo &&
246         !strcmp (zti->curDatabaseInfo->databaseName, database))
247         return 0;
248     for (zdi = zti->databaseInfo; zdi; zdi=zdi->next)
249     {
250         if (!strcmp (zdi->databaseName, database))
251             break;
252     }
253     if (!zdi)
254         return -1;
255     if (zdi->readFlag)
256         zebTargetInfo_readDatabase (zti, zdi);
257     zti->curDatabaseInfo = zdi;
258     return 0;
259 }
260
261 int zebTargetInfo_newDatabase (ZebTargetInfo *zti, const char *database)
262 {
263     struct zebDatabaseInfoB *zdi;
264
265     assert (zti);
266     for (zdi = zti->databaseInfo; zdi; zdi=zdi->next)
267     {
268         if (!strcmp (zdi->databaseName, database))
269             break;
270     }
271     if (zdi)
272         return -1;
273     zdi = xmalloc (sizeof(*zdi));
274     zdi->next = zti->databaseInfo;
275     zti->databaseInfo = zdi;
276     zdi->sysno = 0;
277     zdi->readFlag = 0;
278     zdi->databaseName = xstrdup (database);
279     zdi->SUInfo = NULL;
280     zdi->dirty = 1;
281     zti->dirty = 1;
282     zti->curDatabaseInfo = zdi;
283     return 0;
284 }
285
286 int zebTargetInfo_lookupSU (ZebTargetInfo *zti, int set, int use)
287 {
288     struct zebSUInfoB *zsui;
289
290     assert (zti->curDatabaseInfo);
291     for (zsui = zti->curDatabaseInfo->SUInfo; zsui; zsui=zsui->next)
292         if (zsui->info.use == use && zsui->info.set == set)
293             return zsui->info.ordinal;
294     return -1;
295 }
296
297 int zebTargetInfo_addSU (ZebTargetInfo *zti, int set, int use)
298 {
299     struct zebSUInfoB *zsui;
300
301     assert (zti->curDatabaseInfo);
302     for (zsui = zti->curDatabaseInfo->SUInfo; zsui; zsui=zsui->next)
303         if (zsui->info.use == use && zsui->info.set == set)
304             return -1;
305     zsui = xmalloc (sizeof(*zsui));
306     zsui->next = zti->curDatabaseInfo->SUInfo;
307     zti->curDatabaseInfo->SUInfo = zsui;
308     zti->curDatabaseInfo->dirty = 1;
309     zti->dirty = 1;
310     zsui->info.set = set;
311     zsui->info.use = use;
312     zsui->info.ordinal = (zti->dictNum)++;
313     return zsui->info.ordinal;
314 }
315
316 ZebDatabaseInfo *zebTargetInfo_getDB (ZebTargetInfo *zti)
317 {
318     assert (zti->curDatabaseInfo);
319
320     return &zti->curDatabaseInfo->info;
321 }
322
323 void zebTargetInfo_setDB (ZebTargetInfo *zti, ZebDatabaseInfo *zdi)
324 {
325     assert (zti->curDatabaseInfo);
326
327     zti->curDatabaseInfo->dirty = 1;
328     memcpy (&zti->curDatabaseInfo->info, zdi, sizeof(*zdi));
329 }
330