IDZEBRA  2.2.7
isamc.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 /*
21  * TODO:
22  * Reduction to lower categories in isamc_merge
23  */
24 #if HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 #include <stdlib.h>
28 #include <assert.h>
29 #include <string.h>
30 #include <stdio.h>
31 
32 #include <yaz/log.h>
33 #include <yaz/snprintf.h>
34 #include <yaz/xmalloc.h>
35 #include "isamc-p.h"
36 
37 static void flush_block (ISAMC is, int cat);
38 static void release_fc (ISAMC is, int cat);
39 static void init_fc (ISAMC is, int cat);
40 
41 #define ISAMC_FREELIST_CHUNK 0
42 
43 #define SMALL_TEST 0
44 
46 {
47 
48  static struct ISAMC_filecat_s def_cat[] = {
49 #if SMALL_TEST
50  { 32, 28, 0, 3 },
51  { 64, 54, 30, 0 },
52 #else
53  { 64, 56, 40, 5 },
54  { 128, 120, 100, 10 },
55  { 512, 490, 350, 10 },
56  { 2048, 1900, 1700, 10 },
57  { 8192, 8000, 7900, 10 },
58  { 32768, 32000, 31000, 0 },
59 #endif
60  };
61  m->filecat = def_cat;
62 
63  m->codec.start = NULL;
64  m->codec.decode = NULL;
65  m->codec.encode = NULL;
66  m->codec.stop = NULL;
67  m->codec.reset = NULL;
68 
69  m->compare_item = NULL;
70  m->log_item = NULL;
71 
72  m->debug = 1;
73 
74  m->max_blocks_mem = 10;
75 }
76 
77 ISAMC isamc_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method)
78 {
79  ISAMC is;
80  ISAMC_filecat filecat;
81  int i = 0;
82  int max_buf_size = 0;
83 
84  is = (ISAMC) xmalloc (sizeof(*is));
85 
86  is->method = (ISAMC_M *) xmalloc (sizeof(*is->method));
87  memcpy (is->method, method, sizeof(*method));
88  filecat = is->method->filecat;
89  assert (filecat);
90 
91  /* determine number of block categories */
92  if (is->method->debug)
93  yaz_log(YLOG_LOG, "isc: bsize ifill mfill mblocks");
94  do
95  {
96  if (is->method->debug)
97  yaz_log (YLOG_LOG, "isc:%6d %6d %6d %6d",
98  filecat[i].bsize, filecat[i].ifill,
99  filecat[i].mfill, filecat[i].mblocks);
100  if (max_buf_size < filecat[i].mblocks * filecat[i].bsize)
101  max_buf_size = filecat[i].mblocks * filecat[i].bsize;
102  } while (filecat[i++].mblocks);
103  is->no_files = i;
104  is->max_cat = --i;
105  /* max_buf_size is the larget buffer to be used during merge */
106  max_buf_size = (1 + max_buf_size / filecat[i].bsize) * filecat[i].bsize;
107  if (max_buf_size < (1+is->method->max_blocks_mem) * filecat[i].bsize)
108  max_buf_size = (1+is->method->max_blocks_mem) * filecat[i].bsize;
109  if (is->method->debug)
110  yaz_log (YLOG_LOG, "isc: max_buf_size %d", max_buf_size);
111 
112  assert (is->no_files > 0);
113  is->files = (ISAMC_file) xmalloc (sizeof(*is->files)*is->no_files);
114  if (writeflag)
115  {
116  is->merge_buf = (char *) xmalloc (max_buf_size+256);
117  memset (is->merge_buf, 0, max_buf_size+256);
118  }
119  else
120  is->merge_buf = NULL;
121  for (i = 0; i<is->no_files; i++)
122  {
123  is->files[i].bf = 0;
124  is->files[i].head_is_dirty = 0;
125  is->files[i].head.lastblock = 1;
126  is->files[i].head.freelist = 0;
127  is->files[i].alloc_entries_num = 0;
128  is->files[i].alloc_entries_max =
129  is->method->filecat[i].bsize / sizeof(zint) - 1;
130  is->files[i].alloc_buf = (char *)
131  xmalloc (is->method->filecat[i].bsize);
132  is->files[i].no_writes = 0;
133  is->files[i].no_reads = 0;
134  is->files[i].no_skip_writes = 0;
135  is->files[i].no_allocated = 0;
136  is->files[i].no_released = 0;
137  is->files[i].no_remap = 0;
138  is->files[i].no_forward = 0;
139  is->files[i].no_backward = 0;
140  is->files[i].sum_forward = 0;
141  is->files[i].sum_backward = 0;
142  is->files[i].no_next = 0;
143  is->files[i].no_prev = 0;
144 
145  init_fc (is, i);
146  }
147 
148  for (i = 0; i<is->no_files; i++)
149  {
150  char fname[FILENAME_MAX];
151  int r;
152 
153  yaz_snprintf(fname, sizeof(fname), "%s%c", name, i+'A');
154  is->files[i].bf = bf_open(bfs, fname, is->method->filecat[i].bsize,
155  writeflag);
156  if (!is->files[i].bf)
157  {
158  isamc_close(is);
159  return 0;
160  }
161  r = bf_read(is->files[i].bf, 0, 0, sizeof(ISAMC_head),
162  &is->files[i].head);
163  if (r == -1)
164  {
165  isamc_close(is);
166  return 0;
167  }
168  }
169  return is;
170 }
171 
173 {
174  if (type < 0 || type >= is->no_files)
175  return -1;
176  return is->files[type].head.lastblock-1;
177 }
178 
179 int isamc_block_size (ISAMC is, int type)
180 {
181  ISAMC_filecat filecat = is->method->filecat;
182  if (type < 0 || type >= is->no_files)
183  return -1;
184  return filecat[type].bsize;
185 }
186 
188 {
189  int i;
190 
191  if (is->method->debug)
192  {
193  yaz_log (YLOG_LOG, "isc: next forw mid-f prev backw mid-b");
194  for (i = 0; i<is->no_files; i++)
195  yaz_log (YLOG_LOG, "isc:%8d%8d%8.1f%8d%8d%8.1f",
196  is->files[i].no_next,
197  is->files[i].no_forward,
198  is->files[i].no_forward ?
199  (double) is->files[i].sum_forward/is->files[i].no_forward
200  : 0.0,
201  is->files[i].no_prev,
202  is->files[i].no_backward,
203  is->files[i].no_backward ?
204  (double) is->files[i].sum_backward/is->files[i].no_backward
205  : 0.0);
206  }
207  if (is->method->debug)
208  yaz_log (YLOG_LOG, "isc: writes reads skipped alloc released remap");
209  for (i = 0; i<is->no_files; i++)
210  {
211  release_fc (is, i);
212  if (is->method->debug)
213  yaz_log (YLOG_LOG, "isc:%8d%8d%8d%8d%8d%8d",
214  is->files[i].no_writes,
215  is->files[i].no_reads,
216  is->files[i].no_skip_writes,
217  is->files[i].no_allocated,
218  is->files[i].no_released,
219  is->files[i].no_remap);
220  if (is->files[i].bf)
221  {
222  if (is->files[i].head_is_dirty)
223  bf_write (is->files[i].bf, 0, 0, sizeof(ISAMC_head),
224  &is->files[i].head);
225  flush_block (is, i);
226  bf_close (is->files[i].bf);
227  }
228  xfree(is->files[i].fc_list);
229  xfree(is->files[i].alloc_buf);
230  }
231  xfree (is->files);
232  xfree (is->merge_buf);
233  xfree (is->method);
234  xfree (is);
235  return 0;
236 }
237 
238 int isamc_read_block (ISAMC is, int cat, zint pos, char *dst)
239 {
240  ++(is->files[cat].no_reads);
241  return bf_read (is->files[cat].bf, pos, 0, 0, dst);
242 }
243 
244 int isamc_write_block (ISAMC is, int cat, zint pos, char *src)
245 {
246  ++(is->files[cat].no_writes);
247  if (is->method->debug > 2)
248  yaz_log (YLOG_LOG, "isc: write_block %d " ZINT_FORMAT, cat, pos);
249  return bf_write (is->files[cat].bf, pos, 0, 0, src);
250 }
251 
252 int isamc_write_dblock (ISAMC is, int cat, zint pos, char *src,
253  zint nextpos, int offset)
254 {
255  ISAMC_BLOCK_SIZE size = offset + ISAMC_BLOCK_OFFSET_N;
256  if (is->method->debug > 2)
257  yaz_log (YLOG_LOG, "isc: write_dblock. size=%d nextpos=" ZINT_FORMAT,
258  (int) size, nextpos);
259  src -= ISAMC_BLOCK_OFFSET_N;
260  memcpy (src, &nextpos, sizeof(nextpos));
261  memcpy (src + sizeof(nextpos), &size, sizeof(size));
262  return isamc_write_block (is, cat, pos, src);
263 }
264 
265 #if ISAMC_FREELIST_CHUNK
266 static void flush_block (ISAMC is, int cat)
267 {
268  char *abuf = is->files[cat].alloc_buf;
269  zint block = is->files[cat].head.freelist;
270  if (block && is->files[cat].alloc_entries_num)
271  {
272  memcpy (abuf, &is->files[cat].alloc_entries_num, sizeof(block));
273  bf_write (is->files[cat].bf, block, 0, 0, abuf);
274  is->files[cat].alloc_entries_num = 0;
275  }
276 }
277 
278 static zint alloc_block (ISAMC is, int cat)
279 {
280  zint block = is->files[cat].head.freelist;
281  char *abuf = is->files[cat].alloc_buf;
282 
283  (is->files[cat].no_allocated)++;
284 
285  if (!block)
286  {
287  block = (is->files[cat].head.lastblock)++; /* no free list */
288  is->files[cat].head_is_dirty = 1;
289  }
290  else
291  {
292  if (!is->files[cat].alloc_entries_num) /* read first time */
293  {
294  bf_read (is->files[cat].bf, block, 0, 0, abuf);
295  memcpy (&is->files[cat].alloc_entries_num, abuf,
296  sizeof(is->files[cat].alloc_entries_num));
297  assert (is->files[cat].alloc_entries_num > 0);
298  }
299  /* have some free blocks now */
300  assert (is->files[cat].alloc_entries_num > 0);
301  is->files[cat].alloc_entries_num--;
302  if (!is->files[cat].alloc_entries_num) /* last one in block? */
303  {
304  memcpy (&is->files[cat].head.freelist, abuf + sizeof(int),
305  sizeof(zint));
306  is->files[cat].head_is_dirty = 1;
307 
308  if (is->files[cat].head.freelist)
309  {
310  bf_read (is->files[cat].bf, is->files[cat].head.freelist,
311  0, 0, abuf);
312  memcpy (&is->files[cat].alloc_entries_num, abuf,
313  sizeof(is->files[cat].alloc_entries_num));
314  assert (is->files[cat].alloc_entries_num);
315  }
316  }
317  else
318  memcpy (&block, abuf + sizeof(zint) + sizeof(int) *
319  is->files[cat].alloc_entries_num, sizeof(zint));
320  }
321  return block;
322 }
323 
324 static void release_block (ISAMC is, int cat, zint pos)
325 {
326  char *abuf = is->files[cat].alloc_buf;
327  zint block = is->files[cat].head.freelist;
328 
329  (is->files[cat].no_released)++;
330 
331  if (block && !is->files[cat].alloc_entries_num) /* must read block */
332  {
333  bf_read (is->files[cat].bf, block, 0, 0, abuf);
334  memcpy (&is->files[cat].alloc_entries_num, abuf,
335  sizeof(is->files[cat].alloc_entries_num));
336  assert (is->files[cat].alloc_entries_num > 0);
337  }
338  assert (is->files[cat].alloc_entries_num <= is->files[cat].alloc_entries_max);
339  if (is->files[cat].alloc_entries_num == is->files[cat].alloc_entries_max)
340  {
341  assert (block);
342  memcpy (abuf, &is->files[cat].alloc_entries_num, sizeof(int));
343  bf_write (is->files[cat].bf, block, 0, 0, abuf);
344  is->files[cat].alloc_entries_num = 0;
345  }
346  if (!is->files[cat].alloc_entries_num) /* make new buffer? */
347  {
348  memcpy (abuf + sizeof(int), &block, sizeof(zint));
349  is->files[cat].head.freelist = pos;
350  is->files[cat].head_is_dirty = 1;
351  }
352  else
353  {
354  memcpy (abuf + sizeof(int) +
355  is->files[cat].alloc_entries_num*sizeof(zint),
356  &pos, sizeof(zint));
357  }
358  is->files[cat].alloc_entries_num++;
359 }
360 #else
361 static void flush_block (ISAMC is, int cat)
362 {
363 }
364 
365 static zint alloc_block (ISAMC is, int cat)
366 {
367  zint block;
368  char buf[sizeof(zint)];
369 
370  is->files[cat].head_is_dirty = 1;
371  (is->files[cat].no_allocated)++;
372  if ((block = is->files[cat].head.freelist))
373  {
374  bf_read (is->files[cat].bf, block, 0, sizeof(zint), buf);
375  memcpy (&is->files[cat].head.freelist, buf, sizeof(zint));
376  }
377  else
378  block = (is->files[cat].head.lastblock)++;
379  return block;
380 }
381 
382 static void release_block (ISAMC is, int cat, zint pos)
383 {
384  char buf[sizeof(zint)];
385 
386  (is->files[cat].no_released)++;
387  is->files[cat].head_is_dirty = 1;
388  memcpy (buf, &is->files[cat].head.freelist, sizeof(zint));
389  is->files[cat].head.freelist = pos;
390  bf_write (is->files[cat].bf, pos, 0, sizeof(zint), buf);
391 }
392 #endif
393 
395 {
396  zint block = 0;
397 
398  if (is->files[cat].fc_list)
399  {
400  int j;
401  zint nb;
402  for (j = 0; j < is->files[cat].fc_max; j++)
403  if ((nb = is->files[cat].fc_list[j]) && (!block || nb < block))
404  {
405  is->files[cat].fc_list[j] = 0;
406  block = nb;
407  break;
408  }
409  }
410  if (!block)
411  block = alloc_block (is, cat);
412  if (is->method->debug > 3)
413  yaz_log (YLOG_LOG, "isc: alloc_block in cat %d: " ZINT_FORMAT, cat, block);
414  return block;
415 }
416 
417 void isamc_release_block (ISAMC is, int cat, zint pos)
418 {
419  if (is->method->debug > 3)
420  yaz_log (YLOG_LOG, "isc: release_block in cat %d:" ZINT_FORMAT, cat, pos);
421  if (is->files[cat].fc_list)
422  {
423  int j;
424  for (j = 0; j<is->files[cat].fc_max; j++)
425  if (!is->files[cat].fc_list[j])
426  {
427  is->files[cat].fc_list[j] = pos;
428  return;
429  }
430  }
431  release_block (is, cat, pos);
432 }
433 
434 static void init_fc (ISAMC is, int cat)
435 {
436  int j = 100;
437 
438  is->files[cat].fc_max = j;
439  is->files[cat].fc_list = (zint *)
440  xmalloc (sizeof(*is->files[0].fc_list) * j);
441  while (--j >= 0)
442  is->files[cat].fc_list[j] = 0;
443 }
444 
445 static void release_fc (ISAMC is, int cat)
446 {
447  int j = is->files[cat].fc_max;
448  zint b;
449 
450  while (--j >= 0)
451  if ((b = is->files[cat].fc_list[j]))
452  {
453  release_block (is, cat, b);
454  is->files[cat].fc_list[j] = 0;
455  }
456 }
457 
459 {
460  ISAMC is = pp->is;
461 
462  (*is->method->codec.stop)(pp->decodeClientData);
463  xfree (pp->buf);
464  xfree (pp);
465 }
466 
468 {
469  ISAMC_PP pp = (ISAMC_PP) xmalloc (sizeof(*pp));
470  char *src;
471 
472  pp->cat = (int) isamc_type(ipos);
473  pp->pos = isamc_block(ipos);
474 
475  src = pp->buf = (char *) xmalloc (is->method->filecat[pp->cat].bsize);
476 
477  pp->next = 0;
478  pp->size = 0;
479  pp->offset = 0;
480  pp->is = is;
481  pp->decodeClientData = (*is->method->codec.start)();
482  pp->deleteFlag = 0;
483  pp->numKeys = 0;
484 
485  if (pp->pos)
486  {
487  src = pp->buf;
488  isamc_read_block (is, pp->cat, pp->pos, src);
489  memcpy (&pp->next, src, sizeof(pp->next));
490  src += sizeof(pp->next);
491  memcpy (&pp->size, src, sizeof(pp->size));
492  src += sizeof(pp->size);
493  memcpy (&pp->numKeys, src, sizeof(pp->numKeys));
494  src += sizeof(pp->numKeys);
495  if (pp->next == pp->pos)
496  {
497  yaz_log(YLOG_FATAL|YLOG_LOG, "pp->next = " ZINT_FORMAT, pp->next);
498  yaz_log(YLOG_FATAL|YLOG_LOG, "pp->pos = " ZINT_FORMAT, pp->pos);
499  assert (pp->next != pp->pos);
500  }
501  pp->offset = src - pp->buf;
502  assert (pp->offset == ISAMC_BLOCK_OFFSET_1);
503  if (is->method->debug > 2)
504  yaz_log (YLOG_LOG, "isc: read_block size=%d %d " ZINT_FORMAT " next="
505  ZINT_FORMAT, pp->size, pp->cat, pp->pos, pp->next);
506  }
507  return pp;
508 }
509 
510 /* returns non-zero if item could be read; 0 otherwise */
511 int isamc_pp_read (ISAMC_PP pp, void *buf)
512 {
513  char *cp = buf;
514  return isamc_read_item (pp, &cp);
515 }
516 
517 /* read one item from file - decode and store it in *dst.
518  Returns
519  0 if end-of-file
520  1 if item could be read ok and NO boundary
521  2 if item could be read ok and boundary */
522 int isamc_read_item (ISAMC_PP pp, char **dst)
523 {
524  ISAMC is = pp->is;
525  const char *src = pp->buf + pp->offset;
526 
527  if (pp->offset >= pp->size)
528  {
529  if (!pp->next)
530  {
531  pp->pos = 0;
532  return 0; /* end of file */
533  }
534  if (pp->next > pp->pos)
535  {
536  if (pp->next == pp->pos + 1)
537  is->files[pp->cat].no_next++;
538  else
539  {
540  is->files[pp->cat].no_forward++;
541  is->files[pp->cat].sum_forward += pp->next - pp->pos;
542  }
543  }
544  else
545  {
546  if (pp->next + 1 == pp->pos)
547  is->files[pp->cat].no_prev++;
548  else
549  {
550  is->files[pp->cat].no_backward++;
551  is->files[pp->cat].sum_backward += pp->pos - pp->next;
552  }
553  }
554  /* out new block position */
555  pp->pos = pp->next;
556  src = pp->buf;
557  /* read block and save 'next' and 'size' entry */
558  isamc_read_block (is, pp->cat, pp->pos, pp->buf);
559  memcpy (&pp->next, src, sizeof(pp->next));
560  src += sizeof(pp->next);
561  memcpy (&pp->size, src, sizeof(pp->size));
562  src += sizeof(pp->size);
563  /* assume block is non-empty */
564  assert (src - pp->buf == ISAMC_BLOCK_OFFSET_N);
565 
566  if (pp->next == pp->pos)
567  {
568  yaz_log(YLOG_FATAL|YLOG_LOG, "pp->next = " ZINT_FORMAT, pp->next);
569  yaz_log(YLOG_FATAL|YLOG_LOG, "pp->pos = " ZINT_FORMAT, pp->pos);
570  assert (pp->next != pp->pos);
571  }
572 
573  if (pp->deleteFlag)
574  isamc_release_block (is, pp->cat, pp->pos);
575  (*is->method->codec.decode)(pp->decodeClientData, dst, &src);
576  pp->offset = src - pp->buf;
577  if (is->method->debug > 2)
578  yaz_log (YLOG_LOG, "isc: read_block size=%d %d " ZINT_FORMAT " next="
579  ZINT_FORMAT, pp->size, pp->cat, pp->pos, pp->next);
580  return 2;
581  }
582  (*is->method->codec.decode)(pp->decodeClientData, dst, &src);
583  pp->offset = src - pp->buf;
584  return 1;
585 }
586 
588 {
589  return pp->numKeys;
590 }
591 
592 /*
593  * Local variables:
594  * c-basic-offset: 4
595  * c-file-style: "Stroustrup"
596  * indent-tabs-mode: nil
597  * End:
598  * vim: shiftwidth=4 tabstop=8 expandtab
599  */
600 
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
#define ISAMC_BLOCK_OFFSET_N
Definition: isamc-p.h:94
unsigned ISAMC_BLOCK_SIZE
Definition: isamc-p.h:32
#define ISAMC_BLOCK_OFFSET_1
Definition: isamc-p.h:93
struct ISAMC_file_s * ISAMC_file
ISAMC isamc_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method)
Definition: isamc.c:77
int isamc_block_size(ISAMC is, int type)
Definition: isamc.c:179
int isamc_write_dblock(ISAMC is, int cat, zint pos, char *src, zint nextpos, int offset)
Definition: isamc.c:252
static void release_fc(ISAMC is, int cat)
Definition: isamc.c:445
int isamc_write_block(ISAMC is, int cat, zint pos, char *src)
Definition: isamc.c:244
zint isamc_pp_num(ISAMC_PP pp)
Definition: isamc.c:587
int isamc_close(ISAMC is)
Definition: isamc.c:187
static void release_block(ISAMC is, int cat, zint pos)
Definition: isamc.c:382
static void flush_block(ISAMC is, int cat)
Definition: isamc.c:361
void isamc_getmethod(ISAMC_M *m)
Definition: isamc.c:45
ISAMC_PP isamc_pp_open(ISAMC is, ISAM_P ipos)
Definition: isamc.c:467
int isamc_read_item(ISAMC_PP pp, char **dst)
Definition: isamc.c:522
int isamc_pp_read(ISAMC_PP pp, void *buf)
Definition: isamc.c:511
static void init_fc(ISAMC is, int cat)
Definition: isamc.c:434
void isamc_pp_close(ISAMC_PP pp)
Definition: isamc.c:458
zint isamc_alloc_block(ISAMC is, int cat)
Definition: isamc.c:394
void isamc_release_block(ISAMC is, int cat, zint pos)
Definition: isamc.c:417
zint isamc_block_used(ISAMC is, int type)
Definition: isamc.c:172
static zint alloc_block(ISAMC is, int cat)
Definition: isamc.c:365
int isamc_read_block(ISAMC is, int cat, zint pos, char *dst)
Definition: isamc.c:238
#define isamc_type(x)
Definition: isamc.h:90
struct ISAMC_s * ISAMC
Definition: isamc.h:30
#define isamc_block(x)
Definition: isamc.h:91
zint ISAM_P
Definition: isamc.h:28
struct ISAMC_PP_s * ISAMC_PP
Definition: isamc.h:31
#define FILENAME_MAX
Definition: mfile.h:42
int(* compare_item)(const void *a, const void *b)
Definition: isamc.h:43
ISAMC_filecat filecat
Definition: isamc.h:41
ISAM_CODEC codec
Definition: isamc.h:46
int max_blocks_mem
Definition: isamc.h:48
void(* log_item)(int logmask, const void *p, const char *txt)
Definition: isamc.h:44
int debug
Definition: isamc.h:49
ISAMC_BLOCK_SIZE offset
Definition: isamc-p.h:71
ISAMC_BLOCK_SIZE size
Definition: isamc-p.h:72
char * buf
Definition: isamc-p.h:70
void * decodeClientData
Definition: isamc-p.h:77
zint next
Definition: isamc-p.h:75
zint pos
Definition: isamc-p.h:74
ISAMC is
Definition: isamc-p.h:76
zint numKeys
Definition: isamc-p.h:79
int cat
Definition: isamc-p.h:73
int deleteFlag
Definition: isamc-p.h:78
int fc_max
Definition: isamc-p.h:57
int alloc_entries_max
Definition: isamc-p.h:55
int no_backward
Definition: isamc-p.h:47
int no_forward
Definition: isamc-p.h:46
ISAMC_head head
Definition: isamc-p.h:35
int alloc_entries_num
Definition: isamc-p.h:54
zint sum_backward
Definition: isamc-p.h:49
int no_allocated
Definition: isamc-p.h:42
int no_released
Definition: isamc-p.h:43
int no_next
Definition: isamc-p.h:50
char * alloc_buf
Definition: isamc-p.h:53
zint sum_forward
Definition: isamc-p.h:48
int no_skip_writes
Definition: isamc-p.h:41
int head_is_dirty
Definition: isamc-p.h:37
int no_writes
Definition: isamc-p.h:39
int no_reads
Definition: isamc-p.h:40
int no_prev
Definition: isamc-p.h:51
zint * fc_list
Definition: isamc-p.h:58
int no_remap
Definition: isamc-p.h:44
BFile bf
Definition: isamc-p.h:36
int mblocks
Definition: isamc.h:37
zint lastblock
Definition: isamc-p.h:28
zint freelist
Definition: isamc-p.h:29
char * merge_buf
Definition: isamc-p.h:64
int max_cat
Definition: isamc-p.h:63
int no_files
Definition: isamc-p.h:62
ISAMC_file files
Definition: isamc-p.h:66
ISAMC_M * method
Definition: isamc-p.h:65
void(* decode)(void *p, char **dst, const char **src)
Definition: isam-codec.h:26
void(* stop)(void *p)
Definition: isam-codec.h:25
void(* encode)(void *p, char **dst, const char **src)
Definition: isam-codec.h:27
void(* reset)(void *p)
Definition: isam-codec.h:28
void *(* start)(void)
Definition: isam-codec.h:24
long zint
Zebra integer.
Definition: util.h:66
#define ZINT_FORMAT
Definition: util.h:72