286c2507dae17cdf801d8a7880d3b72a84e556fc
[idzebra-moved-to-github.git] / index / reckeys.c
1 /* $Id: reckeys.c,v 1.11 2006-12-05 08:14:59 adam Exp $
2    Copyright (C) 1995-2006
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
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
10 version.
11
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
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <assert.h>
27 #include <ctype.h>
28
29 #include "reckeys.h"
30 #include <yaz/nmem.h>
31 #include <yaz/xmalloc.h>
32
33 #define NEW 0
34
35 #if NEW
36 struct zebra_rec_word_entry {
37     char *buf;
38     size_t len;
39     int ord;
40     int max_seq;
41     struct zebra_rec_word_entry *next;
42     struct zebra_rec_key_entry *keys;
43     struct zebra_rec_key_entry **last_key;
44 };
45
46 struct zebra_rec_key_entry {
47     struct it_key key;
48     struct zebra_rec_key_entry *next;
49 };
50 #else
51 struct zebra_rec_key_entry {
52     char *buf;
53     size_t len;
54     struct it_key key;
55     struct zebra_rec_key_entry *next;
56 };
57 #endif
58
59 struct zebra_rec_keys_t_ {
60     size_t buf_used;
61     size_t buf_max;
62     size_t fetch_offset;
63     char *buf;
64     void *encode_handle;
65     void *decode_handle;
66     char owner_of_buffer;
67
68     NMEM nmem;
69     size_t hash_size;
70 #if NEW
71     struct zebra_rec_word_entry **entries;
72 #else
73     struct zebra_rec_key_entry **entries;
74 #endif
75 };
76
77
78 #if NEW
79 struct zebra_rec_word_entry **zebra_rec_keys_mk_hash(zebra_rec_keys_t p,
80                                                      const char *buf,
81                                                      size_t len,
82                                                      int ord)
83 {
84     int i;
85     unsigned h = ord;
86
87     for (i = 0; i<len; i++)
88         h = h * 65509 + buf[i];
89     return &p->entries[h % (unsigned) p->hash_size];
90 }
91 #else
92 struct zebra_rec_key_entry **zebra_rec_keys_mk_hash(zebra_rec_keys_t p,
93                                                     const char *buf,
94                                                     size_t len,
95                                                     const struct it_key *key)
96 {
97     unsigned h = 0;
98     size_t i;
99     int j;
100 #if 0
101     h = key->mem[key->len-1];
102 #else
103     for (i = 0; i<len; i++)
104         h = h * 65509 + buf[i];
105     for (j = 0; j<key->len; j++)
106         h = h * 65509 + CAST_ZINT_TO_INT(key->mem[j]);
107 #endif
108     return &p->entries[h % (unsigned) p->hash_size];
109 }
110 #endif
111
112 static void init_hash(zebra_rec_keys_t p)
113 {
114     p->entries = 0;
115     nmem_reset(p->nmem);
116     if (p->hash_size)
117     {
118         size_t i;
119         p->entries = nmem_malloc(p->nmem, p->hash_size * sizeof(*p->entries));
120         for (i = 0; i<p->hash_size; i++)
121             p->entries[i] = 0;
122     }
123 }
124
125 zebra_rec_keys_t zebra_rec_keys_open(void)
126 {
127     zebra_rec_keys_t p = xmalloc(sizeof(*p));
128     p->buf_used = 0;
129     p->buf_max = 0;
130     p->fetch_offset = 0;
131     p->buf = 0;
132     p->owner_of_buffer = 1;
133     p->encode_handle = iscz1_start();
134     p->decode_handle = iscz1_start(); 
135
136     p->nmem = nmem_create();
137     p->hash_size = 32767;
138     p->entries = 0;
139
140     init_hash(p);
141
142     return p;
143 }
144
145 void zebra_rec_keys_set_buf(zebra_rec_keys_t p, char *buf, size_t sz,
146                             int copy_buf)
147 {
148     if (p->owner_of_buffer)
149         xfree(p->buf);
150     p->buf_used = sz;
151     p->buf_max = sz;
152     if (!copy_buf)
153     {
154         p->buf = buf;
155     }
156     else
157     {
158         if (!sz)
159             p->buf = 0;
160         else
161         {
162             p->buf = xmalloc(sz);
163             memcpy(p->buf, buf, sz);
164         }
165     }
166     p->owner_of_buffer = copy_buf;
167 }
168         
169 void zebra_rec_keys_get_buf(zebra_rec_keys_t p, char **buf, size_t *sz)
170 {
171     *buf = p->buf;
172     *sz = p->buf_used;
173
174     p->buf = 0;
175     p->buf_max = 0;
176     p->buf_used = 0;
177 }
178
179 void zebra_rec_keys_close(zebra_rec_keys_t p)
180 {
181     if (!p)
182         return;
183     
184     if (p->owner_of_buffer)
185         xfree(p->buf);
186     if (p->encode_handle)
187         iscz1_stop(p->encode_handle);
188     if (p->decode_handle)
189         iscz1_stop(p->decode_handle);
190     nmem_destroy(p->nmem);
191     xfree(p);
192 }
193
194 #if NEW
195 void zebra_rec_keys_write(zebra_rec_keys_t keys, 
196                           const char *str, size_t slen,
197                           const struct it_key *key)
198 {
199     char *dst;
200     const char *src = (char*) key;
201     
202     struct zebra_rec_word_entry **wep;
203     struct zebra_rec_key_entry **kep;
204     int ord = key->mem[0];
205     int seq = key->mem[key->len-1];
206     
207     assert(keys->owner_of_buffer);
208
209     wep = zebra_rec_keys_mk_hash(keys, str, slen, ord);
210
211     while (*wep)
212     {
213         struct zebra_rec_word_entry *e = *wep;
214         if (ord == e->ord && slen == e->len && !memcmp(str, e->buf, slen))
215             break;
216         wep = &(*wep)->next;
217     }
218     
219     if (!*wep)
220     {
221         *wep = nmem_malloc(keys->nmem, sizeof(**wep));
222         (*wep)->buf = nmem_malloc(keys->nmem, slen);
223         memcpy((*wep)->buf, str, slen);
224         (*wep)->len = slen;
225         (*wep)->ord = ord;
226         (*wep)->next = 0;
227         (*wep)->keys = 0;
228         (*wep)->max_seq = 0;
229         (*wep)->last_key = &(*wep)->keys;
230     }
231     if (seq > (*wep)->max_seq)
232         kep = (*wep)->last_key;
233     else
234     {
235         kep = &(*wep)->keys;
236         while (*kep)
237         {
238             if (!key_compare(key, &(*kep)->key))
239                 return;
240             kep = &(*kep)->next;
241         }
242     }
243     *kep = nmem_malloc(keys->nmem, sizeof(**kep));
244     (*kep)->next = 0;
245     (*wep)->last_key = &(*kep)->next;
246     memcpy(&(*kep)->key, key, sizeof(*key));
247     if (seq > (*wep)->max_seq)
248     {
249         (*wep)->max_seq = seq;
250     }
251 }
252 #else
253 int zebra_rec_keys_add_hash(zebra_rec_keys_t keys, 
254                             const char *str, size_t slen,
255                             const struct it_key *key)
256 {
257     struct zebra_rec_key_entry **kep_first
258         = zebra_rec_keys_mk_hash(keys, str, slen, key);
259     struct zebra_rec_key_entry **kep = kep_first;
260     while (*kep)
261     {
262         struct zebra_rec_key_entry *e = *kep;
263         if (slen == e->len && !memcmp(str, e->buf, slen) &&
264             !key_compare(key, &e->key))
265         {
266             *kep = (*kep)->next; /* out of queue */
267             e->next = *kep_first; /* move to front */
268             *kep_first = e;
269
270             return 0;
271         }
272         kep = &(*kep)->next;
273     }
274     *kep = nmem_malloc(keys->nmem, sizeof(**kep));
275     (*kep)->next = 0;
276     (*kep)->len = slen;
277     memcpy(&(*kep)->key, key, sizeof(*key));
278     (*kep)->buf = nmem_malloc(keys->nmem, slen);
279     memcpy((*kep)->buf, str, slen);
280     return 1;
281 }
282
283 void zebra_rec_keys_write(zebra_rec_keys_t keys, 
284                           const char *str, size_t slen,
285                           const struct it_key *key)
286 {
287     char *dst;
288     const char *src = (char*) key;
289     
290     assert(keys->owner_of_buffer);
291
292 #if 1
293     if (!zebra_rec_keys_add_hash(keys, str, slen, key))
294     {
295 #if 0
296         yaz_log(YLOG_LOG, "dup key slen=%d %.*s "
297                 "ord=" ZINT_FORMAT " seq=" ZINT_FORMAT,
298                 slen, slen, str, key->mem[0], key->mem[key->len-1]);
299 #endif
300         return;  /* key already there . Omit it */
301     }
302 #endif
303     if (keys->buf_used+1024 > keys->buf_max)
304     {
305         char *b = (char *) xmalloc (keys->buf_max += 128000);
306         if (keys->buf_used > 0)
307             memcpy (b, keys->buf, keys->buf_used);
308         xfree (keys->buf);
309         keys->buf = b;
310     }
311     dst = keys->buf + keys->buf_used;
312
313     iscz1_encode(keys->encode_handle, &dst, &src);
314
315     memcpy (dst, str, slen);
316     dst += slen;
317     *dst++ = '\0';
318     keys->buf_used = dst - keys->buf;
319 }
320 #endif
321
322 void zebra_rec_keys_reset(zebra_rec_keys_t keys)
323 {
324     assert(keys);
325     keys->buf_used = 0;
326     
327     iscz1_reset(keys->encode_handle);
328
329     init_hash(keys);
330 }
331
332 int zebra_rec_keys_rewind(zebra_rec_keys_t keys)
333 {
334     assert(keys);
335     iscz1_reset(keys->decode_handle);
336
337 #if NEW
338     if (keys->buf_used == 0)
339     {
340         size_t i;
341         for (i = 0; i<keys->hash_size; i++)
342         {
343             struct zebra_rec_word_entry *we = keys->entries[i];
344             for (; we; we = we->next)
345             {
346                 struct zebra_rec_key_entry *ke = we->keys;
347                 for (; ke; ke = ke->next)
348                 {
349                     const char *src = (char*) &ke->key;
350                     char *dst;
351                     if (keys->buf_used+1024 > keys->buf_max)
352                     {
353                         char *b = (char *) xmalloc (keys->buf_max += 128000);
354                         if (keys->buf_used > 0)
355                             memcpy (b, keys->buf, keys->buf_used);
356                         xfree (keys->buf);
357                         keys->buf = b;
358                     }
359                     
360                     dst = keys->buf + keys->buf_used;
361                     
362                     iscz1_encode(keys->encode_handle, &dst, &src);
363                     
364                     memcpy (dst, we->buf, we->len);
365                     dst += we->len;
366                     *dst++ = '\0';
367                     keys->buf_used = dst - keys->buf;
368                 }
369             }
370         }
371     }
372 #endif
373
374     keys->fetch_offset = 0;
375     if (keys->buf_used == 0)
376         return 0;
377     return 1;
378 }
379
380 int zebra_rec_keys_empty(zebra_rec_keys_t keys)
381 {
382     if (keys->buf_used == 0)
383         return 1;
384     return 0;
385 }
386
387 int zebra_rec_keys_read(zebra_rec_keys_t keys,
388                         const char **str, size_t *slen,
389                         struct it_key *key)
390 {
391     assert(keys);
392     if (keys->fetch_offset == keys->buf_used)
393         return 0;
394     else
395     {
396         const char *src = keys->buf + keys->fetch_offset;
397         char *dst = (char*) key;
398         
399         assert (keys->fetch_offset < keys->buf_used);
400
401         /* store the destination key */
402         iscz1_decode(keys->decode_handle, &dst, &src);
403         
404         /* store pointer to string and length of it */
405         *str = src;
406         *slen = strlen(src);
407         src += *slen + 1;
408         
409         keys->fetch_offset = src - keys->buf;
410     }
411     return 1;
412 }
413 /*
414  * Local variables:
415  * c-basic-offset: 4
416  * indent-tabs-mode: nil
417  * End:
418  * vim: shiftwidth=4 tabstop=8 expandtab
419  */
420