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