X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=isam%2Fisam.c;h=2958f16ec356f83751ebf20fa7c70211caca2596;hb=c9c9df90cf9d66e46b177e62a4402a9def633634;hp=ad2f90c5652de847fa0d5d2b7f56c3b336c6af05;hpb=c6c40893444f2288cdea91d30dd92df0f285e67d;p=idzebra-moved-to-github.git diff --git a/isam/isam.c b/isam/isam.c index ad2f90c..2958f16 100644 --- a/isam/isam.c +++ b/isam/isam.c @@ -4,8 +4,29 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: isam.c,v $ - * Revision 1.2 1994-09-26 16:07:53 quinn - * Most of the functionality in place. + * Revision 1.10 1994-09-28 16:58:32 quinn + * Small mod. + * + * Revision 1.9 1994/09/28 12:56:15 quinn + * Added access functions (ISPT) + * + * Revision 1.8 1994/09/28 12:32:17 quinn + * Trivial + * + * Revision 1.7 1994/09/28 11:56:25 quinn + * Added sort of input to is_merge + * + * Revision 1.6 1994/09/28 11:29:33 quinn + * Added cmp parameter. + * + * Revision 1.5 1994/09/27 20:03:50 quinn + * Seems relatively bug-free. + * + * Revision 1.4 1994/09/26 17:11:29 quinn + * Trivial + * + * Revision 1.3 1994/09/26 17:06:35 quinn + * Back again... * * Revision 1.1 1994/09/12 08:02:13 quinn * Not functional yet @@ -17,15 +38,36 @@ #include #include -#include "isutil.h" -#include "rootblk.h" #include #include #include -#include "memory.h" -#include "physical.h" +#include "isutil.h" +#include "rootblk.h" #include "keyops.h" +static int (*extcmp)(const void *p1, const void *p2); +static ispt_struct *ispt_freelist = 0; + +static ISPT ispt_alloc() +{ + ISPT p; + + if (ispt_freelist) + { + p = ispt_freelist; + ispt_freelist = ispt_freelist->next; + } + else + p = xmalloc(sizeof(ispt_struct)); + return p; +} + +static void ispt_free(ISPT pt) +{ + pt->next = ispt_freelist; + ispt_freelist = pt; +} + static int splitargs(const char *s, char *bf[], int max) { int ct = 0; @@ -52,7 +94,8 @@ static int splitargs(const char *s, char *bf[], int max) * Open isam file. * Process resources. */ -ISAM is_open(const char *name, int writeflag) +ISAM is_open(const char *name, int (*cmp)(const void *p1, const void *p2), + int writeflag) { ISAM new; char *nm, *r, *pp[IS_MAX_BLOCKTYPES+1], m[2]; @@ -213,7 +256,7 @@ ISAM is_open(const char *name, int writeflag) new->types[i].nice_keys_block = 1; } - new->cmp = is_default_cmp; + new->cmp = cmp ? cmp : is_default_cmp; return new; } @@ -258,16 +301,26 @@ static ISAM_P is_address(int type, int pos) return r; } -ISAM_P is_merge(ISAM is, ISAM_P pos, int num, const char *data) +int sort_input(const void *p1, const void *p2) +{ + int rs; + + if ((rs = (*extcmp)(((char *)p1) + 1, ((char *)p2) + 1))) + return rs; + return *((char *)p1) - *((char*)p2); +} + +ISAM_P is_merge(ISAM is, ISAM_P pos, int num, char *data) { is_mtable tab; int res; char keybuf[IS_MAX_RECORD]; - int oldnum, oldtype; + int oldnum, oldtype, i; char operation, *record; + extcmp = is->cmp; + qsort(data, num, is_keysize(is) + 1, sort_input); is_m_establish_tab(is, &tab, pos); - /* TODO: do something to aquire oldnum at this point */ if (pos) if (is_m_read_full(&tab, tab.data) < 0) { @@ -279,10 +332,10 @@ ISAM_P is_merge(ISAM is, ISAM_P pos, int num, const char *data) while (num) { operation = *(data)++; - record = (char*)data; + record = (char*) data; data += is_keysize(is); num--; - while (num && !memcmp(record, data, is_keysize(tab.is) + 1)) + while (num && !memcmp(record - 1, data, is_keysize(tab.is) + 1)) { data += 1 + is_keysize(is); num--; @@ -334,14 +387,67 @@ ISAM_P is_merge(ISAM is, ISAM_P pos, int num, const char *data) } } } - while (tab.pos_type < tab.is->num_types - 1 && tab.num_records > - tab.is->types[tab.pos_type].max_keys) - tab.pos_type++; + i = tab.pos_type; + while (i < tab.is->num_types - 1 && tab.num_records > + tab.is->types[i].max_keys) + i++; + if (i != tab.pos_type) + { + is_p_unmap(&tab); + tab.pos_type = i; + } if (!oldnum || tab.pos_type != oldtype || (abs(oldnum - tab.num_records) * 100) / oldnum > tab.is->repack) is_p_remap(&tab); else is_p_align(&tab); - is_p_sync(&tab); - return is_address(tab.pos_type, tab.data->diskpos); + if (tab.data) + { + is_p_sync(&tab); + pos = is_address(tab.pos_type, tab.data->diskpos); + } + else + pos = 0; + is_m_release_tab(&tab); + return pos; } + +/* + * Locate a table of keys in an isam file. The ISPT is an individual + * position marker for that table. + */ +ISPT is_position(ISAM is, ISAM_P pos) +{ + ispt_struct *p; + + p = ispt_alloc(); + is_m_establish_tab(is, &p->tab, pos); + return p; +} + +/* + * Release ISPT. + */ +void is_pt_free(ISPT ip) +{ + is_m_release_tab(&ip->tab); + ispt_free(ip); +} + +/* + * Read a key from a table. + */ +int is_readkey(ISPT ip, void *buf) +{ + return is_m_read_record(&ip->tab, buf); +} + +int is_numkeys(ISPT ip) +{ + return is_m_num_records(&ip->tab); +} + +void is_rewind(ISPT ip) +{ + is_m_rewind(&ip->tab); +}