1 /* $Id: kcompare.c,v 1.59 2006-07-04 14:10:30 adam Exp $
2 Copyright (C) 1995-2005
5 This file is part of the Zebra server.
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with Zebra; see the file LICENSE.zebra. If not, write to the
19 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
31 #define CODEC_INLINE inline
36 void key_logdump_txt(int logmask, const void *p, const char *txt)
46 memcpy (&key, p, sizeof(key));
47 assert(key.len > 0 && key.len <= IT_KEY_LEVEL_MAX);
49 for (i = 0; i<key.len; i++)
53 sprintf(formstr + strlen(formstr), ZINT_FORMAT, key.mem[i]);
55 yaz_log(logmask, "%s %s", formstr, txt);
58 yaz_log(logmask, " (no key) %s",txt);
61 void key_logdump(int logmask, const void *p)
63 key_logdump_txt(logmask, p, "");
66 int key_compare_it (const void *p1, const void *p2)
68 int i, l = ((struct it_key *) p1)->len;
69 if (((struct it_key *) p2)->len > l)
70 l = ((struct it_key *) p2)->len;
71 assert (l <= 4 && l > 0);
72 for (i = 0; i < l; i++)
74 if (((struct it_key *) p1)->mem[i] != ((struct it_key *) p2)->mem[i])
76 if (((struct it_key *) p1)->mem[i] > ((struct it_key *) p2)->mem[i])
85 char *key_print_it (const void *p, char *buf)
91 int key_compare (const void *p1, const void *p2)
95 memcpy (&i1, p1, sizeof(i1));
96 memcpy (&i2, p2, sizeof(i2));
100 assert (l <= 4 && l > 0);
101 for (i = 0; i < l; i++)
103 if (i1.mem[i] != i2.mem[i])
105 if (i1.mem[i] > i2.mem[i])
114 zint key_get_seq(const void *p)
117 memcpy (&k, p, sizeof(k));
118 return k.mem[k.len-1];
121 zint key_get_segment(const void *p)
124 memcpy (&k, p, sizeof(k));
125 return k.mem[k.len-1] / KEY_SEGMENT_SIZE;
128 int key_qsort_compare (const void *p1, const void *p2)
132 char *cp1 = *(char **) p1;
133 char *cp2 = *(char **) p2;
135 if ((r = strcmp (cp1, cp2)))
138 if ((r = key_compare (cp1+l+1, cp2+l+1)))
140 return cp1[l] - cp2[l];
143 struct iscz1_code_info {
147 void *iscz1_start (void)
149 struct iscz1_code_info *p = (struct iscz1_code_info *)
150 xmalloc (sizeof(*p));
155 void key_init(struct it_key *key)
159 for (i = 0; i<IT_KEY_LEVEL_MAX; i++)
163 void iscz1_reset (void *vp)
165 struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
168 for (i = 0; i< IT_KEY_LEVEL_MAX; i++)
172 void iscz1_stop (void *p)
177 /* small encoder that works with unsigneds of any length */
178 static CODEC_INLINE void iscz1_encode_int (zint d, char **dst)
180 unsigned char *bp = (unsigned char*) *dst;
184 *bp++ = (unsigned) (128 | (d & 127));
187 *bp++ = (unsigned) d;
191 /* small decoder that works with unsigneds of any length */
192 static CODEC_INLINE zint iscz1_decode_int (unsigned char **src)
198 while (((c = *(*src)++) & 128))
200 d += ((zint) (c&127) << r);
203 d += ((zint) c << r);
207 void iscz1_encode (void *vp, char **dst, const char **src)
209 struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
219 if diff is 0, then there is more ...
220 if diff is non-zero, then _may_ be more
222 memcpy (&tkey, *src, sizeof(struct it_key));
224 /* deal with leader + delta encoding .. */
226 assert(tkey.len > 0 && tkey.len <= 4);
227 for (i = 0; i < tkey.len; i++)
229 d = tkey.mem[i] - p->key.mem[i];
230 if (d || i == tkey.len-1)
231 { /* all have been equal until now, now make delta .. */
232 p->key.mem[i] = tkey.mem[i];
235 iscz1_encode_int (i + (tkey.len << 3) + 64, dst);
237 iscz1_encode_int (d, dst);
241 iscz1_encode_int (i + (tkey.len << 3), dst);
246 /* rest uses absolute encoding ... */
247 for (; i < tkey.len; i++)
249 iscz1_encode_int (tkey.mem[i], dst);
250 p->key.mem[i] = tkey.mem[i];
252 (*src) += sizeof(struct it_key);
255 void iscz1_decode (void *vp, char **dst, const char **src)
257 struct iscz1_code_info *p = (struct iscz1_code_info *) vp;
260 int leader = (int) iscz1_decode_int ((unsigned char **) src);
263 p->key.mem[i] += iscz1_decode_int ((unsigned char **) src);
265 p->key.mem[i] = iscz1_decode_int ((unsigned char **) src);
266 p->key.len = (leader >> 3) & 7;
267 while (++i < p->key.len)
268 p->key.mem[i] = iscz1_decode_int ((unsigned char **) src);
269 memcpy (*dst, &p->key, sizeof(struct it_key));
270 (*dst) += sizeof(struct it_key);
273 ISAMS_M *key_isams_m (Res res, ISAMS_M *me)
275 isams_getmethod (me);
277 me->compare_item = key_compare;
278 me->log_item = key_logdump_txt;
280 me->codec.start = iscz1_start;
281 me->codec.decode = iscz1_decode;
282 me->codec.encode = iscz1_encode;
283 me->codec.stop = iscz1_stop;
284 me->codec.reset = iscz1_reset;
286 me->debug = atoi(res_get_def (res, "isamsDebug", "0"));
291 ISAMC_M *key_isamc_m (Res res, ISAMC_M *me)
293 isamc_getmethod (me);
295 me->compare_item = key_compare;
296 me->log_item = key_logdump_txt;
298 me->codec.start = iscz1_start;
299 me->codec.decode = iscz1_decode;
300 me->codec.encode = iscz1_encode;
301 me->codec.stop = iscz1_stop;
302 me->codec.reset = iscz1_reset;
304 me->debug = atoi(res_get_def (res, "isamcDebug", "0"));
309 int key_SU_encode (int ch, char *out)
315 out[i] = 65 + (ch & 63);
334 int key_SU_decode (int *ch, const unsigned char *out)
339 for (len = 1; *out >= 65; len++, out++)
341 *ch += (*out - 65) * fact;
344 *ch += (*out - 1) * fact;
351 * indent-tabs-mode: nil
353 * vim: shiftwidth=4 tabstop=8 expandtab