Use of cisam system - enabled if setting isamc is 1.
[idzebra-moved-to-github.git] / index / kcompare.c
1 /*
2  * Copyright (C) 1994-1996, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: kcompare.c,v $
7  * Revision 1.18  1996-10-29 14:09:44  adam
8  * Use of cisam system - enabled if setting isamc is 1.
9  *
10  * Revision 1.17  1996/06/04 10:18:58  adam
11  * Minor changes - removed include of ctype.h.
12  *
13  * Revision 1.16  1996/05/13  14:23:05  adam
14  * Work on compaction of set/use bytes in dictionary.
15  *
16  * Revision 1.15  1995/11/20  16:59:46  adam
17  * New update method: the 'old' keys are saved for each records.
18  *
19  * Revision 1.14  1995/10/30  15:08:08  adam
20  * Bug fixes.
21  *
22  * Revision 1.13  1995/10/27  14:00:11  adam
23  * Implemented detection of database availability.
24  *
25  * Revision 1.12  1995/10/17  18:02:08  adam
26  * New feature: databases. Implemented as prefix to words in dictionary.
27  *
28  * Revision 1.11  1995/10/06  16:33:37  adam
29  * Use attribute mappings.
30  *
31  * Revision 1.10  1995/09/29  14:01:41  adam
32  * Bug fixes.
33  *
34  * Revision 1.9  1995/09/28  12:10:32  adam
35  * Bug fixes. Field prefix used in queries.
36  *
37  * Revision 1.8  1995/09/28  09:19:42  adam
38  * xfree/xmalloc used everywhere.
39  * Extract/retrieve method seems to work for text records.
40  *
41  * Revision 1.7  1995/09/27  12:22:28  adam
42  * More work on extract in record control.
43  * Field name is not in isam keys but in prefix in dictionary words.
44  *
45  * Revision 1.6  1995/09/14  07:48:23  adam
46  * Record control management.
47  *
48  * Revision 1.5  1995/09/11  13:09:34  adam
49  * More work on relevance feedback.
50  *
51  * Revision 1.4  1995/09/08  14:52:27  adam
52  * Minor changes. Dictionary is lower case now.
53  *
54  * Revision 1.3  1995/09/07  13:58:36  adam
55  * New parameter: result-set file descriptor (RSFD) to support multiple
56  * positions within the same result-set.
57  * Boolean operators: and, or, not implemented.
58  * Result-set references.
59  *
60  * Revision 1.2  1995/09/06  16:11:17  adam
61  * Option: only one word key per file.
62  *
63  * Revision 1.1  1995/09/04  09:10:36  adam
64  * More work on index add/del/update.
65  * Merge sort implemented.
66  * Initial work on z39 server.
67  *
68  */
69
70 #include <stdlib.h>
71 #include <string.h>
72 #include <stdio.h>
73 #include <assert.h>
74
75 #include "index.h"
76
77 void key_logdump (int logmask, const void *p)
78 {
79     struct it_key key;
80
81     memcpy (&key, p, sizeof(key));
82     logf (logmask, "%7d s=%-4d", key.sysno, key.seqno);
83 }
84
85 int key_compare (const void *p1, const void *p2)
86 {
87     struct it_key i1, i2;
88     memcpy (&i1, p1, sizeof(i1));
89     memcpy (&i2, p2, sizeof(i2));
90     if (i1.sysno != i2.sysno)
91     {
92         if (i1.sysno > i2.sysno)
93             return 2;
94         else
95             return -2;
96     }
97 #if IT_KEY_HAVE_SEQNO
98     if (i1.seqno != i2.seqno)
99     {
100         if (i1.seqno > i2.seqno)
101             return 1;
102         else
103             return -1;
104     }
105 #else
106     if (i1.freq != i2.freq)
107     {
108         if (i1.freq > i2.freq)
109             return 1;
110         else
111             return -1;
112     }
113 #endif
114     return 0;
115 }
116
117 int key_qsort_compare (const void *p1, const void *p2)
118 {
119     int r;
120     size_t l;
121     char *cp1 = *(char **) p1;
122     char *cp2 = *(char **) p2;
123  
124     if ((r = strcmp (cp1, cp2)))
125         return r;
126     l = strlen(cp1)+1;
127     if ((r = key_compare (cp1+l+1, cp2+l+1)))
128         return r;
129     return cp1[l] - cp2[l];
130 }
131
132 struct iscz_code_info {
133     struct it_key key;
134 };
135
136 static void *iscz_code_start (int mode)
137 {
138     struct iscz_code_info *p = xmalloc (sizeof(*p));
139     p->key.sysno = 0;
140     p->key.seqno = 0;
141     return p;
142 }
143
144 static void iscz_code_stop (int mode, void *p)
145 {
146     xfree (p);
147 }
148
149 void iscz_encode_int (unsigned d, char **dst)
150 {
151     unsigned char *bp = (unsigned char*) *dst;
152
153     if (d <= 63)
154         *bp++ = d;
155     else if (d <= 16383)
156     {
157         *bp++ = 64 + (d>>8);
158        *bp++ = d & 255;
159     }
160     else if (d <= 4194303)
161     {
162         *bp++ = 128 + (d>>16);
163         *bp++ = (d>>8) & 255;
164         *bp++ = d & 255;
165     }
166     else
167     {
168         *bp++ = 192 + (d>>24);
169         *bp++ = (d>>16) & 255;
170         *bp++ = (d>>8) & 255;
171         *bp++ = d & 255;
172     }
173     *dst = (char *) bp;
174 }
175
176 int isxz_decode_int (unsigned char **src)
177 {
178     unsigned c = *(*src)++;
179     switch (c & 192)
180     {
181     case 0:
182         return c;
183     case 64:
184         return ((c & 63) << 8) + *(*src)++;
185     case 128:
186         c = ((c & 63) << 8) + *(*src)++;
187         c = (c << 8) + *(*src)++;
188         return c;
189     }
190     c = ((c & 63) << 8) + *(*src)++;
191     c = (c << 8) + *(*src)++;
192     c = (c << 8) + *(*src)++;
193     return c;
194 }
195
196 static void iscz_code_item (int mode, void *vp, char **dst, char **src)
197 {
198     struct iscz_code_info *p = vp;
199     struct it_key tkey;
200     int d;
201
202     if (mode == ISAMC_ENCODE)
203     {
204         memcpy (&tkey, *src, sizeof(struct it_key));
205         d = tkey.sysno - p->key.sysno;
206         iscz_encode_int (d, dst);
207         if (d)
208         {
209             p->key.sysno = tkey.sysno;
210             p->key.seqno = 0;
211         }
212         iscz_encode_int (tkey.seqno - p->key.seqno, dst);
213         p->key.seqno = tkey.seqno;
214         (*src) += sizeof(struct it_key);
215     }
216     else
217     {
218         d = isxz_decode_int ((unsigned char **) src);
219         if (d)
220         {
221             p->key.sysno += d;
222             p->key.seqno = 0;
223         }
224         d = isxz_decode_int ((unsigned char **) src);
225         p->key.seqno += d;
226         memcpy (*dst, &p->key, sizeof(struct it_key));
227         (*dst) += sizeof(struct it_key);
228     }
229 }
230
231 ISAMC_M key_isamc_m (void)
232 {
233     static ISAMC_M me = NULL;
234
235     if (me)
236         return me;
237
238     me = isc_getmethod ();
239
240     me->compare_item = key_compare;
241
242     me->code_start = iscz_code_start;
243     me->code_item = iscz_code_item;
244     me->code_stop = iscz_code_stop;
245
246     me->debug = atoi(res_get_def (common_resource, "isamcDebug", "0"));
247
248     logf (LOG_LOG, "ISAMC system active");
249     return me;
250 }
251