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