From f35acdb246c32bc8330fd77104f952711ad1bff5 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Wed, 18 Mar 1998 09:23:55 +0000 Subject: [PATCH] Blocks are stored in chunks on free list - up to factor 2 in speed. Fixed bug that could occur in block category rearrangemen. --- isamc/isamc-p.h | 21 +++++--- isamc/isamc.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++------- isamc/merge.c | 44 ++++++++++++++-- 3 files changed, 192 insertions(+), 30 deletions(-) diff --git a/isamc/isamc-p.h b/isamc/isamc-p.h index a52e486..d9275b6 100644 --- a/isamc/isamc-p.h +++ b/isamc/isamc-p.h @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: isamc-p.h,v $ - * Revision 1.5 1998-03-16 10:37:24 adam + * Revision 1.6 1998-03-18 09:23:55 adam + * Blocks are stored in chunks on free list - up to factor 2 in speed. + * Fixed bug that could occur in block category rearrangemen. + * + * Revision 1.5 1998/03/16 10:37:24 adam * Added more statistics. * * Revision 1.4 1996/11/08 11:15:28 adam @@ -30,6 +34,8 @@ typedef struct { int freelist; } ISAMC_head; +typedef unsigned ISAMC_BLOCK_SIZE; + typedef struct ISAMC_file_s { ISAMC_head head; BFile bf; @@ -49,6 +55,10 @@ typedef struct ISAMC_file_s { int no_next; int no_prev; + char *alloc_buf; + int alloc_entries_num; + int alloc_entries_max; + int fc_max; int *fc_list; } *ISAMC_file; @@ -63,8 +73,8 @@ struct ISAMC_s { struct ISAMC_PP_s { char *buf; - unsigned offset; - unsigned short size; + ISAMC_BLOCK_SIZE offset; + ISAMC_BLOCK_SIZE size; int cat; int pos; int next; @@ -74,9 +84,8 @@ struct ISAMC_PP_s { int numKeys; }; -#define ISAMC_BLOCK_OFFSET_N (sizeof(int)+sizeof(short)) -#define ISAMC_BLOCK_OFFSET_1 (sizeof(int)+sizeof(short)+sizeof(int)) - +#define ISAMC_BLOCK_OFFSET_N (sizeof(int)+sizeof(ISAMC_BLOCK_SIZE)) +#define ISAMC_BLOCK_OFFSET_1 (sizeof(int)+sizeof(ISAMC_BLOCK_SIZE)+sizeof(int)) int isc_alloc_block (ISAMC is, int cat); void isc_release_block (ISAMC is, int cat, int pos); int isc_read_block (ISAMC is, int cat, int pos, char *dst); diff --git a/isamc/isamc.c b/isamc/isamc.c index 3e89b32..2cfe1a2 100644 --- a/isamc/isamc.c +++ b/isamc/isamc.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: isamc.c,v $ - * Revision 1.12 1998-03-16 10:37:24 adam + * Revision 1.13 1998-03-18 09:23:55 adam + * Blocks are stored in chunks on free list - up to factor 2 in speed. + * Fixed bug that could occur in block category rearrangemen. + * + * Revision 1.12 1998/03/16 10:37:24 adam * Added more statistics. * * Revision 1.11 1998/03/13 15:30:50 adam @@ -63,22 +67,28 @@ #include #include "isamc-p.h" +static void flush_block (ISAMC is, int cat); static void release_fc (ISAMC is, int cat); static void init_fc (ISAMC is, int cat); +#define ISAMC_FREELIST_CHUNK 1 + #define SMALL_TEST 0 ISAMC_M isc_getmethod (void) { static struct ISAMC_filecat_s def_cat[] = { #if SMALL_TEST - { 32, 28, 0, 3 }, - { 64, 54, 30, 0 }, + { 32, 28, 0, 3 }, + { 64, 54, 30, 0 }, #else - { 32, 28, 24, 20 }, - { 512, 490, 350, 20 }, - { 4096, 3950, 4200, 20 }, - {32768, 32000, 30000, 0 }, + { 32, 28, 20, 7 }, + { 128, 120, 100, 7 }, + { 512, 490, 350, 7 }, + { 2048, 1900, 1700, 7 }, + { 8192, 8000, 7900, 7 }, + { 32768, 32000, 31000, 7 }, + {131072, 129000, 121000, 0 } #endif }; ISAMC_M m = xmalloc (sizeof(*m)); @@ -156,6 +166,10 @@ ISAMC isc_open (BFiles bfs, const char *name, int writeflag, ISAMC_M method) 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 = xmalloc (is->method->filecat[i].bsize); is->files[i].no_writes = 0; is->files[i].no_reads = 0; is->files[i].no_skip_writes = 0; @@ -227,6 +241,7 @@ int isc_close (ISAMC is) is->files[i].no_released, is->files[i].no_remap); xfree (is->files[i].fc_list); + flush_block (is, i); bf_close (is->files[i].bf); } xfree (is->files); @@ -252,7 +267,7 @@ int isc_write_block (ISAMC is, int cat, int pos, char *src) int isc_write_dblock (ISAMC is, int cat, int pos, char *src, int nextpos, int offset) { - unsigned short size = offset + ISAMC_BLOCK_OFFSET_N; + ISAMC_BLOCK_SIZE size = offset + ISAMC_BLOCK_OFFSET_N; if (is->method->debug > 2) logf (LOG_LOG, "isc: write_dblock. size=%d nextpos=%d", (int) size, nextpos); @@ -262,6 +277,109 @@ int isc_write_dblock (ISAMC is, int cat, int pos, char *src, return isc_write_block (is, cat, pos, src); } +#if ISAMC_FREELIST_CHUNK +static void flush_block (ISAMC 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 (ISAMC 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 (ISAMC 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 (ISAMC is, int cat) +{ + char *abuf = is->files[cat].alloc_buf; + xfree (abuf); +} + static int alloc_block (ISAMC is, int cat) { int block; @@ -279,6 +397,18 @@ static int alloc_block (ISAMC is, int cat) return block; } +static void release_block (ISAMC 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 isc_alloc_block (ISAMC is, int cat) { int block = 0; @@ -301,17 +431,6 @@ int isc_alloc_block (ISAMC is, int cat) return block; } -static void release_block (ISAMC 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); -} - void isc_release_block (ISAMC is, int cat, int pos) { if (is->method->debug > 3) diff --git a/isamc/merge.c b/isamc/merge.c index 2728194..28aa2bf 100644 --- a/isamc/merge.c +++ b/isamc/merge.c @@ -4,7 +4,11 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: merge.c,v $ - * Revision 1.7 1998-03-11 11:18:18 adam + * Revision 1.8 1998-03-18 09:23:55 adam + * Blocks are stored in chunks on free list - up to factor 2 in speed. + * Fixed bug that could occur in block category rearrangemen. + * + * Revision 1.7 1998/03/11 11:18:18 adam * Changed the isc_merge to take into account the mfill (minimum-fill). * * Revision 1.6 1998/03/06 13:54:03 adam @@ -48,6 +52,31 @@ struct isc_merge_block { int dirty; /* block is different from that on file */ }; +static void opt_blocks (ISAMC is, struct isc_merge_block *mb, int ptr) +{ + int i, no_dirty = 0; + for (i = 0; i mb[j].block) + j_min = j; + } + assert (j_min >= 0); + tmp = mb[j_min].block; + mb[j_min].block = mb[i].block; + mb[i].block = tmp; + mb[i].dirty = 1; + } +} + static void flush_blocks (ISAMC is, struct isc_merge_block *mb, int ptr, char *r_buf, int *firstpos, int cat, int last, int *numkeys) @@ -56,9 +85,6 @@ static void flush_blocks (ISAMC is, struct isc_merge_block *mb, int ptr, for (i = 0; imethod->filecat[cat].ifill - @@ -397,6 +429,8 @@ ISAMC_P isc_merge (ISAMC is, ISAMC_P ipos, ISAMC_I data) ptr, j, cat); ptr = j; border = get_border (is, mb, ptr, cat, firstpos); + if (is->method->debug > 3) + logf (LOG_LOG, "isc: border=%d r_offset=%d", border, r_offset); } } if (mb[ptr].offset < r_offset) -- 1.7.10.4