Get rid of SYSNO which is zint anyway. Removed various prototypes
[idzebra-moved-to-github.git] / index / reckeys.c
1 /* $Id: reckeys.c,v 1.10 2006-11-21 22:17:49 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 struct zebra_rec_key_entry {
34     char *buf;
35     size_t len;
36     struct it_key key;
37     struct zebra_rec_key_entry *next;
38 };
39
40 struct zebra_rec_keys_t_ {
41     size_t buf_used;
42     size_t buf_max;
43     size_t fetch_offset;
44     char *buf;
45     void *encode_handle;
46     void *decode_handle;
47     char owner_of_buffer;
48
49     NMEM nmem;
50     size_t hash_size;
51     struct zebra_rec_key_entry **entries; 
52 };
53
54
55 struct zebra_rec_key_entry **zebra_rec_keys_mk_hash(zebra_rec_keys_t p,
56                                                     const char *buf,
57                                                     size_t len,
58                                                     const struct it_key *key)
59 {
60     unsigned h = 0;
61     size_t i;
62     int j;
63 #if 0
64     h = key->mem[key->len-1];
65 #else
66     for (i = 0; i<len; i++)
67         h = h * 65509 + buf[i];
68     for (j = 0; j<key->len; j++)
69         h = h * 65509 + CAST_ZINT_TO_INT(key->mem[j]);
70 #endif
71     return &p->entries[h % (unsigned) p->hash_size];
72 }
73
74 static void init_hash(zebra_rec_keys_t p)
75 {
76     p->entries = 0;
77     nmem_reset(p->nmem);
78     if (p->hash_size)
79     {
80         size_t i;
81         p->entries = nmem_malloc(p->nmem, p->hash_size * sizeof(*p->entries));
82         for (i = 0; i<p->hash_size; i++)
83             p->entries[i] = 0;
84     }
85 }
86
87 zebra_rec_keys_t zebra_rec_keys_open(void)
88 {
89     zebra_rec_keys_t p = xmalloc(sizeof(*p));
90     p->buf_used = 0;
91     p->buf_max = 0;
92     p->fetch_offset = 0;
93     p->buf = 0;
94     p->owner_of_buffer = 1;
95     p->encode_handle = iscz1_start();
96     p->decode_handle = iscz1_start(); 
97
98     p->nmem = nmem_create();
99     p->hash_size = 32767;
100     p->entries = 0;
101
102     init_hash(p);
103
104     return p;
105 }
106
107 void zebra_rec_keys_set_buf(zebra_rec_keys_t p, char *buf, size_t sz,
108                             int copy_buf)
109 {
110     if (p->owner_of_buffer)
111         xfree(p->buf);
112     p->buf_used = sz;
113     p->buf_max = sz;
114     if (!copy_buf)
115     {
116         p->buf = buf;
117     }
118     else
119     {
120         if (!sz)
121             p->buf = 0;
122         else
123         {
124             p->buf = xmalloc(sz);
125             memcpy(p->buf, buf, sz);
126         }
127     }
128     p->owner_of_buffer = copy_buf;
129 }
130         
131 void zebra_rec_keys_get_buf(zebra_rec_keys_t p, char **buf, size_t *sz)
132 {
133     *buf = p->buf;
134     *sz = p->buf_used;
135
136     p->buf = 0;
137     p->buf_max = 0;
138     p->buf_used = 0;
139 }
140
141 void zebra_rec_keys_close(zebra_rec_keys_t p)
142 {
143     if (!p)
144         return;
145     
146     if (p->owner_of_buffer)
147         xfree(p->buf);
148     if (p->encode_handle)
149         iscz1_stop(p->encode_handle);
150     if (p->decode_handle)
151         iscz1_stop(p->decode_handle);
152     nmem_destroy(p->nmem);
153     xfree(p);
154 }
155
156 int zebra_rec_keys_add_hash(zebra_rec_keys_t keys, 
157                             const char *str, size_t slen,
158                             const struct it_key *key)
159 {
160     struct zebra_rec_key_entry **kep_first
161         = zebra_rec_keys_mk_hash(keys, str, slen, key);
162     struct zebra_rec_key_entry **kep = kep_first;
163     while (*kep)
164     {
165         struct zebra_rec_key_entry *e = *kep;
166         if (slen == e->len && !memcmp(str, e->buf, slen) &&
167             !key_compare(key, &e->key))
168         {
169             *kep = (*kep)->next; /* out of queue */
170             e->next = *kep_first; /* move to front */
171             *kep_first = e;
172
173             return 0;
174         }
175         kep = &(*kep)->next;
176     }
177     *kep = nmem_malloc(keys->nmem, sizeof(**kep));
178     (*kep)->next = 0;
179     (*kep)->len = slen;
180     memcpy(&(*kep)->key, key, sizeof(*key));
181     (*kep)->buf = nmem_malloc(keys->nmem, slen);
182     memcpy((*kep)->buf, str, slen);
183     return 1;
184 }
185
186 void zebra_rec_keys_write(zebra_rec_keys_t keys, 
187                           const char *str, size_t slen,
188                           const struct it_key *key)
189 {
190     char *dst;
191     const char *src = (char*) key;
192     
193     assert(keys->owner_of_buffer);
194
195 #if 1
196     if (!zebra_rec_keys_add_hash(keys, str, slen, key))
197     {
198 #if 0
199         yaz_log(YLOG_LOG, "dup key slen=%d %.*s "
200                 "ord=" ZINT_FORMAT " seq=" ZINT_FORMAT,
201                 slen, slen, str, key->mem[0], key->mem[key->len-1]);
202 #endif
203         return;  /* key already there . Omit it */
204     }
205 #endif
206     if (keys->buf_used+1024 > keys->buf_max)
207     {
208         char *b = (char *) xmalloc (keys->buf_max += 128000);
209         if (keys->buf_used > 0)
210             memcpy (b, keys->buf, keys->buf_used);
211         xfree (keys->buf);
212         keys->buf = b;
213     }
214     dst = keys->buf + keys->buf_used;
215
216     iscz1_encode(keys->encode_handle, &dst, &src);
217
218     memcpy (dst, str, slen);
219     dst += slen;
220     *dst++ = '\0';
221     keys->buf_used = dst - keys->buf;
222 }
223
224 void zebra_rec_keys_reset(zebra_rec_keys_t keys)
225 {
226     assert(keys);
227     keys->buf_used = 0;
228     
229     iscz1_reset(keys->encode_handle);
230
231     init_hash(keys);
232
233 }
234
235 int zebra_rec_keys_rewind(zebra_rec_keys_t keys)
236 {
237     assert(keys);
238     iscz1_reset(keys->decode_handle);
239     keys->fetch_offset = 0;
240     if (keys->buf_used == 0)
241         return 0;
242     return 1;
243 }
244
245 int zebra_rec_keys_empty(zebra_rec_keys_t keys)
246 {
247     if (keys->buf_used == 0)
248         return 1;
249     return 0;
250 }
251
252 int zebra_rec_keys_read(zebra_rec_keys_t keys,
253                         const char **str, size_t *slen,
254                         struct it_key *key)
255 {
256     assert(keys);
257     if (keys->fetch_offset == keys->buf_used)
258         return 0;
259     else
260     {
261         const char *src = keys->buf + keys->fetch_offset;
262         char *dst = (char*) key;
263         
264         assert (keys->fetch_offset < keys->buf_used);
265
266         /* store the destination key */
267         iscz1_decode(keys->decode_handle, &dst, &src);
268         
269         /* store pointer to string and length of it */
270         *str = src;
271         *slen = strlen(src);
272         src += *slen + 1;
273         
274         keys->fetch_offset = src - keys->buf;
275     }
276     return 1;
277 }
278 /*
279  * Local variables:
280  * c-basic-offset: 4
281  * indent-tabs-mode: nil
282  * End:
283  * vim: shiftwidth=4 tabstop=8 expandtab
284  */
285