IDZEBRA  2.1.2
recindex.c
Go to the documentation of this file.
1 /* This file is part of the Zebra server.
2  Copyright (C) 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 #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 
35 struct recindex {
36  char *index_fname;
40 };
41 
43  zint next; /* first block of record info / next free entry */
44  int size; /* size of record or 0 if free entry */
45 } ent;
46 
47 
48 static 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 
68 int 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 
82 void *rect_code_start(void)
83 {
84  return 0;
85 }
86 
87 void 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 
106 void 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 
125 void rect_code_reset(void *p)
126 {
127 }
128 
129 void rect_code_stop(void *p)
130 {
131 }
132 
133 
134 recindex_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 
176 static 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)
187  bf_close(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 
208 ZEBRA_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 
225 int 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 
286  int no;
288  void *buf;
289  int itemsize;
291 };
292 
293 int 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 
void * rect_code_start(void)
Definition: recindex.c:82
void * buf
Definition: recindex.c:288
void isamb_dump(ISAMB b, ISAM_P pos, void(*pr)(const char *str))
Definition: isamb.c:1496
static void rect_log_item(int level, const void *b, const char *txt)
Definition: recindex.c:48
ISAMB isamb
Definition: recindex.c:38
#define ZEBRA_OK
Definition: util.h:82
zint ISAM_P
Definition: isamc.h:28
void rect_encode(void *p, char **dst, const char **src)
Definition: recindex.c:87
int bt_code_read(void *vp, char **dst, int *insertMode)
Definition: recindex.c:293
#define ZEBRA_FAIL
Definition: util.h:81
int size
Definition: recindex.c:44
int isamb_pp_forward(ISAMB_PP pp, void *buf, const void *untilbuf)
Definition: isamb.c:1523
void isamb_pp_close(ISAMB_PP pp)
Definition: isamb.c:1428
void(* reset)(void *p)
Definition: isam-codec.h:28
int rect_compare(const void *a, const void *b)
Definition: recindex.c:68
int recindex_read_indx(recindex_t p, zint sysno, void *buf, int itemsize, int ignoreError)
Definition: recindex.c:225
void(* decode)(void *p, char **dst, const char **src)
Definition: isam-codec.h:26
void recindex_close(recindex_t p)
closes record index handle
Definition: recindex.c:182
int recindex_read_head(recindex_t p, void *buf)
Definition: recindex.c:198
zint next
Definition: recindex.c:43
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:204
#define CAST_ZINT_TO_INT(x)
Definition: util.h:96
void(* log_item)(int logmask, const void *p, const char *txt)
Definition: isamc.h:44
void zebra_zint_decode(const char **src, zint *pos)
Definition: zint.c:39
const char * recindex_get_fname(recindex_t p)
Definition: recindex.c:203
ZEBRA_RES recindex_write_head(recindex_t p, const void *buf, size_t len)
Definition: recindex.c:208
ISAMB_PP isamb_pp_open(ISAMB isamb, ISAM_P pos, int scope)
Definition: isamb.c:1386
#define RIDX_CHUNK
Definition: recindex.c:32
void bf_close(BFile bf)
closes a Block file (may call exit)
Definition: bfile.c:151
Definition: isamb.c:94
ISAM_CODEC codec
Definition: isamc.h:46
void isamb_merge(ISAMB b, ISAM_P *pos, ISAMC_I *data)
Definition: isamb.c:1265
void zebra_zint_encode(char **dst, zint pos)
Definition: zint.c:26
void *(* start)(void)
Definition: isam-codec.h:24
Definition: recindex.c:42
int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
read from block file (may call exit)
Definition: bfile.c:319
void(* stop)(void *p)
Definition: isam-codec.h:25
long zint
Zebra integer.
Definition: util.h:66
int(* compare_item)(const void *a, const void *b)
Definition: isamc.h:43
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:346
ISAM_P isam_p
Definition: recindex.c:39
BFile index_BFile
Definition: recindex.c:37
void rect_code_stop(void *p)
Definition: recindex.c:129
recindex_t recindex_open(BFiles bfs, int rw, int use_isamb)
opens record index handle
Definition: recindex.c:134
char * index_fname
Definition: recindex.c:36
zint isamb_get_root_ptr(ISAMB b)
Definition: isamb.c:1667
void rect_decode(void *p, char **dst, const char **src)
Definition: recindex.c:106
void isamb_close(ISAMB isamb)
Definition: isamb.c:454
void isamb_set_root_ptr(ISAMB b, zint root_ptr)
Definition: isamb.c:1672
short ZEBRA_RES
Common return type for Zebra API.
Definition: util.h:80
void rect_code_reset(void *p)
Definition: recindex.c:125
struct record_index_entry ent
BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag)
opens and returns a Block file handle
Definition: bfile.c:261
void(* encode)(void *p, char **dst, const char **src)
Definition: isam-codec.h:27
static void log_pr(const char *txt)
Definition: recindex.c:176
void recindex_write_indx(recindex_t p, zint sysno, void *buf, int itemsize)
Definition: recindex.c:312
#define ZINT_FORMAT
Definition: util.h:72