From 8ffa50abf129b5c747fe36fd7f9bf72493d51fc0 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 6 Aug 2004 12:56:04 +0000 Subject: [PATCH] Remove isamd. --- include/isamd.h | 112 ------ isamc/isamd.c | 877 ---------------------------------------- isamc/merge-d.c | 1193 ------------------------------------------------------- 3 files changed, 2182 deletions(-) delete mode 100644 include/isamd.h delete mode 100644 isamc/isamd.c delete mode 100644 isamc/merge-d.c diff --git a/include/isamd.h b/include/isamd.h deleted file mode 100644 index d9112ed..0000000 --- a/include/isamd.h +++ /dev/null @@ -1,112 +0,0 @@ -/* $Id$ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004 - Index Data Aps - -This file is part of the Zebra server. - -Zebra is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -Zebra is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Zebra; see the file LICENSE.zebra. If not, write to the -Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. -*/ - -#ifndef ISAMD_H -#define ISAMD_H - -#include - -YAZ_BEGIN_CDECL - -typedef struct ISAMD_s *ISAMD; -typedef int ISAMD_P; -typedef struct ISAMD_PP_s *ISAMD_PP; - -typedef struct ISAMD_filecat_s { /* filecategories, mostly block sizes */ - int bsize; /* block size */ - int mblocks; /* maximum keys before switching to larger sizes */ -} *ISAMD_filecat; - -typedef struct ISAMD_M_s { - ISAMD_filecat filecat; - - int (*compare_item)(const void *a, const void *b); - void (*log_item)(int logmask, const void *p, const char *txt); - -#define ISAMD_DECODE 0 -#define ISAMD_ENCODE 1 - void *(*code_start)(int mode); - void (*code_stop)(int mode, void *p); - void (*code_item)(int mode, void *p, char **dst, const char **src); - void (*code_reset)(void *p); - - int max_blocks_mem; - int debug; -} ISAMD_M; - -typedef struct ISAMD_I_s { /* encapsulation of input data */ - int (*read_item)(void *clientData, char **dst, int *insertMode); - void *clientData; -} *ISAMD_I; - -ISAMD_M *isamd_getmethod (ISAMD_M *me); - -ISAMD isamd_open (BFiles bfs, const char *name, int writeflag, ISAMD_M *method); -int isamd_close (ISAMD is); -/*ISAMD_P isamd_append (ISAMD is, ISAMD_P pos, ISAMD_I data);*/ -int isamd_append (ISAMD is, char *dictentry, int dictlen, ISAMD_I data); - - - -/* Shortcut: If the isam is relatively short, we store the */ -/* whole thing in the dictionary, and allocate no blocks at all! */ -#define ISAMD_MAX_DICT_LEN 16 - -/*ISAMD_PP isamd_pp_open (ISAMD is, const char *dictbuf);*/ -ISAMD_PP isamd_pp_open (ISAMD is, const char *dictbuf, int dictlen); -ISAMD_PP isamd_pp_create (ISAMD is, int cat); - -void isamd_pp_close (ISAMD_PP pp); -int isamd_read_item (ISAMD_PP pp, char **dst); -int isamd_read_main_item (ISAMD_PP pp, char **dst); -int isamd_pp_read (ISAMD_PP pp, void *buf); -int isamd_pp_num (ISAMD_PP pp); - -int isamd_block_used (ISAMD is, int type); -int isamd_block_size (ISAMD is, int type); - - -#define isamd_type(x) ((x) & 7) -#define isamd_block(x) ((x) >> 3) -#define isamd_addr(blk,typ) (((blk)<<3)+(typ)) - -void isamd_buildfirstblock(ISAMD_PP pp); -void isamd_buildlaterblock(ISAMD_PP pp); - -YAZ_END_CDECL - -#endif /* ISAMD_H */ - - -/* - * $Log: isamd.h,v $ - * Revision 1.3 1999/08/18 08:33:41 heikki - * Fixes - * - * Revision 1.2 1999/07/14 13:21:34 heikki - * Added isam-d files. Compiles (almost) clean. Doesn't work at all - * - * Revision 1.1 1999/07/14 12:34:43 heikki - * Copied from isamh, starting to change things... - * - * - */ diff --git a/isamc/isamd.c b/isamc/isamd.c deleted file mode 100644 index f6d17dc..0000000 --- a/isamc/isamd.c +++ /dev/null @@ -1,877 +0,0 @@ -/* $Id: isamd.c,v 1.27 2004-06-01 12:56:39 adam Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 - Index Data Aps - -This file is part of the Zebra server. - -Zebra is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -Zebra is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Zebra; see the file LICENSE.zebra. If not, write to the -Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. -*/ - -#include -#include -#include -#include - -#include -#include "../index/index.h" /* isamd uses the internal structure of it_key */ -#include "isamd-p.h" - -static void flush_block (ISAMD is, int cat); -static void release_fc (ISAMD is, int cat); -static void init_fc (ISAMD is, int cat); - -#define ISAMD_FREELIST_CHUNK 1 - -#define SMALL_TEST 0 - -ISAMD_M *isamd_getmethod (ISAMD_M *me) -{ - static struct ISAMD_filecat_s def_cat[] = { -#if SMALL_TEST -/* blocksz, max. Unused time being */ - { 32, 40 }, /* 24 is the smallest unreasonable size! */ - { 64, 0 }, -#else - { 32, 1 }, - { 128, 1 }, - { 256, 1 }, - { 512, 1 }, - { 1024, 1 }, - { 2048, 1 }, - { 4096, 1 }, - { 8192, 0 }, - -#endif -#ifdef SKIPTHIS - - - - { 32, 1 }, - { 128, 1 }, - { 512, 1 }, - { 2048, 1 }, - { 8192, 1 }, - { 32768, 1 }, - {131072, 0 }, - - { 24, 1 }, /* Experimental sizes */ - { 32, 1 }, - { 64, 1 }, - { 128, 1 }, - { 256, 1 }, - { 512, 1 }, - { 1024, 1 }, - { 2048, 0 }, -#endif - - }; - ISAMD_M *m = (ISAMD_M *) xmalloc (sizeof(*m)); /* never released! */ - m->filecat = def_cat; /* ok, only alloc'd once */ - - m->code_start = NULL; - m->code_item = NULL; - m->code_stop = NULL; - m->code_reset = NULL; - - m->compare_item = NULL; - m->log_item = NULL; - - m->debug = 0; /* default to no debug */ - - m->max_blocks_mem = 10; - - return m; -} - - - -ISAMD isamd_open (BFiles bfs, const char *name, int writeflag, ISAMD_M *method) -{ - ISAMD is; - ISAMD_filecat filecat; - int i = 0; - - is = (ISAMD) xmalloc (sizeof(*is)); - - is->method = (ISAMD_M *) xmalloc (sizeof(*is->method)); - memcpy (is->method, method, sizeof(*method)); - filecat = is->method->filecat; - assert (filecat); - - /* determine number of block categories */ - if (is->method->debug>0) - logf (LOG_LOG, "isamd: bsize maxkeys"); - do - { - if (is->method->debug>0) - logf (LOG_LOG, "isamd:%6d %6d", - filecat[i].bsize, filecat[i].mblocks); - } while (filecat[i++].mblocks); - is->no_files = i; - is->max_cat = --i; - - assert (is->no_files > 0); - assert (is->max_cat <=8 ); /* we have only 3 bits for it */ - - is->files = (ISAMD_file) xmalloc (sizeof(*is->files)*is->no_files); - - for (i = 0; ino_files; i++) - { - char fname[512]; - - sprintf (fname, "%s%c", name, i+'A'); - is->files[i].bf = bf_open (bfs, fname, is->method->filecat[i].bsize, - writeflag); - is->files[i].head_is_dirty = 0; - if (!bf_read (is->files[i].bf, 0, 0, sizeof(ISAMD_head), - &is->files[i].head)) - { - is->files[i].head.lastblock = 1; - is->files[i].head.freelist = 0; - } - is->files[i].alloc_entries_num = 0; - is->files[i].alloc_entries_max = - is->method->filecat[i].bsize / sizeof(int) - 1; - is->files[i].alloc_buf = (char *) - xmalloc (is->method->filecat[i].bsize); - is->files[i].no_writes = 0; /* clear statistics */ - is->files[i].no_reads = 0; - is->files[i].no_skip_writes = 0; - is->files[i].no_allocated = 0; - is->files[i].no_released = 0; - is->files[i].no_remap = 0; - is->files[i].no_forward = 0; - is->files[i].no_backward = 0; - is->files[i].sum_forward = 0; - is->files[i].sum_backward = 0; - is->files[i].no_next = 0; - is->files[i].no_prev = 0; - is->files[i].no_op_diffonly=0; - is->files[i].no_op_main=0; - init_fc (is, i); - } - is->last_pos=0; - is->last_cat=0; - is->no_read=0; - is->no_read_main=0; - is->no_write=0; - is->no_op_single=0; - is->no_op_new=0; - is->no_read_keys=0; - is->no_read_eof=0; - is->no_seek_nxt=0; - is->no_seek_sam=0; - is->no_seek_fwd=0; - is->no_seek_prv=0; - is->no_seek_bak=0; - is->no_seek_cat=0; - is->no_fbuilds=0; - is->no_appds=0; - is->no_merges=0; - is->no_non=0; - is->no_singles=0; - - return is; -} - -int isamd_block_used (ISAMD is, int type) -{ - if ( type==-1) /* singleton */ - return 0; - if (type < 0 || type >= is->no_files) - return -1; - return is->files[type].head.lastblock-1; -} - -int isamd_block_size (ISAMD is, int type) -{ - ISAMD_filecat filecat = is->method->filecat; - if ( type==-1) /* singleton */ - return 0; /* no bytes used */ - if (type < 0 || type >= is->no_files) - return -1; - return filecat[type].bsize; -} - -int isamd_close (ISAMD is) -{ - int i; - int s; - - if (is->method->debug>0) - { - logf (LOG_LOG, "isamd statistics"); - logf (LOG_LOG, "f nxt forw mid-f prev backw mid-b"); - for (i = 0; ino_files; i++) - logf (LOG_LOG, "%d%7d%7d%7.1f%7d%7d%7.1f",i, - is->files[i].no_next, - is->files[i].no_forward, - is->files[i].no_forward ? - (double) is->files[i].sum_forward/is->files[i].no_forward - : 0.0, - is->files[i].no_prev, - is->files[i].no_backward, - is->files[i].no_backward ? - (double) is->files[i].sum_backward/is->files[i].no_backward - : 0.0); - } - if (is->method->debug>0) - logf (LOG_LOG, "f writes reads skipped alloc released "); - for (i = 0; ino_files; i++) - { - release_fc (is, i); - assert (is->files[i].bf); - if (is->files[i].head_is_dirty) - bf_write (is->files[i].bf, 0, 0, sizeof(ISAMD_head), - &is->files[i].head); - if (is->method->debug>0) - logf (LOG_LOG, "%d%8d%8d%8d%8d%8d",i, - is->files[i].no_writes, - is->files[i].no_reads, - is->files[i].no_skip_writes, - is->files[i].no_allocated, - is->files[i].no_released); - xfree (is->files[i].fc_list); - flush_block (is, i); - bf_close (is->files[i].bf); - } - - if (is->method->debug>0) - { - logf (LOG_LOG, "f opens main diffonly"); - for (i = 0; ino_files; i++) - { - logf (LOG_LOG, "%d%8d%8d%8d",i, - is->files[i].no_op_main+ - is->files[i].no_op_diffonly, - is->files[i].no_op_main, - is->files[i].no_op_diffonly); - } - logf(LOG_LOG,"open single %8d", is->no_op_single); - logf(LOG_LOG,"open new %8d", is->no_op_new); - - logf(LOG_LOG, "new build %8d", is->no_fbuilds); - logf(LOG_LOG, "append %8d", is->no_appds); - logf(LOG_LOG, " merges %8d", is->no_merges); - logf(LOG_LOG, " singles %8d", is->no_singles); - logf(LOG_LOG, " no-ops %8d", is->no_non); - - logf(LOG_LOG, "read blocks %8d", is->no_read); - logf(LOG_LOG, "read keys: %8d %8.1f k/bl", - is->no_read_keys, - 1.0*(is->no_read_keys+1)/(is->no_read+1) ); - logf(LOG_LOG, "read main-k %8d %8.1f %% of keys", - is->no_read_main, - 100.0*(is->no_read_main+1)/(is->no_read_keys+1) ); - logf(LOG_LOG, "read ends: %8d %8.1f k/e", - is->no_read_eof, - 1.0*(is->no_read_keys+1)/(is->no_read_eof+1) ); - s= is->no_seek_nxt+ is->no_seek_sam+ is->no_seek_fwd + - is->no_seek_prv+ is->no_seek_bak+ is->no_seek_cat; - if (s==0) - s++; - logf(LOG_LOG, "seek same %8d %8.1f%%", - is->no_seek_sam, 100.0*is->no_seek_sam/s ); - logf(LOG_LOG, "seek next %8d %8.1f%%", - is->no_seek_nxt, 100.0*is->no_seek_nxt/s ); - logf(LOG_LOG, "seek prev %8d %8.1f%%", - is->no_seek_prv, 100.0*is->no_seek_prv/s ); - logf(LOG_LOG, "seek forw %8d %8.1f%%", - is->no_seek_fwd, 100.0*is->no_seek_fwd/s ); - logf(LOG_LOG, "seek back %8d %8.1f%%", - is->no_seek_bak, 100.0*is->no_seek_bak/s ); - logf(LOG_LOG, "seek cat %8d %8.1f%%", - is->no_seek_cat, 100.0*is->no_seek_cat/s ); - } - xfree (is->files); - xfree (is->method); - xfree (is); - return 0; -} - -static void isamd_seek_stat(ISAMD is, int cat, int pos) -{ - if (cat != is->last_cat) - is->no_seek_cat++; - else if ( pos == is->last_pos) - is->no_seek_sam++; - else if ( pos == is->last_pos+1) - is->no_seek_nxt++; - else if ( pos == is->last_pos-1) - is->no_seek_prv++; - else if ( pos > is->last_pos) - is->no_seek_fwd++; - else if ( pos < is->last_pos) - is->no_seek_bak++; - is->last_cat = cat; - is->last_pos = pos; -} /* seek_stat */ - -int isamd_read_block (ISAMD is, int cat, int pos, char *dst) -{ - isamd_seek_stat(is,cat,pos); - ++(is->files[cat].no_reads); - ++(is->no_read); - if (is->method->debug > 6) - logf (LOG_LOG, "isamd: read_block %d:%d",cat, pos); - return bf_read (is->files[cat].bf, pos, 0, 0, dst); -} - -int isamd_write_block (ISAMD is, int cat, int pos, char *src) -{ - isamd_seek_stat(is,cat,pos); - ++(is->files[cat].no_writes); - ++(is->no_write); - if (is->method->debug > 6) - logf (LOG_LOG, "isamd: write_block %d:%d", cat, pos); - return bf_write (is->files[cat].bf, pos, 0, 0, src); -} - -int isamd_write_dblock (ISAMD is, int cat, int pos, char *src, - int nextpos, int offset) -{ - ISAMD_BLOCK_SIZE size = offset + ISAMD_BLOCK_OFFSET_N; - if (is->method->debug > 4) - logf (LOG_LOG, "isamd: write_dblock. size=%d nextpos=%d", - (int) size, nextpos); - src -= ISAMD_BLOCK_OFFSET_N; - assert( ISAMD_BLOCK_OFFSET_N == sizeof(int)+sizeof(int) ); - memcpy (src, &nextpos, sizeof(int)); - memcpy (src + sizeof(int), &size, sizeof(size)); - return isamd_write_block (is, cat, pos, src); -} - -#if ISAMD_FREELIST_CHUNK -static void flush_block (ISAMD is, int cat) -{ - char *abuf = is->files[cat].alloc_buf; - int block = is->files[cat].head.freelist; - if (block && is->files[cat].alloc_entries_num) - { - memcpy (abuf, &is->files[cat].alloc_entries_num, sizeof(int)); - bf_write (is->files[cat].bf, block, 0, 0, abuf); - is->files[cat].alloc_entries_num = 0; - } - xfree (abuf); -} - -static int alloc_block (ISAMD is, int cat) -{ - int block = is->files[cat].head.freelist; - char *abuf = is->files[cat].alloc_buf; - - (is->files[cat].no_allocated)++; - - if (!block) - { - block = (is->files[cat].head.lastblock)++; /* no free list */ - is->files[cat].head_is_dirty = 1; - } - else - { - if (!is->files[cat].alloc_entries_num) /* read first time */ - { - bf_read (is->files[cat].bf, block, 0, 0, abuf); - memcpy (&is->files[cat].alloc_entries_num, abuf, - sizeof(is->files[cat].alloc_entries_num)); - assert (is->files[cat].alloc_entries_num > 0); - } - /* have some free blocks now */ - assert (is->files[cat].alloc_entries_num > 0); - is->files[cat].alloc_entries_num--; - if (!is->files[cat].alloc_entries_num) /* last one in block? */ - { - memcpy (&is->files[cat].head.freelist, abuf + sizeof(int), - sizeof(int)); - is->files[cat].head_is_dirty = 1; - - if (is->files[cat].head.freelist) - { - bf_read (is->files[cat].bf, is->files[cat].head.freelist, - 0, 0, abuf); - memcpy (&is->files[cat].alloc_entries_num, abuf, - sizeof(is->files[cat].alloc_entries_num)); - assert (is->files[cat].alloc_entries_num); - } - } - else - memcpy (&block, abuf + sizeof(int) + sizeof(int) * - is->files[cat].alloc_entries_num, sizeof(int)); - } - return block; -} - -static void release_block (ISAMD is, int cat, int pos) -{ - char *abuf = is->files[cat].alloc_buf; - int block = is->files[cat].head.freelist; - - (is->files[cat].no_released)++; - - if (block && !is->files[cat].alloc_entries_num) /* must read block */ - { - bf_read (is->files[cat].bf, block, 0, 0, abuf); - memcpy (&is->files[cat].alloc_entries_num, abuf, - sizeof(is->files[cat].alloc_entries_num)); - assert (is->files[cat].alloc_entries_num > 0); - } - assert (is->files[cat].alloc_entries_num <= is->files[cat].alloc_entries_max); - if (is->files[cat].alloc_entries_num == is->files[cat].alloc_entries_max) - { - assert (block); - memcpy (abuf, &is->files[cat].alloc_entries_num, sizeof(int)); - bf_write (is->files[cat].bf, block, 0, 0, abuf); - is->files[cat].alloc_entries_num = 0; - } - if (!is->files[cat].alloc_entries_num) /* make new buffer? */ - { - memcpy (abuf + sizeof(int), &block, sizeof(int)); - is->files[cat].head.freelist = pos; - is->files[cat].head_is_dirty = 1; - } - else - { - memcpy (abuf + sizeof(int) + - is->files[cat].alloc_entries_num*sizeof(int), - &pos, sizeof(int)); - } - is->files[cat].alloc_entries_num++; -} -#else -static void flush_block (ISAMD is, int cat) -{ - char *abuf = is->files[cat].alloc_buf; - xfree (abuf); -} - -static int alloc_block (ISAMD is, int cat) -{ - int block; - char buf[sizeof(int)]; - - is->files[cat].head_is_dirty = 1; - (is->files[cat].no_allocated)++; - if ((block = is->files[cat].head.freelist)) - { - bf_read (is->files[cat].bf, block, 0, sizeof(int), buf); - memcpy (&is->files[cat].head.freelist, buf, sizeof(int)); - } - else - block = (is->files[cat].head.lastblock)++; - return block; -} - -static void release_block (ISAMD is, int cat, int pos) -{ - char buf[sizeof(int)]; - - (is->files[cat].no_released)++; - is->files[cat].head_is_dirty = 1; - memcpy (buf, &is->files[cat].head.freelist, sizeof(int)); - is->files[cat].head.freelist = pos; - bf_write (is->files[cat].bf, pos, 0, sizeof(int), buf); -} -#endif - -int isamd_alloc_block (ISAMD is, int cat) -{ - int block = 0; - - if (is->files[cat].fc_list) - { - int j, nb; - for (j = 0; j < is->files[cat].fc_max; j++) - if ((nb = is->files[cat].fc_list[j]) && (!block || nb < block)) - { - is->files[cat].fc_list[j] = 0; - block = nb; - break; - } - } - if (!block) - block = alloc_block (is, cat); - if (is->method->debug > 4) - logf (LOG_LOG, "isamd: alloc_block in cat %d: %d", cat, block); - return block; -} - -void isamd_release_block (ISAMD is, int cat, int pos) -{ - if (is->method->debug > 4) - logf (LOG_LOG, "isamd: release_block in cat %d: %d", cat, pos); - assert(pos!=0); - - if (is->files[cat].fc_list) - { - int j; - for (j = 0; jfiles[cat].fc_max; j++) - if (!is->files[cat].fc_list[j]) - { - is->files[cat].fc_list[j] = pos; - return; - } - } - release_block (is, cat, pos); -} - -static void init_fc (ISAMD is, int cat) -{ - int j = 100; - - is->files[cat].fc_max = j; - is->files[cat].fc_list = (int *) - xmalloc (sizeof(*is->files[0].fc_list) * j); - while (--j >= 0) - is->files[cat].fc_list[j] = 0; -} - -static void release_fc (ISAMD is, int cat) -{ - int b, j = is->files[cat].fc_max; - - while (--j >= 0) - if ((b = is->files[cat].fc_list[j])) - { - release_block (is, cat, b); - is->files[cat].fc_list[j] = 0; - } -} - -void isamd_pp_close (ISAMD_PP pp) -{ - ISAMD is = pp->is; - - (*is->method->code_stop)(ISAMD_DECODE, pp->decodeClientData); - isamd_free_diffs(pp); /* see merge-d.h */ - if (is->method->debug > 5) - logf (LOG_LOG, "isamd_pp_close %p %d=%d:%d sz=%d n=%d=%d:%d nk=%d", - pp, isamd_addr(pp->pos, pp->cat), pp->cat, pp->pos, pp->size, - pp->next, isamd_type(pp->next), isamd_block(pp->next), - pp->numKeys ); - xfree (pp->buf); - xfree (pp); -} - - -ISAMD_PP isamd_pp_create (ISAMD is, int cat) -/* creates a pp_buff without data in it. pos=0, cat as given */ -{ - ISAMD_PP pp = (ISAMD_PP) xmalloc (sizeof(*pp)); - int sz = is->method->filecat[is->max_cat].bsize; - - pp->numKeys = 0; - pp->buf = (char *) xmalloc (sz); - memset(pp->buf,'\0',sz); /* clear the buffer, for new blocks */ - - pp->next = 0; - pp->size = 0; - pp->offset = 0; - pp->is = is; - pp->diffs=0; - pp->diffbuf=0; - pp->diffinfo=0; - pp->decodeClientData = (*is->method->code_start)(ISAMD_DECODE); - pp->cat = cat; - pp->pos = 0; - is->no_op_new++; - return pp; - -} - - -ISAMD_PP isamd_pp_open (ISAMD is, const char *dictbuf, int dictlen) -{ - ISAMD_P ipos; - ISAMD_PP pp = (ISAMD_PP) xmalloc (sizeof(*pp)); - char *src; - int sz = is->method->filecat[is->max_cat].bsize; - /* always allocate for the largest blocks, saves trouble */ - int dictnum; - - pp->numKeys = 0; - src = pp->buf = (char *) xmalloc (sz); - memset(src,'\0',sz); /* clear the buffer, for new blocks */ - - pp->next = 0; - pp->size = 0; - pp->offset = 0; - pp->is = is; - pp->diffs=0; - pp->diffbuf=0; - pp->diffinfo=0; - pp->decodeClientData = (*is->method->code_start)(ISAMD_DECODE); - - dictnum=*dictbuf; /* numkeys for internals, 0 for externals */ - - if (0==dictnum) - { - memcpy(&ipos, dictbuf+1, sizeof(ISAMD_P) ); - } - else /* dictionary block, fake a real one */ - { - pp->cat=0; - pp->pos=0; - if (is->method->debug > 5) - logf (LOG_LOG, "isamd_pp_open dict"); - pp->numKeys=(unsigned char) dictbuf[0]; - memcpy(pp->buf+ISAMD_BLOCK_OFFSET_1, dictbuf+1,dictlen-1); - pp->size=pp->offset=dictlen+ISAMD_BLOCK_OFFSET_1-1; - is->no_op_single++; - return pp; - } /* dict block */ - - pp->cat = isamd_type(ipos); - pp->pos = isamd_block(ipos); - - if (0==pp->pos) - is->no_op_new++; - - if (pp->pos) - { - src = pp->buf; - isamd_read_block (is, pp->cat, pp->pos, src); - memcpy (&pp->next, src, sizeof(pp->next)); - src += sizeof(pp->next); - memcpy (&pp->size, src, sizeof(pp->size)); - src += sizeof(pp->size); - memcpy (&pp->numKeys, src, sizeof(pp->numKeys)); - src += sizeof(pp->numKeys); - assert (pp->next != isamd_addr(pp->pos,pp->cat)); - pp->offset = src - pp->buf; - assert (pp->offset == ISAMD_BLOCK_OFFSET_1); - assert(pp->size>=ISAMD_BLOCK_OFFSET_1); /*??*/ - if (pp->next) - is->files[pp->cat].no_op_main++; - else - is->files[pp->cat].no_op_diffonly++; - } - if (is->method->debug > 5) - logf (LOG_LOG, "isamd_pp_open %p %d=%d:%d sz=%d n=%d=%d:%d", - pp, isamd_addr(pp->pos, pp->cat), pp->cat, pp->pos, pp->size, - pp->next, isamd_type(pp->next), isamd_block(pp->next) ); - - return pp; -} - - - -void isamd_buildfirstblock(ISAMD_PP pp){ - char *dst=pp->buf; - assert(pp->buf); - assert(pp->next != isamd_addr(pp->pos,pp->cat)); - memcpy(dst, &pp->next, sizeof(pp->next) ); - dst += sizeof(pp->next); - memcpy(dst, &pp->size,sizeof(pp->size)); - dst += sizeof(pp->size); - memcpy(dst, &pp->numKeys, sizeof(pp->numKeys)); - dst += sizeof(pp->numKeys); - assert (dst - pp->buf == ISAMD_BLOCK_OFFSET_1); - if (pp->is->method->debug > 5) - logf (LOG_LOG, "isamd: bldfirst: p=%d=%d:%d n=%d:%d:%d sz=%d nk=%d ", - isamd_addr(pp->pos,pp->cat),pp->cat, pp->pos, - pp->next, isamd_type(pp->next), isamd_block(pp->next), - pp->size, pp->numKeys); -} - -void isamd_buildlaterblock(ISAMD_PP pp){ - char *dst=pp->buf; - assert(pp->buf); - assert(pp->next != isamd_addr(pp->pos,pp->cat)); - memcpy(dst, &pp->next, sizeof(pp->next) ); - dst += sizeof(pp->next); - memcpy(dst, &pp->size,sizeof(pp->size)); - dst += sizeof(pp->size); - assert (dst - pp->buf == ISAMD_BLOCK_OFFSET_N); - if (pp->is->method->debug > 5) - logf (LOG_LOG, "isamd: l8r: sz=%d p=%d/%d>%d/%d", - pp->size, - pp->pos, pp->cat, - isamd_block(pp->next), isamd_type(pp->next) ); -} - - - -/* returns non-zero if item could be read; 0 otherwise */ -int isamd_pp_read (ISAMD_PP pp, void *buf) -{ - - return isamd_read_item (pp, (char **) &buf); - /* note: isamd_read_item is in merge-d.c, because it is so */ - /* convoluted with the merge process */ -} - -/* read one main item from file - decode and store it in *dst. - Does not worry about diffs - Returns - 0 if end-of-file - 1 if item could be read ok -*/ -int isamd_read_main_item (ISAMD_PP pp, char **dst) -{ - ISAMD is = pp->is; - char *src = pp->buf + pp->offset; - int newcat; - int oldoffs; - - if (pp->offset >= pp->size) - { - if (!pp->next) - { - pp->pos = 0; - return 0; /* end of file */ - } - if (pp->next > pp->pos) - { - if (pp->next == pp->pos + 1) - is->files[pp->cat].no_next++; - else - { - is->files[pp->cat].no_forward++; - is->files[pp->cat].sum_forward += pp->next - pp->pos; - } - } - else - { - if (pp->next + 1 == pp->pos) - is->files[pp->cat].no_prev++; - else - { - is->files[pp->cat].no_backward++; - is->files[pp->cat].sum_backward += pp->pos - pp->next; - } - } - /* out new block position */ - newcat = isamd_type(pp->next); - pp->pos = isamd_block(pp->next); - pp->cat = isamd_type(pp->next); - pp->is->no_read_main++; - src = pp->buf; - /* read block and save 'next' and 'size' entry */ - isamd_read_block (is, pp->cat, pp->pos, src); - memcpy (&pp->next, src, sizeof(pp->next)); - src += sizeof(pp->next); - memcpy (&pp->size, src, sizeof(pp->size)); - src += sizeof(pp->size); - /* assume block is non-empty */ - pp->offset = oldoffs = src - pp->buf; - assert (pp->offset == ISAMD_BLOCK_OFFSET_N); - assert (pp->next != isamd_addr(pp->pos,pp->cat)); - (*is->method->code_reset)(pp->decodeClientData); - /* finally, read the item */ - (*is->method->code_item)(ISAMD_DECODE, pp->decodeClientData, dst, &src); - pp->offset = src - pp->buf; - if (is->method->debug > 8) - logf (LOG_LOG, "isamd: read_m: block %d:%d sz=%d ofs=%d-%d next=%d", - pp->cat, pp->pos, pp->size, oldoffs, pp->offset, pp->next); - return 2; - } - oldoffs=pp->offset; - (*is->method->code_item)(ISAMD_DECODE, pp->decodeClientData, dst, &src); - pp->offset = src - pp->buf; - if (is->method->debug > 8) - logf (LOG_LOG, "isamd: read_m: got %d:%d sz=%d ofs=%d-%d next=%d", - pp->cat, pp->pos, pp->size, oldoffs, pp->offset, pp->next); - return 1; -} - -int isamd_pp_num (ISAMD_PP pp) -{ - return pp->numKeys; -} - -#if 0 -/* for testing .. */ -static char *hexdump(unsigned char *p, int len, char *buff) { - static char localbuff[128]; - char bytebuff[8]; - if (!buff) buff=localbuff; - *buff='\0'; - while (len--) { - sprintf(bytebuff,"%02x",*p); - p++; - strcat(buff,bytebuff); - if (len) strcat(buff," "); - } - return buff; -} -#endif - -#ifdef SKIPTHIS - /* needs different arguments, or something */ -void isamd_pp_dump (ISAMD is, ISAMD_P ipos) -{ - ISAMD_PP pp; - ISAMD_P oldaddr=0; - struct it_key key; - int i,n; - int occur =0; - int oldoffs; - int diffmax=1; - int diffidx; - char hexbuff[64]; - int olddebug= is->method->debug; - is->method->debug=0; /* no debug logs while reading for dump */ - - logf(LOG_LOG,"dumping isamd block %d (%d:%d)", - (int)ipos, isamd_type(ipos), isamd_block(ipos) ); - pp=isamd_pp_open(is,ipos); - logf(LOG_LOG,"numKeys=%d, ofs=%d sz=%d", - pp->numKeys, pp->offset, pp->size ); - diffidx=oldoffs= pp->offset; - while ((diffidx < is->method->filecat[pp->cat].bsize) && (diffmax>0)) - { - memcpy(&diffmax,&(pp->buf[diffidx]),sizeof(int)); - logf (LOG_LOG,"diff set at %d-%d: %s", diffidx, diffmax, - hexdump(pp->buf+diffidx,8,0)); - /*! todo: dump the actual diffs as well !!! */ - diffidx=diffmax; - - } /* dump diffs */ - while(isamd_pp_read(pp, &key)) - { - if (oldaddr != isamd_addr(pp->pos,pp->cat) ) - { - oldaddr = isamd_addr(pp->pos,pp->cat); - logf(LOG_LOG,"block %d=%d:%d sz=%d nx=%d=%d:%d ofs=%d", - isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos, - pp->size, - pp->next, isamd_type(pp->next), isamd_block(pp->next), - pp->offset); - i=0; - while (isize) { - n=pp->size-i; - if (n>8) n=8; - logf(LOG_LOG," %05x: %s",i,hexdump(pp->buf+i,n,hexbuff)); - i+=n; - } - if (oldoffs > ISAMD_BLOCK_OFFSET_N) - oldoffs=ISAMD_BLOCK_OFFSET_N; - } /* new block */ - occur++; - logf (LOG_LOG," got %d:%d=%x:%x from %s at %d=%x", - key.sysno, key.seqno, - key.sysno, key.seqno, - hexdump(pp->buf+oldoffs, pp->offset-oldoffs, hexbuff), - oldoffs, oldoffs); - oldoffs = pp->offset; - } - /*!*/ /*TODO: dump diffs too!!! */ - isamd_pp_close(pp); - is->method->debug=olddebug; -} /* dump */ - -#endif - diff --git a/isamc/merge-d.c b/isamc/merge-d.c deleted file mode 100644 index 2912ecf..0000000 --- a/isamc/merge-d.c +++ /dev/null @@ -1,1193 +0,0 @@ -/* $Id: merge-d.c,v 1.30 2003-03-05 16:41:10 adam Exp $ - Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002 - Index Data Aps - -This file is part of the Zebra server. - -Zebra is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2, or (at your option) any later -version. - -Zebra is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License -along with Zebra; see the file LICENSE.zebra. If not, write to the -Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. -*/ - - - - -#define NEW_ISAM_D 1 /* not yet ready to delete the old one! */ - -#include -#include -#include -#include -#include -#include "../index/index.h" -#include "isamd-p.h" - - -struct ISAMD_DIFF_s { - int diffidx; - int maxidx; - struct it_key key; - void *decodeData; - int mode; - int difftype; -}; - -#define DT_NONE 0 /* no diff, marks end of sequence */ -#define DT_DIFF 1 /* ordinarry diff */ -#define DT_MAIN 2 /* main data */ -#define DT_INPU 3 /* input data to be merged */ -#define DT_DONE 4 /* done with all input here */ - - - -/*************************************************************** - * Input preprocess filter - ***************************************************************/ - - -#define FILTER_NOTYET -1 /* no data read in yet, to be done */ - -struct ISAMD_FILTER_s { - ISAMD_I data; /* where the data comes from */ - ISAMD is; /* for debug flags */ - struct it_key k1; /* the next item to be returned */ - int m1; /* mode for k1 */ - int r1; /* result for read of k1, or NOTYET */ - struct it_key k2; /* the one after that */ - int m2; - int r2; -}; - -typedef struct ISAMD_FILTER_s *FILTER; - - -void filter_fill(FILTER F) -{ - while ( (F->r1 == FILTER_NOTYET) || (F->r2 == FILTER_NOTYET) ) - { - if (F->r1==FILTER_NOTYET) - { /* move data forward in the filter */ - F->k1 = F->k2; - F->m1 = F->m2; - F->r1 = F->r2; - if ( 0 != F->r1 ) /* not eof */ - F->r2 = FILTER_NOTYET; /* say we want more */ - if (F->is->method->debug > 9) - logf(LOG_LOG,"filt_fill: shift %d.%d m=%d r=%d", - F->k1.sysno, - F->k1.seqno, - F->m1, F->r1); - } - if (F->r2==FILTER_NOTYET) - { /* read new bottom value */ - char *k_ptr = (char*) &F->k2; - F->r2 = (F->data->read_item)(F->data->clientData, &k_ptr, &F->m2); - if (F->is->method->debug > 9) - logf(LOG_LOG,"filt_fill: read %d.%d m=%d r=%d", - F->k2.sysno, F->k2.seqno, F->m2, F->r2); - } - if ( (F->k1.sysno == F->k2.sysno) && - (F->k1.seqno == F->k2.seqno) && - (F->m1 != F->m2) && - (F->r1 >0 ) && (F->r2 >0) ) - { /* del-ins pair of same key (not eof) , ignore both */ - if (F->is->method->debug > 9) - logf(LOG_LOG,"filt_fill: skipped %d.%d m=%d/%d r=%d/%d", - F->k1.sysno, F->k1.seqno, - F->m1,F->m2, F->r1,F->r2); - F->r1 = FILTER_NOTYET; - F->r2 = FILTER_NOTYET; - } - } /* while */ -} /* filter_fill */ - - -FILTER filter_open( ISAMD is, ISAMD_I data ) -{ - FILTER F = (FILTER) xmalloc(sizeof(struct ISAMD_FILTER_s)); - F->is = is; - F->data = data; - F->k1.sysno=0; - F->k1.seqno=0; - F->k2=F->k1; - F->m1 = F->m2 = 0; - F->r1 = F->r2 = FILTER_NOTYET; - filter_fill(F); - return F; -} - -static void filter_close (FILTER F) -{ - xfree(F); -} - -static int filter_read( FILTER F, - struct it_key *k, - int *mode) -{ - int res; - filter_fill(F); - if (F->is->method->debug > 9) - logf(LOG_LOG,"filt_read: reading %d.%d m=%d r=%d", - F->k1.sysno, F->k1.seqno, F->m1, F->r1); - res = F->r1; - if(res) - { - *k = F->k1; - *mode= F->m1; - } - F->r1 = FILTER_NOTYET; - return res; -} - -static int filter_isempty(FILTER F) -{ - return ( (0 == F->r1) && (0 == F->r2)) ; -} - -#if 0 -static int filter_only_one(FILTER F) -{ - return ( (0 != F->r1) && (0 == F->r2)); -} -#endif - -/* We may need backfilling, if we read a lonely key to make */ -/* a singleton, but its bitw will not fit in. Then we need to */ -/* process it normally, which means reading it again. So we */ -/* need to unread it first. Luckily the filter is empty at that */ -/* point */ -#if 0 -static void filter_backfill(FILTER F, struct it_key *k, int mode) -{ - assert(F->r1 == FILTER_NOTYET ); /* not overwriting data! */ - F->k1=*k; - F->m1=mode; - F->r1=1; /* ok read */ -} -#endif - -/*************************************************************** - * Singleton encoding - ***************************************************************/ -/* When there is only a single item, we don't allocate a block - * for it, but code it in the directory entry directly, if it - * fits. - */ - -#define DEC_SYSBITS 15 -#define DEC_SEQBITS 15 -#define DEC_MASK(n) ((1<<(n))-1) - -#define SINGLETON_BIT (1<<(DEC_SYSBITS+DEC_SEQBITS+1)) - -int is_singleton(ISAMD_P ipos) -{ - return 0; /* no singletons any more */ - return ( ipos != 0 ) && ( ipos & SINGLETON_BIT ); -} - - -int singleton_encode(struct it_key *k) -/* encodes the key into one int. If it does not fit, returns 0 */ -{ - return 0; /* no more singletons */ - if ( (k->sysno & DEC_MASK(DEC_SYSBITS) ) != k->sysno ) - return 0; /* no room dor sysno */ - if ( (k->seqno & DEC_MASK(DEC_SYSBITS) ) != k->seqno ) - return 0; /* no room dor sysno */ - return (k->sysno | (k->seqno << DEC_SYSBITS) ) | SINGLETON_BIT; -} - -void singleton_decode (int code, struct it_key *k) -{ - assert (code & SINGLETON_BIT); - k->sysno = code & DEC_MASK(DEC_SYSBITS); - code = code >> DEC_SYSBITS; - k->seqno = code & DEC_MASK(DEC_SEQBITS); -} - - -/*************************************************************** - * General support routines - ***************************************************************/ - - - -static char *hexdump(unsigned char *p, int len, char *buff) { - static char localbuff[128]; - char bytebuff[8]; - if (!buff) buff=localbuff; - *buff='\0'; - while (len--) { - sprintf(bytebuff,"%02x",*p); - p++; - strcat(buff,bytebuff); - if (len) strcat(buff,","); - } - return buff; -} - - - -static void isamd_reduceblock(ISAMD_PP pp) -/* takes a large block, and reduces its category if possible */ -/* Presumably the first block in an isam-list */ -{ - if (pp->pos) - return; /* existing block, do not touch */ - /* TODO: Probably we may touch anyway? */ - if (pp->is->method->debug > 5) - logf(LOG_LOG,"isamd_reduce: start p=%d c=%d sz=%d", - pp->pos, pp->cat, pp->size); - while ( ( pp->cat > 0 ) && (!pp->next) && - (pp->offset < pp->is->method->filecat[pp->cat-1].bsize ) ) - pp->cat--; - pp->pos = isamd_alloc_block(pp->is, pp->cat); - if (pp->is->method->debug > 5) - logf(LOG_LOG,"isamd_reduce: got p=%d c=%d sz=%d", - pp->pos, pp->cat, pp->size); -} /* reduceblock */ - - -static int save_first_pp ( ISAMD_PP firstpp) -{ - isamd_buildfirstblock(firstpp); - isamd_write_block(firstpp->is,firstpp->cat,firstpp->pos,firstpp->buf); - return isamd_addr(firstpp->pos,firstpp->cat); -} - - -static void save_last_pp (ISAMD_PP pp) -{ - pp->next = 0;/* just to be sure */ - isamd_buildlaterblock(pp); - isamd_write_block(pp->is,pp->cat,pp->pos,pp->buf); -} - -#ifdef UNUSED -static int save_both_pps (ISAMD_PP firstpp, ISAMD_PP pp) -{ - /* order of things: Better to save firstpp first, if there are just two */ - /* blocks, but last if there are blocks in between, as these have already */ - /* been saved... optimise later (that's why this is in its own func...*/ - int retval = save_first_pp(firstpp); - if (firstpp!=pp){ - save_last_pp(pp); - isamd_pp_close(pp); - } - isamd_pp_close(firstpp); - return retval; -} /* save_both_pps */ -#endif - - - -/*************************************************************** - * Diffblock handling - ***************************************************************/ - -void isamd_free_diffs(ISAMD_PP pp) -{ - int i; - if (pp->is->method->debug > 5) - logf(LOG_LOG,"isamd_free_diffs: pp=%p di=%p", pp, pp->diffinfo); - if (!pp->diffinfo) - return; - for (i=0;pp->diffinfo[i].difftype!=DT_NONE;i++) - if(pp->diffinfo[i].decodeData) - { - if (pp->is->method->debug > 8) - logf(LOG_LOG,"isamd_free_diffs [%d]=%p",i, - pp->diffinfo[i].decodeData); - (*pp->is->method->code_stop)(ISAMD_DECODE,pp->diffinfo[i].decodeData); - } - xfree(pp->diffinfo); - if (pp->diffbuf != pp->buf) - xfree (pp->diffbuf); - pp->diffbuf=0; - pp->diffinfo=0; -} /* isamd_free_diffs */ - - -static void getDiffInfo(ISAMD_PP pp ) -{ /* builds the diff info structures from a diffblock */ - int maxinfos = pp->is->method->filecat[pp->cat].bsize / 5 +2; - /* Each diff takes at least 5 bytes. Probably more, but this is safe */ - int i=1; /* [0] is used for the main data, [n+1] for merge inputs */ - int diffsz= maxinfos * sizeof(struct ISAMD_DIFF_s); - int maxsz = pp->is->method->filecat[pp->is->max_cat].bsize; - int diffidx = ISAMD_BLOCK_OFFSET_1; - - pp->diffinfo = xmalloc( diffsz ); - pp->offset = pp->size+1; /* used this block up */ - memset(pp->diffinfo,'\0',diffsz); - if (pp->is->method->debug > 5) - logf(LOG_LOG,"isamd_getDiffInfo: %d=%d:%d->%d, ix=%d mx=%d", - isamd_addr(pp->pos, pp->cat), pp->cat, pp->pos, pp->next, - diffidx,maxinfos); - - /* duplicate the buffer for diffs */ - /* (so that we can read the next real buffer(s) */ - assert(0==pp->diffbuf); - pp->diffbuf=xmalloc(maxsz); - memcpy(pp->diffbuf, pp->buf, maxsz); - - pp->diffinfo[0].maxidx=-1; /* mark as special */ - pp->diffinfo[0].difftype=DT_MAIN; - - while (i pp->is->method->filecat[pp->cat].bsize ) - { - if (pp->is->method->debug > 5) - logf(LOG_LOG,"isamd_getDiffInfo:Near end (no room for len) at ix=%d n=%d", - diffidx, i); - return; /* whole block done */ - } - memcpy( &pp->diffinfo[i].maxidx, &pp->diffbuf[diffidx], sizeof(int) ); - pp->diffinfo[i].difftype=DT_DIFF; - if (pp->is->method->debug > 5) - logf(LOG_LOG,"isamd_getDiffInfo: max=%d ix=%d dbuf=%p", - pp->diffinfo[i].maxidx, diffidx, pp->diffbuf); - - if ( (pp->is->method->debug > 0) && - (pp->diffinfo[i].maxidx > pp->is->method->filecat[pp->cat].bsize) ) - { - logf(LOG_LOG,"Bad MaxIx!!! %s:%d: diffidx=%d", - __FILE__,__LINE__, diffidx); - logf(LOG_LOG,"i=%d maxix=%d bsz=%d", i, pp->diffinfo[i].maxidx, - pp->is->method->filecat[pp->cat].bsize); - logf(LOG_LOG,"pp=%d=%d:%d pp->nx=%d=%d:%d", - isamd_addr(pp->pos,pp->cat), pp->pos, pp->cat, - pp->next, isamd_type(pp->next), isamd_block(pp->next) ); - } - assert(pp->diffinfo[i].maxidx <= pp->is->method->filecat[pp->cat].bsize+1); - - if (0==pp->diffinfo[i].maxidx) - { - if (pp->is->method->debug > 5) /* !!! 4 */ - logf(LOG_LOG,"isamd_getDiffInfo:End mark at ix=%d n=%d", - diffidx, i); - return; /* end marker */ - } - diffidx += sizeof(int); - pp->diffinfo[i].decodeData = (*pp->is->method->code_start)(ISAMD_DECODE); - pp->diffinfo[i].diffidx = diffidx; - if (pp->is->method->debug > 5) - logf(LOG_LOG,"isamd_getDiff[%d]:%d-%d %s", - i,diffidx-sizeof(int),pp->diffinfo[i].maxidx, - hexdump((char *)&pp->diffbuf[diffidx-4],8,0) ); - diffidx=pp->diffinfo[i].maxidx; - if ( diffidx > pp->is->method->filecat[pp->cat].bsize ) - return; /* whole block done */ - ++i; - } - assert (!"too many diff sequences in the block"); -} - -/*************************************************************** - * Main block operations - ***************************************************************/ - - -static ISAMD_PP get_new_main_block( ISAMD_PP firstpp, ISAMD_PP pp) -{ /* allocates a new block for the main data, and links it in */ - int newblock; - if (0 == firstpp->next) - { /* special case, pp not yet allocated. */ - /*Started as largest size, that's fine */ - pp->pos = isamd_alloc_block(pp->is,pp->cat); - firstpp->next = isamd_addr(pp->pos,pp->cat); - if (pp->is->method->debug >3) - logf(LOG_LOG,"isamd_build: Alloc 1. dblock p=%d=%d:%d", - isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos); - } - newblock=isamd_alloc_block(pp->is,pp->cat); - pp->next=isamd_addr(newblock,pp->cat); - isamd_buildlaterblock(pp); - isamd_write_block(pp->is,pp->cat,pp->pos,pp->buf); - if (pp->is->method->debug >3) - logf(LOG_LOG,"isamd_build: Alloc nxt %d=%d:%d -> %d=%d:%d", - isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos, - isamd_addr(newblock,pp->cat), pp->cat, newblock); - pp->next=0; - pp->pos=newblock; - pp->size=pp->offset=ISAMD_BLOCK_OFFSET_N; - return pp; -} /* get_new_main_block */ - - -static ISAMD_PP append_main_item(ISAMD_PP firstpp, - ISAMD_PP pp, - struct it_key *i_key) -{ /* appends one item in the main data block, allocates new if needed */ - char *i_item= (char *) i_key; /* same as char */ - char *i_ptr=i_item; - char codebuff[128]; - char *c_ptr = codebuff; - int codelen; - char hexbuff[64]; - - int maxsize = pp->is->method->filecat[pp->is->max_cat].bsize; - - c_ptr=codebuff; - i_ptr=i_item; - (*pp->is->method->code_item)(ISAMD_ENCODE, pp->decodeClientData, - &c_ptr, &i_ptr); - codelen = c_ptr - codebuff; - assert ( (codelen<128) && (codelen>0)); - if (pp->is->method->debug >7) - logf(LOG_LOG,"isamd:build: coded %s nk=%d,ofs=%d-%d", - hexdump(codebuff, c_ptr-codebuff,hexbuff), firstpp->numKeys+1, - pp->offset, pp->offset+codelen); - - if (pp->offset + codelen > maxsize ) - { /* oops, block full - get a new one */ - pp = get_new_main_block( firstpp, pp ); - /* reset encoging and code again */ - (*pp->is->method->code_reset)(pp->decodeClientData); - c_ptr=codebuff; - i_ptr=i_item; - (*pp->is->method->code_item)(ISAMD_ENCODE, pp->decodeClientData, - &c_ptr, &i_ptr); - codelen = c_ptr - codebuff; - assert ( (codelen<128) && (codelen>0)); - if (pp->is->method->debug >7) - logf(LOG_LOG,"isamd:build: recoded into %s (nk=%d)", - hexdump(codebuff, c_ptr-codebuff,hexbuff), firstpp->numKeys+1); - } /* block full */ - - assert (pp->offset + codelen <= maxsize ); - - /* write the data into pp, now we must have room */ - memcpy(&(pp->buf[pp->offset]),codebuff,codelen); - pp->offset += codelen; - pp->size += codelen; - firstpp->numKeys++; - /* clear the next 4 bytes in block, to avoid confusions with diff lens */ - /* dirty, it should not be done here, but something slips somewhere, and */ - /* I hope this fixes it... - Heikki */ - codelen = pp->offset; - while ( (codelen < maxsize ) && (codelen <= pp->offset+4) ) - pp->buf[codelen++] = '\0'; - return pp; -} /* append_main_item */ - - -/*************************************************************** - * Read with merge - ***************************************************************/ - -/* Reads one item and corrects for the diffs, if any */ -/* return 1 for ok, 0 for eof */ -int isamd_read_item_merge ( - ISAMD_PP pp, - char **dst, - struct it_key *p_key, /* the data item that didn't fit*/ - /* ISAMD_I data) */ /* more input data comes here */ - FILTER filt) /* more input data comes here */ -{ /* The last two args can be null for ordinary reads */ - char *keyptr; - char *codeptr; - char *codestart; - int winner=0; /* which diff holds the day */ - int i; /* looping diffs */ - int cmp; - int retry=1; - int oldoffs; - int rc; - - if (!pp->diffinfo) - { /* first time */ - getDiffInfo(pp); - - for(i=1; pp->diffinfo[i].difftype!=DT_NONE; i++) - ; /* find last diff */ - if (p_key) - { /* we have an extra item to inject into the merge */ - if (pp->is->method->debug >9) /* !!!!! */ - logf(LOG_LOG,"isamd_read_item: going to merge with %d.%d", - p_key->sysno, p_key->seqno); - pp->diffinfo[i].key = *p_key; /* the key merge could not handle */ - pp->diffinfo[i].mode = pp->diffinfo[i].key.seqno & 1; - pp->diffinfo[i].key.seqno >>= 1; - pp->diffinfo[i].difftype=DT_INPU; - if (pp->is->method->debug > 7) - logf(LOG_LOG,"isamd_read_item: inpu key %d sys=%d seq=%d=2*%d+%d", - i, p_key->sysno, - pp->diffinfo[i].key.seqno*2 + pp->diffinfo[1].mode, - pp->diffinfo[i].key.seqno, - pp->diffinfo[i].mode); - p_key->sysno=p_key->seqno=0; /* used it up */ - } - - if (filt) - { /* we have a whole input stream to inject */ - pp->diffinfo[i].difftype=DT_INPU; - } - } /* first time */ - - while (retry) - - { - retry=0; - winner = 0; - for (i=0; (!retry) && (pp->diffinfo[i].difftype); i++) - { - if (0==pp->diffinfo[i].key.sysno) - {/* read a new one, if possible */ - if ((pp->diffinfo[i].difftype==DT_DIFF) && - (pp->diffinfo[i].diffidx < pp->diffinfo[i].maxidx)) - { /* a normal kind of diff */ - oldoffs=pp->diffinfo[i].diffidx; - codeptr= codestart = &(pp->diffbuf[pp->diffinfo[i].diffidx]); - keyptr=(char *)&(pp->diffinfo[i].key); - (*pp->is->method->code_item)(ISAMD_DECODE, - pp->diffinfo[i].decodeData, &keyptr, &codeptr); - pp->diffinfo[i].diffidx += codeptr-codestart; - pp->diffinfo[i].mode = pp->diffinfo[i].key.seqno & 1; - pp->diffinfo[i].key.seqno = pp->diffinfo[i].key.seqno >>1 ; - if (pp->is->method->debug > 9) - logf(LOG_LOG,"isamd_read_item: dif[%d] at %d-%d: %s", - i,oldoffs, pp->diffinfo[i].diffidx, - hexdump(pp->buf+oldoffs, pp->diffinfo[i].diffidx-oldoffs,0)); - if (pp->is->method->debug > 7) - logf(LOG_LOG,"isamd_read_item: rd dif[%d] %d.%d (%x.%x)", - i, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno); - } - else if ( pp->diffinfo[i].difftype==DT_MAIN) - { /* read a main item */ - assert(i==0); /* main data goes before any diffs */ - oldoffs=pp->offset; - keyptr=(char*) &(pp->diffinfo[0].key); - rc= isamd_read_main_item(pp,&keyptr); - if (0==rc) - { /* eof */ - if (pp->is->method->debug > 7) - logf(LOG_LOG,"isamd_read_item: eof (rc=%d) main ", - rc); - pp->diffinfo[i].maxidx=-1; - pp->diffinfo[i].key.sysno=0; - pp->diffinfo[i].key.seqno=0; - pp->diffinfo[i].difftype= DT_DONE; - } - else - { /* not eof */ - pp->diffinfo[i].mode = 1; - if (pp->is->method->debug > 7) - logf(LOG_LOG,"isamd_read_item: rd main %d-%d %d.%d (%x.%x) m=%d", - oldoffs,pp->offset, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - pp->diffinfo[i].mode); - } /* not eof */ - } - else if (pp->diffinfo[i].difftype==DT_INPU) - { - keyptr = (char *) &pp->diffinfo[i].key; - /* rc = (*data->read_item)(data->clientData, &keyptr, &pp->diffinfo[i].mode); */ - rc = filter_read(filt, &pp->diffinfo[i].key, - &pp->diffinfo[i].mode); - if (!rc) - { /* did not get it */ - pp->diffinfo[i].key.sysno=0; - pp->diffinfo[i].maxidx=0; /* signal the end */ - pp->diffinfo[i].difftype=DT_DONE; - } - if (pp->is->method->debug >7) - logf(LOG_LOG,"merge: read inpu m=%d %d.%d (%x.%x)", - pp->diffinfo[i].mode, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno ); - } /* read an input item */ - } /* read a new one */ - - if (pp->is->method->debug > 8) - logf(LOG_LOG,"isamd_read_item: considering d%d %d.%d ix=%d mx=%d", - i, pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - pp->diffinfo[i].diffidx, pp->diffinfo[i].maxidx); - - if ( 0!= pp->diffinfo[i].key.sysno) - { /* got a key, compare */ - if (i!=winner) - cmp=key_compare(&pp->diffinfo[i].key, &pp->diffinfo[winner].key); - else - cmp=-1; - if (0==pp->diffinfo[winner].key.sysno) - cmp=-1; /* end of main sequence, take all diffs */ - if (cmp<0) - { - if (pp->is->method->debug > 8) - logf(LOG_LOG,"isamd_read_item: ins [%d]%d.%d < [%d]%d.%d", - i, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - winner, - pp->diffinfo[winner].key.sysno, pp->diffinfo[winner].key.seqno); - if (pp->diffinfo[i].mode) /* insert diff, should always be */ - winner = i; - else - { - if (pp->is->method->debug > 1) - logf(LOG_LOG,"delete diff for nonexisting item"); - assert(!"delete diff for nonexisting item"); - /* is an assert too steep here? Not really.*/ - } - } /* earlier key */ - else if (cmp==0) - { - if (!pp->diffinfo[i].mode) /* delete diff. should always be */ - { - if (pp->is->method->debug > 8) - logf(LOG_LOG,"isamd_read_item: del %d at%d %d.%d (%x.%x)", - i, winner, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno); - pp->diffinfo[winner].key.sysno=0; /* delete it */ - } - else - if (pp->is->method->debug > 2) - logf(LOG_LOG,"isamd_read_item: duplicate ins %d at%d %d.%d (%x.%x)", - i, winner, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno, - pp->diffinfo[i].key.sysno, pp->diffinfo[i].key.seqno); - /* skip the insert, since we already have it in the base */ - /* Should we fail an assertion here??? */ - pp->diffinfo[i].key.sysno=0; /* done with the delete */ - retry=1; /* start all over again */ - } /* matching key */ - /* else it is a later key, its turn will come */ - } /* got a key */ - } /* for each diff */ - } /* not retry */ - - if ( pp->diffinfo[winner].key.sysno) - { - if (pp->is->method->debug > 7) - logf(LOG_LOG,"isamd_read_item: got %d %d.%d (%x.%x)", - winner, - pp->diffinfo[winner].key.sysno, pp->diffinfo[winner].key.seqno, - pp->diffinfo[winner].key.sysno, pp->diffinfo[winner].key.seqno); - memcpy(*dst, &pp->diffinfo[winner].key, sizeof(struct it_key) ); - *dst += sizeof(struct it_key); - pp->diffinfo[winner].key.sysno=0; /* used that one up */ - cmp= 1; - } - else - { - if (pp->is->method->debug > 7) - logf(LOG_LOG,"isamd_read_item: eof w=%d %d.%d (%x.%x)", - winner, - pp->diffinfo[winner].key.sysno, pp->diffinfo[winner].key.seqno, - pp->diffinfo[winner].key.sysno, pp->diffinfo[winner].key.seqno); - assert(winner==0); /* if nothing found, nothing comes from a diff */ - cmp= 0; /* eof */ - } - if (cmp) - ++(pp->is->no_read_keys); - else - ++(pp->is->no_read_eof); - - return cmp; - -} /* isamd_read_item */ - - -int isamd_read_item (ISAMD_PP pp, char **dst) -{ - return isamd_read_item_merge(pp,dst,0,0); -} - - -/*************************************************************** - * Merge - ***************************************************************/ - -static int merge ( ISAMD_PP firstpp, /* first pp (with diffs) */ - struct it_key *p_key, /* the data item that didn't fit*/ - FILTER filt, /* more input data arriving here */ - char *dictentry, /* the thin in the dictionary */ - int dictlen) /* and its size */ -{ - int diffidx; - int killblk=0; - struct it_key r_key; - char * r_ptr; - int r_more = 1; - ISAMD_PP pp; - ISAMD_PP readpp=firstpp; - int retpos=0; - int diffcat = firstpp->cat; /* keep the category of the diffblock even */ - /* if it is going to be empty now. */ - /* Alternative: Make it the minimal, and */ - /* resize later. Saves disk, but will lead */ - /* into bad seeks. */ - - ++(readpp->is->no_merges); - - /* set up diffs as they should be for reading */ - diffidx = ISAMD_BLOCK_OFFSET_1; - - if (readpp->is->method->debug >4) - logf(LOG_LOG,"isamd_merge: f=%d=%d:%d n=%d=%d:%d", - isamd_addr(firstpp->pos,firstpp->cat), firstpp->cat, firstpp->pos, - firstpp->next, isamd_type(firstpp->next), isamd_block(firstpp->next)); - - /* release our data block. Do before reading, when pos is stable ! */ - killblk=firstpp->pos; - if (killblk) - { - isamd_release_block(firstpp->is, firstpp->cat, killblk); - if (readpp->is->method->debug >3) - logf(LOG_LOG,"isamd_merge: released old firstblock %d (%d:%d)", - isamd_addr(killblk,firstpp->cat), firstpp->cat, killblk ); - } - - - r_ptr= (char *) &r_key; - r_more = isamd_read_item_merge( readpp, &r_ptr, p_key, filt); - if (!r_more) - { /* oops, all data has been deleted! what to do??? */ - /* never mind, we have at least one more delta to add to the block */ - /* pray that is not a delete as well... */ - r_key.sysno = 0; - r_key.seqno = 0; - if (readpp->is->method->debug >5) - logf(LOG_LOG,"isamd_merge:all data has been deleted (nk=%d) ", - readpp->numKeys); - } - - - /* set up the new blocks for simple writing */ - /* firstpp=isamd_pp_open(readpp->is,isamd_addr(0, diffcat)); */ - firstpp=isamd_pp_create(readpp->is, diffcat); - firstpp->pos=isamd_alloc_block(firstpp->is,diffcat); - if (readpp->is->method->debug >3) - logf(LOG_LOG,"isamd_merge: allocated new firstpp %d=%d:%d", - isamd_addr(firstpp->pos,firstpp->cat), firstpp->cat, firstpp->pos ); - - pp=isamd_pp_create(readpp->is,readpp->is->max_cat ); - pp->offset=pp->size=ISAMD_BLOCK_OFFSET_N; - - while (r_more) - { - if (readpp->is->method->debug >6) - logf(LOG_LOG,"isamd_merge: got key %d.%d", - r_key.sysno, r_key.seqno ); - pp= append_main_item(firstpp, pp, &r_key); - - if ( (readpp->pos != killblk ) && (0!=readpp->pos) ) - { /* pos can get to 0 at end of main seq, if still diffs left...*/ - if (readpp->is->method->debug >3) - logf(LOG_LOG,"isamd_merge: released block %d (%d:%d) now %d=%d:%d", - isamd_addr(killblk,readpp->cat), readpp->cat, killblk, - isamd_addr(readpp->pos,readpp->cat),readpp->cat, readpp->pos ); - isamd_release_block(readpp->is, readpp->cat, readpp->pos); - killblk=readpp->pos; - } - - /* (try to) read next item */ - r_ptr= (char *) &r_key; - r_more = isamd_read_item_merge( readpp, &r_ptr,0,filt); - - } /* while read */ - - - isamd_reduceblock(pp); /* reduce size if possible */ - if (0==firstpp->next) - firstpp->next = isamd_addr(pp->pos,pp->cat); - save_last_pp(pp); - if (readpp->is->method->debug >4) - logf(LOG_LOG,"isamd_merge: saved last block %d=%d:%d", - isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos); - isamd_pp_close(pp); - - if (readpp->is->method->debug >5) - logf(LOG_LOG,"isamd_merge: closing readpp %d=%d:%d di=%p", - isamd_addr(readpp->pos,readpp->cat), readpp->cat, readpp->pos, - readpp->diffinfo); - isamd_pp_close(readpp); /* pos is 0 by now, at eof. close works anyway */ - - if (readpp->is->method->debug >2) - logf(LOG_LOG,"isamd_merge: merge ret f=%d=%d:%d pp=%d=%d:%d", - isamd_addr(firstpp->pos,pp->cat), firstpp->cat, firstpp->pos, - isamd_addr(pp->pos,pp->cat), pp->cat, pp->pos); - - firstpp->size = firstpp->offset = ISAMD_BLOCK_OFFSET_1; /* nothing there */ - memset(firstpp->buf,'\0',firstpp->is->method->filecat[firstpp->cat].bsize); - save_first_pp(firstpp); - retpos = isamd_addr(firstpp->pos, firstpp->cat); - isamd_pp_close(firstpp); - - /* Create the dict entry */ - /*!*/ /* it could be this could go in the dict as well, if there's */ - /* been really many deletes. Somehow I suspect that is not the */ - /* case. FIXME: Collect statistics and see if needed */ - dictentry[0]=0; /* mark as a real isam */ - memcpy(dictentry+1, &retpos, sizeof(ISAMD_P)); - dictlen=sizeof(ISAMD_P)+1; - return dictlen; - -} /* merge */ - - - - -/*************************************************************** - * Appending diffs - ***************************************************************/ - - - -static int append_diffs( - ISAMD is, - char *dictentry, int dictlen, - FILTER filt) -{ - ISAMD_P ipos; - struct it_key i_key; /* one input item */ - char *i_item = (char *) &i_key; /* same as chars */ - char *i_ptr=i_item; - int i_more =1; - int i_mode; /* 0 for delete, 1 for insert */ - - ISAMD_PP firstpp; - char hexbuff[64]; - int diffidx=0; - int maxsize=0; - int difflenidx; - char codebuff[128]; - char *c_ptr = codebuff; - int codelen; - int merge_rc; - ISAMD_P retpos; - int dsize; - - if (0==dictlen) - { - firstpp=isamd_pp_create(is, 0 ); - firstpp->size=firstpp->offset=ISAMD_BLOCK_OFFSET_1; - /* create in smallest category, will expand later */ - ++(is->no_fbuilds); - } - else - { - firstpp=isamd_pp_open(is, dictentry, dictlen); - if (dictentry[0] ) - ipos=0; - else - memcpy(&ipos,dictentry+1,sizeof(ISAMD_P)); - ++(is->no_appds); - } - - if (is->method->debug >2) - logf(LOG_LOG,"isamd_appd: Start ipos=%d=%d:%d n=%d=%d:%d nk=%d sz=%d", - ipos, isamd_type(ipos), isamd_block(ipos), - firstpp->next, isamd_type(firstpp->next), isamd_block(firstpp->next), - firstpp->numKeys, firstpp->size); - maxsize = is->method->filecat[firstpp->cat].bsize; - - difflenidx = diffidx = firstpp->size; - - diffidx+=sizeof(int); /* difflen will be stored here */ - - /* read first input */ - i_more = filter_read(filt, &i_key, &i_mode); - /* i_more = (*data->read_item)(data->clientData, &i_ptr, &i_mode); */ - - if (is->method->debug >6) - logf(LOG_LOG,"isamd_appd: start m=%d %d.%d=%x.%x: %d", - i_mode, - i_key.sysno, i_key.seqno, - i_key.sysno, i_key.seqno, - i_key.sysno*2+i_mode); - - while (i_more) - { - /* store the mode bit inside key */ - assert( ((i_key.seqno<<1)>>1) == i_key.seqno); /* can spare the bit */ - i_key.seqno = i_key.seqno * 2 + i_mode; - - c_ptr=codebuff; - i_ptr=i_item; - (*is->method->code_item)(ISAMD_ENCODE, firstpp->decodeClientData, - &c_ptr, &i_ptr); - codelen = c_ptr - codebuff; - assert ( (codelen<128) && (codelen>0)); - if (is->method->debug >7) - logf(LOG_LOG,"isamd_appd: coded %d: %s (nk=%d) (ix=%d)", - codelen, hexdump(codebuff, codelen,hexbuff), - firstpp->numKeys,diffidx); - - if (diffidx + codelen > maxsize ) - { /* block full */ - while ( (firstpp->cat < firstpp->is->max_cat) && - (diffidx + codelen > maxsize) ) - { /* try to increase the block size */ - if (firstpp->pos > 0) /* free the old block if allocated */ - isamd_release_block(is, firstpp->cat, firstpp->pos); - ++firstpp->cat; - maxsize = is->method->filecat[firstpp->cat].bsize; - firstpp->pos=0; /* need to allocate it when saving */ - if (is->method->debug >3) - logf(LOG_LOG,"isamd_appd: increased diff block sz to %d (%d)", - firstpp->cat, maxsize); - } - if ((firstpp->cat >= firstpp->is->max_cat) && - (diffidx + codelen > maxsize) ) - { /* max size - can't help, need to merge it */ - if (is->method->debug >7) - logf(LOG_LOG,"isamd_appd: need to merge"); - if (is->method->debug >9) /* !!!!! */ - logf(LOG_LOG,"isamd_appd: going to merge with m=%d %d.%d", - i_mode, i_key.sysno, i_key.seqno); - merge_rc = merge (firstpp, &i_key, filt, dictentry, dictlen); - if (0!=merge_rc) - return merge_rc; /* merge handled them all ! */ - assert(!"merge returned zero ??"); - } /* need to merge */ - } /* block full */ - - if (!( diffidx+codelen <= maxsize )) - { /* bug hunting */ - logf(LOG_LOG,"OOPS, diffidx problem: d=%d c=%d s=%d > m=%d", - diffidx, codelen, diffidx+codelen, maxsize); - logf(LOG_LOG,"ipos=%d f=%d=%d:%d", - ipos, - isamd_addr(firstpp->pos, firstpp->cat), - firstpp->cat, firstpp->pos ); - } - assert ( diffidx+codelen <= maxsize ); - - /* save the diff */ - memcpy(&(firstpp->buf[diffidx]),codebuff,codelen); - diffidx += codelen; - firstpp->size = firstpp->offset = diffidx; - - if (i_mode) - firstpp->numKeys++; /* insert diff */ - else - firstpp->numKeys--; /* delete diff */ - - /* update length of this diff run */ - memcpy(&(firstpp->buf[difflenidx]),&diffidx,sizeof(diffidx)); - - /* (try to) read the next input */ - i_ptr = i_item; - i_more = filter_read(filt, &i_key, &i_mode); - /* i_more = (*data->read_item)(data->clientData, &i_ptr, &i_mode); */ - if ( (i_more) && (is->method->debug >6) ) - logf(LOG_LOG,"isamd_appd: got m=%d %d.%d=%x.%x: %d", - i_mode, - i_key.sysno, i_key.seqno, - i_key.sysno, i_key.seqno, - i_key.sysno*2+i_mode); - } /* more loop */ - - /* clear the next difflen, if room for such */ - difflenidx = diffidx; - while ( (difflenidx-diffidx<=sizeof(int)+1) && (difflenidxbuf[difflenidx++]='\0'; - - if (firstpp->numKeys==0) - { - /* FIXME: Release blocks that may be allocated !!! */ - return 0; /* don't bother storing this! */ - } - - dsize=diffidx-ISAMD_BLOCK_OFFSET_1; - /* logf(LOG_LOG,"!! nxt=%d diffidx=%d ds=%d", - firstpp->next, diffidx, dsize); */ - - if ( (0==firstpp->next) && (dsize numKeys < 128); - assert(firstpp->numKeys >0); - /* actually, 255 is good enough, but sign mismatches... */ - /* in real life, 4-5 is as much as we can hope for, as long */ - /* as ISAMD_MAX_DICT_LEN is reasonably small (8) */ - dictentry[0]=firstpp->numKeys; - memcpy(dictentry+1, firstpp->buf+ISAMD_BLOCK_OFFSET_1, dsize); - dictlen=dsize+1; - } - else - { - if (0==firstpp->pos) /* need to (re)alloc the block */ - firstpp->pos = isamd_alloc_block(is, firstpp->cat); - retpos = save_first_pp( firstpp ); - isamd_pp_close(firstpp); - dictentry[0]=0; /* mark as a real isam */ - memcpy(dictentry+1, &retpos, sizeof(ISAMD_P)); - dictlen=sizeof(ISAMD_P)+1; - } - - return dictlen; -} /* append_diffs */ - - - - -/************************************************************* - * isamd_append itself - *************************************************************/ - -int isamd_append (ISAMD is, char *dictentry, int dictlen, ISAMD_I data) -/*ISAMD_P isamd_append (ISAMD is, ISAMD_P ipos, ISAMD_I data) */ -{ - FILTER F = filter_open(is,data); - int newlen=0; - - if ( filter_isempty(F) ) /* can be, if del-ins of the same */ - { - if (is->method->debug >3) - logf(LOG_LOG,"isamd_appd: nothing to do "); - filter_close(F); - ++(is->no_non); - return dictlen; /* without doing anything at all */ - } - -#ifdef SKIPTHIS - /* The old way to handle singletons */ - if ( ( 0==ipos) && filter_only_one(F) ) - { - struct it_key k; - int mode; - filter_read(F,&k,&mode); - assert(mode); - rc = singleton_encode(&k); - if (!rc) - { - if (is->method->debug >9) - logf(LOG_LOG,"isamd_appd: singleton didn't fit, backfilling"); - filter_backfill(F,&k, mode); - } - if (is->method->debug >9) - logf(LOG_LOG,"isamd_appd: singleton %d (%x)", - rc,rc); - if (rc) - is->no_singles++; - assert ( (rc==0) || is_singleton(rc) ); - } - newlen = append_diffs(is,ipos,F); -#endif - newlen = append_diffs(is,dictentry,dictlen,F); - filter_close(F); - - if (is->method->debug >2) - logf(LOG_LOG,"isamd_appd: ret len=%d ", newlen); - return newlen; -} /* isamd_append */ - - - - - - - -/* - * $Log: merge-d.c,v $ - * Revision 1.30 2003-03-05 16:41:10 adam - * Fix GCC warnings - * - * Revision 1.29 2002/11/26 22:18:34 adam - * Remove // comments - * - * Revision 1.28 2002/08/02 19:26:56 adam - * Towards GPL - * - * Revision 1.27 2002/07/12 18:12:21 heikki - * Isam-D now stores small entries directly in the dictionary. - * Needs more tuning and cleaning... - * - * Revision 1.26 2002/07/11 16:16:00 heikki - * Fixed a bug in isamd, failed to store a single key when its bits - * did not fit into a singleton. - * - * Revision 1.25 1999/11/30 13:48:04 adam - * Improved installation. Updated for inclusion of YAZ header files. - * - * Revision 1.24 1999/10/05 09:57:40 heikki - * Tuning the isam-d (and fixed a small "detail") - * - * Revision 1.23 1999/09/27 14:36:36 heikki - * singletons - * - * Revision 1.22 1999/09/23 18:01:18 heikki - * singleton optimising - * - * Revision 1.21 1999/09/21 17:36:43 heikki - * Added filter function. Not much of effect on the small test set... - * - * Revision 1.20 1999/09/20 15:48:06 heikki - * Small changes - * - * Revision 1.19 1999/09/13 13:28:28 heikki - * isam-d optimizing: merging input data in the same go - * - * Revision 1.18 1999/08/25 18:09:24 heikki - * Starting to optimize - * - * Revision 1.17 1999/08/24 13:17:42 heikki - * Block sizes, comments - * - * Revision 1.16 1999/08/24 10:12:02 heikki - * Comments about optimising - * - * Revision 1.15 1999/08/22 08:26:34 heikki - * COmments - * - * Revision 1.14 1999/08/20 12:25:58 heikki - * Statistics in isamd - * - * Revision 1.13 1999/08/18 13:59:19 heikki - * Fixed another unlikely difflen bug - * - * Revision 1.12 1999/08/18 13:28:17 heikki - * Set log levels to decent values - * - * Revision 1.11 1999/08/18 10:37:11 heikki - * Fixed (another) difflen bug - * - * Revision 1.10 1999/08/18 09:13:31 heikki - * Fixed a detail - * - * Revision 1.9 1999/08/17 19:46:53 heikki - * Fixed a memory leak - * - * Revision 1.8 1999/08/07 11:30:59 heikki - * Bug fixing (still a mem leak somewhere) - * - * Revision 1.7 1999/08/04 14:21:18 heikki - * isam-d seems to be working. - * - * Revision 1.6 1999/07/23 15:43:05 heikki - * Hunted a few bugs in isam-d. Still crashes on the long test run - * - * Revision 1.5 1999/07/23 13:58:52 heikki - * merged closer to working, still fails on filling a separate, large block - * - * Revision 1.4 1999/07/21 14:53:55 heikki - * isamd read and write functions work, except when block full - * Merge missing still. Need to split some functions - * - * Revision 1.1 1999/07/14 13:14:47 heikki - * Created empty - * - * - */ - - -- 1.7.10.4