IDZEBRA 2.2.8
recindex.c
Go to the documentation of this file.
1/* This file is part of the Zebra server.
2 Copyright (C) Index Data
3
4Zebra is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 2, or (at your option) any later
7version.
8
9Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18*/
19
20#if HAVE_CONFIG_H
21#include <config.h>
22#endif
23#include <stdio.h>
24#include <stdlib.h>
25#include <assert.h>
26#include <string.h>
27
28#include <idzebra/isamb.h>
29#include <yaz/yaz-util.h>
30#include "recindex.h"
31
32#define RIDX_CHUNK 128
33
34
41
43 zint next; /* first block of record info / next free entry */
44 int size; /* size of record or 0 if free entry */
46
47
48static void rect_log_item(int level, const void *b, const char *txt)
49{
50 zint sys;
51 int len;
52
53
54 memcpy(&sys, b, sizeof(sys));
55 len = ((const char *) b)[sizeof(sys)];
56
57 if (len == sizeof(struct record_index_entry))
58 {
59 memcpy(&ent, (const char *)b + sizeof(sys) + 1, len);
60 yaz_log(YLOG_LOG, "%s " ZINT_FORMAT " next=" ZINT_FORMAT " sz=%d", txt, sys,
61 ent.next, ent.size);
62
63 }
64 else
65 yaz_log(YLOG_LOG, "%s " ZINT_FORMAT, txt, sys);
66}
67
68int rect_compare(const void *a, const void *b)
69{
70 zint s_a, s_b;
71
72 memcpy(&s_a, a, sizeof(s_a));
73 memcpy(&s_b, b, sizeof(s_b));
74
75 if (s_a > s_b)
76 return 1;
77 else if (s_a < s_b)
78 return -1;
79 return 0;
80}
81
82void *rect_code_start(void)
83{
84 return 0;
85}
86
87void rect_encode(void *p, char **dst, const char **src)
88{
89 zint sys;
90 int len;
91
92 memcpy(&sys, *src, sizeof(sys));
93 zebra_zint_encode(dst, sys);
94 (*src) += sizeof(sys);
95
96 len = **src;
97 **dst = len;
98 (*src)++;
99 (*dst)++;
100
101 memcpy(*dst, *src, len);
102 *dst += len;
103 *src += len;
104}
105
106void rect_decode(void *p, char **dst, const char **src)
107{
108 zint sys;
109 int len;
110
111 zebra_zint_decode(src, &sys);
112 memcpy(*dst, &sys, sizeof(sys));
113 *dst += sizeof(sys);
114
115 len = **src;
116 **dst = len;
117 (*src)++;
118 (*dst)++;
119
120 memcpy(*dst, *src, len);
121 *dst += len;
122 *src += len;
123}
124
125void rect_code_reset(void *p)
126{
127}
128
129void rect_code_stop(void *p)
130{
131}
132
133
134recindex_t recindex_open(BFiles bfs, int rw, int use_isamb)
135{
136 recindex_t p = xmalloc(sizeof(*p));
137 p->index_BFile = 0;
138 p->isamb = 0;
139
140 p->index_fname = "reci";
141 p->index_BFile = bf_open(bfs, p->index_fname, RIDX_CHUNK, rw);
142 if (p->index_BFile == NULL)
143 {
144 yaz_log(YLOG_FATAL|YLOG_ERRNO, "open %s", p->index_fname);
145 xfree(p);
146 return 0;
147 }
148
149 if (use_isamb)
150 {
151 int isam_block_size = 4096;
152 ISAMC_M method;
153
154 method.compare_item = rect_compare;
155 method.log_item = rect_log_item;
156 method.codec.start = rect_code_start;
157 method.codec.encode = rect_encode;
158 method.codec.decode = rect_decode;
159 method.codec.reset = rect_code_reset;
160 method.codec.stop = rect_code_stop;
161
162 p->index_fname = "rect";
163 p->isamb = isamb_open2(bfs, p->index_fname, rw, &method,
164 /* cache */ 0,
165 /* no_cat */ 1, &isam_block_size,
166 /* use_root_ptr */ 1);
167
168 p->isam_p = 0;
169 if (p->isamb)
171
172 }
173 return p;
174}
175
176static void log_pr(const char *txt)
177{
178 yaz_log(YLOG_LOG, "%s", txt);
179}
180
181
183{
184 if (p)
185 {
186 if (p->index_BFile)
188 if (p->isamb)
189 {
191 isamb_dump(p->isamb, p->isam_p, log_pr);
192 isamb_close(p->isamb);
193 }
194 xfree(p);
195 }
196}
197
199{
200 return bf_read(p->index_BFile, 0, 0, 0, buf);
201}
202
204{
205 return p->index_fname;
206}
207
208ZEBRA_RES recindex_write_head(recindex_t p, const void *buf, size_t len)
209{
210 int r;
211
212 assert(p);
213
214 assert(p->index_BFile);
215
216 r = bf_write(p->index_BFile, 0, 0, len, buf);
217 if (r)
218 {
219 yaz_log(YLOG_FATAL|YLOG_ERRNO, "write head of %s", p->index_fname);
220 return ZEBRA_FAIL;
221 }
222 return ZEBRA_OK;
223}
224
225int recindex_read_indx(recindex_t p, zint sysno, void *buf, int itemsize,
226 int ignoreError)
227{
228 int r = 0;
229 if (p->isamb)
230 {
231 if (p->isam_p)
232 {
233 char item[256];
234 char *st = item;
235 char untilbuf[sizeof(zint) + 1];
236
237 ISAMB_PP isam_pp = isamb_pp_open(p->isamb, p->isam_p, 1);
238
239 memcpy(untilbuf, &sysno, sizeof(sysno));
240 untilbuf[sizeof(sysno)] = 0;
241 r = isamb_pp_forward(isam_pp, st, untilbuf);
242
243 isamb_pp_close(isam_pp);
244 if (!r)
245 return 0;
246
247 if (item[sizeof(sysno)] != itemsize)
248 {
249 yaz_log(YLOG_WARN, "unexpected entry size %d != %d",
250 item[sizeof(sysno)], itemsize);
251 return 0;
252 }
253 memcpy(buf, item + sizeof(sysno) + 1, itemsize);
254 }
255 }
256 else
257 {
258 zint pos = (sysno-1)*itemsize;
259 int off = CAST_ZINT_TO_INT(pos%RIDX_CHUNK);
260 int sz1 = RIDX_CHUNK - off; /* sz1 is size of buffer to read.. */
261
262 if (sz1 > itemsize)
263 sz1 = itemsize; /* no more than itemsize bytes */
264
265 r = bf_read(p->index_BFile, 1+pos/RIDX_CHUNK, off, sz1, buf);
266 if (r == 1 && sz1 < itemsize) /* boundary? - must read second part */
267 r = bf_read(p->index_BFile, 2+pos/RIDX_CHUNK, 0, itemsize - sz1,
268 (char*) buf + sz1);
269 if (r != 1 && !ignoreError)
270 {
271 yaz_log(YLOG_FATAL|YLOG_ERRNO, "read in %s at pos %ld",
272 p->index_fname, (long) pos);
273 }
274 }
275#if 0
276 {
277 struct record_index_entry *ep = buf;
278 yaz_log(YLOG_LOG, "read r=%d sysno=" ZINT_FORMAT " next=" ZINT_FORMAT
279 " sz=%d", r, sysno, ep->next, ep->size);
280 }
281#endif
282 return r;
283}
284
292
293int bt_code_read(void *vp, char **dst, int *insertMode)
294{
295 struct code_read_data *s = (struct code_read_data *) vp;
296
297 if (s->no == 0)
298 return 0;
299
300 (s->no)--;
301
302 memcpy(*dst, &s->sysno, sizeof(zint));
303 *dst += sizeof(zint);
304 **dst = s->itemsize;
305 (*dst)++;
306 memcpy(*dst, s->buf, s->itemsize);
307 *dst += s->itemsize;
308 *insertMode = s->insert_flag;
309 return 1;
310}
311
313{
314#if 0
315 yaz_log(YLOG_LOG, "write_indx sysno=" ZINT_FORMAT, sysno);
316#endif
317 if (p->isamb)
318 {
319 struct code_read_data input;
320 ISAMC_I isamc_i;
321
322 input.sysno = sysno;
323 input.buf = buf;
324 input.itemsize = itemsize;
325
326 isamc_i.clientData = &input;
327 isamc_i.read_item = bt_code_read;
328
329 input.no = 1;
330 input.insert_flag = 2;
331 isamb_merge(p->isamb, &p->isam_p, &isamc_i);
332 }
333 else
334 {
335 zint pos = (sysno-1)*itemsize;
336 int off = CAST_ZINT_TO_INT(pos%RIDX_CHUNK);
337 int sz1 = RIDX_CHUNK - off; /* sz1 is size of buffer to read.. */
338
339 if (sz1 > itemsize)
340 sz1 = itemsize; /* no more than itemsize bytes */
341
342 bf_write(p->index_BFile, 1+pos/RIDX_CHUNK, off, sz1, buf);
343 if (sz1 < itemsize) /* boundary? must write second part */
344 bf_write(p->index_BFile, 2+pos/RIDX_CHUNK, 0, itemsize - sz1,
345 (char*) buf + sz1);
346 }
347}
348
349
350/*
351 * Local variables:
352 * c-basic-offset: 4
353 * c-file-style: "Stroustrup"
354 * indent-tabs-mode: nil
355 * End:
356 * vim: shiftwidth=4 tabstop=8 expandtab
357 */
358
int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
read from block file (may call exit)
Definition bfile.c:205
void bf_close(BFile bf)
closes a Block file (may call exit)
Definition bfile.c:139
BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag)
opens and returns a Block file handle
Definition bfile.c:150
int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf)
writes block of bytes to file (may call exit)
Definition bfile.c:232
ISAMB_PP isamb_pp_open(ISAMB isamb, ISAM_P pos, int scope)
Definition isamb.c:1387
zint isamb_get_root_ptr(ISAMB b)
Definition isamb.c:1669
void isamb_dump(ISAMB b, ISAM_P pos, void(*pr)(const char *str))
Definition isamb.c:1498
void isamb_close(ISAMB isamb)
Definition isamb.c:455
void isamb_set_root_ptr(ISAMB b, zint root_ptr)
Definition isamb.c:1674
int isamb_pp_forward(ISAMB_PP pp, void *buf, const void *untilbuf)
Definition isamb.c:1525
ISAMB isamb_open2(BFiles bfs, const char *name, int writeflag, ISAMC_M *method, int cache, int no_cat, int *sizes, int use_root_ptr)
Definition isamb.c:205
void isamb_pp_close(ISAMB_PP pp)
Definition isamb.c:1429
void isamb_merge(ISAMB b, ISAM_P *pos, ISAMC_I *data)
Definition isamb.c:1266
zint ISAM_P
Definition isamc.h:28
void rect_code_reset(void *p)
Definition recindex.c:125
int bt_code_read(void *vp, char **dst, int *insertMode)
Definition recindex.c:293
int recindex_read_indx(recindex_t p, zint sysno, void *buf, int itemsize, int ignoreError)
Definition recindex.c:225
struct record_index_entry ent
void * rect_code_start(void)
Definition recindex.c:82
void recindex_write_indx(recindex_t p, zint sysno, void *buf, int itemsize)
Definition recindex.c:312
void rect_encode(void *p, char **dst, const char **src)
Definition recindex.c:87
const char * recindex_get_fname(recindex_t p)
Definition recindex.c:203
static void rect_log_item(int level, const void *b, const char *txt)
Definition recindex.c:48
recindex_t recindex_open(BFiles bfs, int rw, int use_isamb)
opens record index handle
Definition recindex.c:134
static void log_pr(const char *txt)
Definition recindex.c:176
#define RIDX_CHUNK
Definition recindex.c:32
void rect_decode(void *p, char **dst, const char **src)
Definition recindex.c:106
void recindex_close(recindex_t p)
closes record index handle
Definition recindex.c:182
void rect_code_stop(void *p)
Definition recindex.c:129
int rect_compare(const void *a, const void *b)
Definition recindex.c:68
ZEBRA_RES recindex_write_head(recindex_t p, const void *buf, size_t len)
Definition recindex.c:208
int recindex_read_head(recindex_t p, void *buf)
Definition recindex.c:198
int(* compare_item)(const void *a, const void *b)
Definition isamc.h:43
ISAM_CODEC codec
Definition isamc.h:46
void(* log_item)(int logmask, const void *p, const char *txt)
Definition isamc.h:44
void(* decode)(void *p, char **dst, const char **src)
Definition isam-codec.h:26
void(* stop)(void *p)
Definition isam-codec.h:25
void *(* start)(void)
Definition isam-codec.h:24
void(* encode)(void *p, char **dst, const char **src)
Definition isam-codec.h:27
void(* reset)(void *p)
Definition isam-codec.h:28
BFile index_BFile
Definition recindex.c:37
ISAM_P isam_p
Definition recindex.c:39
char * index_fname
Definition recindex.c:36
ISAMB isamb
Definition recindex.c:38
Definition recindex.c:42
int size
Definition recindex.c:44
zint next
Definition recindex.c:43
long zint
Zebra integer.
Definition util.h:66
void zebra_zint_decode(const char **src, zint *pos)
Definition zint.c:39
#define ZEBRA_FAIL
Definition util.h:81
#define ZINT_FORMAT
Definition util.h:72
void zebra_zint_encode(char **dst, zint pos)
Definition zint.c:26
#define CAST_ZINT_TO_INT(x)
Definition util.h:96
#define ZEBRA_OK
Definition util.h:82
short ZEBRA_RES
Common return type for Zebra API.
Definition util.h:80