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