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