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