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