IDZEBRA 2.2.8
isamc.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/*
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
37static void flush_block (ISAMC is, int cat);
38static void release_fc (ISAMC is, int cat);
39static 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
77ISAMC 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
179int 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
238int 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
244int 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
252int isamc_write_dblock (ISAMC is, int cat, zint pos, char *src,
253 zint nextpos, int offset)
254{
256 if (is->method->debug > 2)
257 yaz_log (YLOG_LOG, "isc: write_dblock. size=%d nextpos=" ZINT_FORMAT,
258 (int) size, nextpos);
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
266static 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
278static 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
324static 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
361static void flush_block (ISAMC is, int cat)
362{
363}
364
365static 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
382static 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
417void 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
434static 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
445static 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 */
511int 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 */
522int 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 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
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 *(* 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
long zint
Zebra integer.
Definition util.h:66
#define ZINT_FORMAT
Definition util.h:72