Adding isamh stuff
[idzebra-moved-to-github.git] / index / kcompare.c
1 /*
2  * Copyright (C) 1994-1999, Index Data
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: kcompare.c,v $
7  * Revision 1.30  1999-06-30 15:07:23  heikki
8  * Adding isamh stuff
9  *
10  * Revision 1.29  1999/06/30 09:08:23  adam
11  * Added coder to reset.
12  *
13  * Revision 1.28  1999/05/26 07:49:13  adam
14  * C++ compilation.
15  *
16  * Revision 1.27  1999/05/12 13:08:06  adam
17  * First version of ISAMS.
18  *
19  * Revision 1.26  1999/02/02 14:50:54  adam
20  * Updated WIN32 code specific sections. Changed header.
21  *
22  * Revision 1.25  1998/06/08 15:26:06  adam
23  * Minor changes.
24  *
25  * Revision 1.24  1998/06/08 14:43:12  adam
26  * Added suport for EXPLAIN Proxy servers - added settings databasePath
27  * and explainDatabase to facilitate this. Increased maximum number
28  * of databases and attributes in one register.
29  *
30  * Revision 1.23  1998/03/05 08:45:12  adam
31  * New result set model and modular ranking system. Moved towards
32  * descent server API. System information stored as "SGML" records.
33  *
34  * Revision 1.22  1997/09/22 12:39:06  adam
35  * Added get_pos method for the ranked result sets.
36  *
37  * Revision 1.21  1997/09/17 12:19:13  adam
38  * Zebra version corresponds to YAZ version 1.4.
39  * Changed Zebra server so that it doesn't depend on global common_resource.
40  *
41  * Revision 1.20  1996/12/23 15:30:44  adam
42  * Work on truncation.
43  * Bug fix: result sets weren't deleted after server shut down.
44  *
45  * Revision 1.19  1996/12/11 12:08:00  adam
46  * Added better compression.
47  *
48  * Revision 1.18  1996/10/29 14:09:44  adam
49  * Use of cisam system - enabled if setting isamc is 1.
50  *
51  * Revision 1.17  1996/06/04 10:18:58  adam
52  * Minor changes - removed include of ctype.h.
53  *
54  * Revision 1.16  1996/05/13  14:23:05  adam
55  * Work on compaction of set/use bytes in dictionary.
56  *
57  * Revision 1.15  1995/11/20  16:59:46  adam
58  * New update method: the 'old' keys are saved for each records.
59  *
60  * Revision 1.14  1995/10/30  15:08:08  adam
61  * Bug fixes.
62  *
63  * Revision 1.13  1995/10/27  14:00:11  adam
64  * Implemented detection of database availability.
65  *
66  * Revision 1.12  1995/10/17  18:02:08  adam
67  * New feature: databases. Implemented as prefix to words in dictionary.
68  *
69  * Revision 1.11  1995/10/06  16:33:37  adam
70  * Use attribute mappings.
71  *
72  * Revision 1.10  1995/09/29  14:01:41  adam
73  * Bug fixes.
74  *
75  * Revision 1.9  1995/09/28  12:10:32  adam
76  * Bug fixes. Field prefix used in queries.
77  *
78  * Revision 1.8  1995/09/28  09:19:42  adam
79  * xfree/xmalloc used everywhere.
80  * Extract/retrieve method seems to work for text records.
81  *
82  * Revision 1.7  1995/09/27  12:22:28  adam
83  * More work on extract in record control.
84  * Field name is not in isam keys but in prefix in dictionary words.
85  *
86  * Revision 1.6  1995/09/14  07:48:23  adam
87  * Record control management.
88  *
89  * Revision 1.5  1995/09/11  13:09:34  adam
90  * More work on relevance feedback.
91  *
92  * Revision 1.4  1995/09/08  14:52:27  adam
93  * Minor changes. Dictionary is lower case now.
94  *
95  * Revision 1.3  1995/09/07  13:58:36  adam
96  * New parameter: result-set file descriptor (RSFD) to support multiple
97  * positions within the same result-set.
98  * Boolean operators: and, or, not implemented.
99  * Result-set references.
100  *
101  * Revision 1.2  1995/09/06  16:11:17  adam
102  * Option: only one word key per file.
103  *
104  * Revision 1.1  1995/09/04  09:10:36  adam
105  * More work on index add/del/update.
106  * Merge sort implemented.
107  * Initial work on z39 server.
108  *
109  */
110
111 #include <stdlib.h>
112 #include <string.h>
113 #include <stdio.h>
114 #include <assert.h>
115
116 #include "index.h"
117
118 void key_logdump (int logmask, const void *p)
119 {
120     struct it_key key;
121
122     memcpy (&key, p, sizeof(key));
123     logf (logmask, "%7d s=%-4d", key.sysno, key.seqno);
124 }
125
126 int key_compare_it (const void *p1, const void *p2)
127 {
128     if (((struct it_key *) p1)->sysno != ((struct it_key *) p2)->sysno)
129     {
130         if (((struct it_key *) p1)->sysno > ((struct it_key *) p2)->sysno)
131             return 2;
132         else
133             return -2;
134     }
135     if (((struct it_key *) p1)->seqno != ((struct it_key *) p2)->seqno)
136     {
137         if (((struct it_key *) p1)->seqno > ((struct it_key *) p2)->seqno)
138             return 1;
139         else
140             return -1;
141     }
142     return 0;
143 }
144
145 int key_compare (const void *p1, const void *p2)
146 {
147     struct it_key i1, i2;
148     memcpy (&i1, p1, sizeof(i1));
149     memcpy (&i2, p2, sizeof(i2));
150     if (i1.sysno != i2.sysno)
151     {
152         if (i1.sysno > i2.sysno)
153             return 2;
154         else
155             return -2;
156     }
157     if (i1.seqno != i2.seqno)
158     {
159         if (i1.seqno > i2.seqno)
160             return 1;
161         else
162             return -1;
163     }
164     return 0;
165 }
166
167 int key_qsort_compare (const void *p1, const void *p2)
168 {
169     int r;
170     size_t l;
171     char *cp1 = *(char **) p1;
172     char *cp2 = *(char **) p2;
173  
174     if ((r = strcmp (cp1, cp2)))
175         return r;
176     l = strlen(cp1)+1;
177     if ((r = key_compare (cp1+l+1, cp2+l+1)))
178         return r;
179     return cp1[l] - cp2[l];
180 }
181
182 int key_get_pos (const void *p)
183 {
184     struct it_key key;
185     memcpy (&key, p, sizeof(key));
186     return key.seqno;
187 }
188
189 struct iscz1_code_info {
190     struct it_key key;
191 };
192
193 static void *iscz1_code_start (int mode)
194 {
195     struct iscz1_code_info *p = (struct iscz1_code_info *)
196         xmalloc (sizeof(*p));
197     p->key.sysno = 0;
198     p->key.seqno = 0;
199     return p;
200 }
201
202 static void iscz1_code_reset (void *vp)
203 {
204     struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
205     p->key.sysno = 0;
206     p->key.seqno = 0;
207 }
208
209 static void iscz1_code_stop (int mode, void *p)
210 {
211     xfree (p);
212 }
213
214 void iscz1_encode_int (unsigned d, char **dst)
215 {
216     unsigned char *bp = (unsigned char*) *dst;
217
218     if (d <= 63)
219         *bp++ = d;
220     else if (d <= 16383)
221     {
222         *bp++ = 64 + (d>>8);
223        *bp++ = d & 255;
224     }
225     else if (d <= 4194303)
226     {
227         *bp++ = 128 + (d>>16);
228         *bp++ = (d>>8) & 255;
229         *bp++ = d & 255;
230     }
231     else
232     {
233         *bp++ = 192 + (d>>24);
234         *bp++ = (d>>16) & 255;
235         *bp++ = (d>>8) & 255;
236         *bp++ = d & 255;
237     }
238     *dst = (char *) bp;
239 }
240
241 int iscz1_decode_int (unsigned char **src)
242 {
243     unsigned c = *(*src)++;
244     switch (c & 192)
245     {
246     case 0:
247         return c;
248     case 64:
249         return ((c & 63) << 8) + *(*src)++;
250     case 128:
251         c = ((c & 63) << 8) + *(*src)++;
252         c = (c << 8) + *(*src)++;
253         return c;
254     }
255     c = ((c & 63) << 8) + *(*src)++;
256     c = (c << 8) + *(*src)++;
257     c = (c << 8) + *(*src)++;
258     return c;
259 }
260
261 static void iscz1_code_item (int mode, void *vp, char **dst, char **src)
262 {
263     struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
264     struct it_key tkey;
265     int d;
266
267     if (mode == ISAMC_ENCODE)
268     {
269         memcpy (&tkey, *src, sizeof(struct it_key));
270         d = tkey.sysno - p->key.sysno;
271         if (d)
272         {
273             iscz1_encode_int (2*tkey.seqno + 1, dst);
274             iscz1_encode_int (d, dst);
275             p->key.sysno += d;
276             p->key.seqno = tkey.seqno;
277         }
278         else
279         {
280             iscz1_encode_int (2*(tkey.seqno - p->key.seqno), dst);
281             p->key.seqno = tkey.seqno;
282         }
283         (*src) += sizeof(struct it_key);
284     }
285     else
286     {
287         d = iscz1_decode_int ((unsigned char **) src);
288         if (d & 1)
289         {
290             p->key.seqno = d>>1;
291             p->key.sysno += iscz1_decode_int ((unsigned char **) src);
292         }
293         else
294             p->key.seqno += d>>1;
295         memcpy (*dst, &p->key, sizeof(struct it_key));
296         (*dst) += sizeof(struct it_key);
297     }
298 }
299
300 ISAMC_M key_isamc_m (Res res)
301 {
302     static ISAMC_M me = NULL;
303
304     if (me)
305         return me;
306
307     me = isc_getmethod ();
308
309     me->compare_item = key_compare;
310
311     me->code_start = iscz1_code_start;
312     me->code_item = iscz1_code_item;
313     me->code_stop = iscz1_code_stop;
314     me->code_reset = iscz1_code_reset;
315
316     me->debug = atoi(res_get_def (res, "isamcDebug", "0"));
317
318     return me;
319 }
320
321 ISAMS_M key_isams_m (Res res)
322 {
323     static ISAMS_M me = NULL;
324
325     if (me)
326         return me;
327
328     me = isams_getmethod ();
329
330     me->compare_item = key_compare;
331
332     me->code_start = iscz1_code_start;
333     me->code_item = iscz1_code_item;
334     me->code_stop = iscz1_code_stop;
335
336     me->debug = atoi(res_get_def (res, "isamsDebug", "0"));
337
338     return me;
339 }
340
341 ISAMH_M key_isamh_m (Res res)
342 {
343     static ISAMH_M me = NULL;
344
345     if (me)
346         return me;
347
348     me = isamh_getmethod ();
349
350     me->compare_item = key_compare;
351
352     me->code_start = iscz1_code_start;
353     me->code_item = iscz1_code_item;
354     me->code_stop = iscz1_code_stop;
355
356     me->debug = atoi(res_get_def (res, "isamhDebug", "2"));
357
358     return me;
359 }
360
361
362 int key_SU_code (int ch, char *out)
363 {
364     int i;
365     for (i = 0; ch; i++)
366     {
367         if (ch > 63)
368             out[i] = 128 + (ch & 63);
369         else
370             out[i] = 1 + ch;
371         ch = ch >> 6;
372     }
373     return i;
374 }