27#include <yaz/snprintf.h>
28#include <yaz/xmalloc.h>
36#define ISAMB_MAJOR_VERSION 3
37#define ISAMB_MINOR_VERSION_NO_ROOT 0
38#define ISAMB_MINOR_VERSION_WITH_ROOT 1
54#define DST_ITEM_MAX 5000
57#define ISAMB_MAX_PAGE 32768
59#define ISAMB_MAX_LEVEL 10
61#define DST_BUF_SIZE (2*ISAMB_MAX_PAGE+DST_ITEM_MAX+100)
64#define ISAMB_CACHE_ENTRY_SIZE ISAMB_MAX_PAGE
68#define CAT_MASK (CAT_MAX-1)
73#define ISAMB_MIN_SIZE 32
75#define ISAMB_FAC_SIZE 4
78#define ISAMB_PTR_CODEC 1
148#define encode_item_len encode_ptr
152 unsigned char *
bp = (
unsigned char*) *
dst;
156 *
bp++ = (
unsigned char) (128 | (
pos & 127));
166 (*dst) +=
sizeof(
pos);
170#define decode_item_len decode_ptr
178 while (((
c = *(
const unsigned char *)((*src)++)) & 128))
190 (*src) +=
sizeof(*pos);
219 isamb->
cache = cache;
243 assert(cache == 0 || cache == 1);
292 int major, minor, len,
pos = 0;
301 if (
sscanf(
hbuf+5,
"%d %d %d", &major, &minor, &len) != 3)
314 for (left = len -
sizes[
i]; left > 0; left = left -
sizes[
i])
320 "file=%s len=%d pos=%d",
346 yaz_log(
YLOG_WARN,
"isamb debug enabled. Things will be slower than usual");
400 if ((*ce)->pos ==
norm)
497 for (left = len -
b_size; left > 0; left = left -
b_size)
554 src = (
char*) p->
buf + 3;
688 char *
dst = (
char*)p->
buf + 3;
739 const char *
src0 = src;
906 (*sp)->size =
endp - src;
907 memcpy((*sp)->bytes, src, (*sp)->size);
1110 const char *
src_0 = src;
1217 if (!*p || (*p)->
leaf)
1236 const char *src =
p1->bytes +
p1->offset;
1243 while (src !=
p1->bytes +
p1->size)
1301 char *
dst =
p2->bytes +
p2->size;
1360 pp->skipped_numbers = 0;
1361 pp->returned_numbers = 0;
1364 pp->skipped_nodes[
i] =
pp->accessed_nodes[
i] = 0;
1369 pp->block[
pp->level] = p;
1371 pp->total_size += p->
size;
1378 pp->accessed_nodes[
pp->level]++;
1380 pp->block[
pp->level+1] = 0;
1381 pp->maxlevel =
pp->level;
1399 pp->maxlevel,
pp->skipped_numbers,
pp->returned_numbers);
1400 for (
i =
pp->maxlevel;
i>=0;
i--)
1401 if (
pp->skipped_nodes[
i] ||
pp->accessed_nodes[
i])
1404 pp->accessed_nodes[
i],
pp->skipped_nodes[
i]);
1405 pp->isamb->skipped_numbers +=
pp->skipped_numbers;
1406 pp->isamb->returned_numbers +=
pp->returned_numbers;
1407 for (
i =
pp->maxlevel;
i>=0;
i--)
1409 pp->isamb->accessed_nodes[
i] +=
pp->accessed_nodes[
i];
1410 pp->isamb->skipped_nodes[
i] +=
pp->skipped_nodes[
i];
1415 *blocks =
pp->no_blocks;
1416 for (
i = 0;
i <=
pp->level;
i++)
1444 "%*s " ZINT_FORMAT " cat=%d size=%d max=%d items="
1550 pp->block[
pp->level] = 0;
1552 p =
pp->block[
pp->level];
1602 pp->total_size += p->
size;
1655 pp->returned_numbers++;
int bf_read(BFile bf, zint no, int offset, int nbytes, void *buf)
read from block file (may call exit)
void bf_close(BFile bf)
closes a Block file (may call exit)
BFile bf_open(BFiles bfs, const char *name, int block_size, int wflag)
opens and returns a Block file handle
int bf_write(BFile bf, zint no, int offset, int nbytes, const void *buf)
writes block of bytes to file (may call exit)
static struct ISAMB_block * open_block(ISAMB b, ISAM_P pos)
void isamb_pp_pos(ISAMB_PP pp, double *current, double *total)
ISAMB_PP isamb_pp_open(ISAMB isamb, ISAM_P pos, int scope)
void isamb_pp_close_x(ISAMB_PP pp, zint *size, zint *blocks)
static int cache_block(ISAMB b, ISAM_P pos, unsigned char *userbuf, int wr)
void isamb_set_int_count(ISAMB b, int v)
#define ISAMB_MAJOR_VERSION
zint isamb_get_leaf_splits(ISAMB b)
ISAMB isamb_open(BFiles bfs, const char *name, int writeflag, ISAMC_M *method, int cache)
int isamb_block_info(ISAMB isamb, int cat)
zint isamb_get_int_splits(ISAMB b)
ISAMB_PP isamb_pp_open_x(ISAMB isamb, ISAM_P pos, int *level, int scope)
static void isamb_dump_r(ISAMB b, ISAM_P pos, void(*pr)(const char *str), int level)
int isamb_pp_forward(ISAMB_PP pp, void *buf, const void *untilb)
struct ISAMB_block * new_block(ISAMB b, int leaf, int cat)
struct ISAMB_block * new_int(ISAMB b, int cat)
int insert_leaf(ISAMB b, struct ISAMB_block **sp1, void *lookahead_item, int *lookahead_mode, ISAMC_I *stream, struct ISAMB_block **sp2, void *sub_item, int *sub_size, const void *max_item)
int insert_int(ISAMB b, struct ISAMB_block *p, void *lookahead_item, int *mode, ISAMC_I *stream, struct ISAMB_block **sp, void *split_item, int *split_size, const void *last_max_item)
zint isamb_get_root_ptr(ISAMB b)
struct ISAMB_block * new_leaf(ISAMB b, int cat)
static void flush_blocks(ISAMB b, int cat)
void isamb_dump(ISAMB b, ISAM_P pos, void(*pr)(const char *str))
void isamb_close(ISAMB isamb)
static void encode_ptr(char **dst, zint pos)
void isamb_set_root_ptr(ISAMB b, zint root_ptr)
void close_block(ISAMB b, struct ISAMB_block *p)
void isamb_merge(ISAMB b, ISAM_P *pos, ISAMC_I *stream)
#define ISAMB_MINOR_VERSION_WITH_ROOT
ISAMB isamb_open2(BFiles bfs, const char *name, int writeflag, ISAMC_M *method, int cache, int no_cat, int *sizes, int use_root_ptr)
void isamb_pp_close(ISAMB_PP pp)
#define ISAMB_MINOR_VERSION_NO_ROOT
#define ISAMB_CACHE_ENTRY_SIZE
void isamb_set_cache_size(ISAMB b, int v)
int isamb_unlink(ISAMB b, ISAM_P pos)
static void decode_ptr(const char **src, zint *pos)
int insert_sub(ISAMB b, struct ISAMB_block **p, void *new_item, int *mode, ISAMC_I *stream, struct ISAMB_block **sp, void *sub_item, int *sub_size, const void *max_item)
int isamb_pp_read(ISAMB_PP pp, void *buf)
static void check_block(ISAMB b, struct ISAMB_block *p)
zint accessed_nodes[ISAMB_MAX_LEVEL]
zint skipped_nodes[ISAMB_MAX_LEVEL]
struct ISAMB_block ** block
struct ISAMB_cache_entry * next
struct ISAMB_cache_entry * cache_entries
zint number_of_int_splits
zint number_of_leaf_splits
zint accessed_nodes[ISAMB_MAX_LEVEL]
zint skipped_nodes[ISAMB_MAX_LEVEL]
int(* read_item)(void *clientData, char **dst, int *insertMode)
int(* compare_item)(const void *a, const void *b)
void(* log_item)(int logmask, const void *p, const char *txt)
void(* decode)(void *p, char **dst, const char **src)
void(* encode)(void *p, char **dst, const char **src)
void zebra_exit(const char *msg)