From: Adam Dickmeiss Date: Fri, 20 Dec 1996 11:07:20 +0000 (+0000) Subject: Implemented Multi-or result set. X-Git-Tag: ZEBRA.1.0~357 X-Git-Url: http://git.indexdata.com/?p=idzebra-moved-to-github.git;a=commitdiff_plain;h=5d20c4e9f612a012313370c82dc8481b9f19d5df Implemented Multi-or result set. --- diff --git a/rset/Makefile b/rset/Makefile index 5ca63d5..00f6abd 100644 --- a/rset/Makefile +++ b/rset/Makefile @@ -1,7 +1,7 @@ # Copyright (C) 1994-1996, Index Data I/S # All rights reserved. # Sebastian Hammer, Adam Dickmeiss -# $Id: Makefile,v 1.13 1996-10-29 13:55:18 adam Exp $ +# $Id: Makefile,v 1.14 1996-12-20 11:07:20 adam Exp $ SHELL=/bin/sh RANLIB=ranlib @@ -13,7 +13,8 @@ INCLUDE=-I../include $(YAZINC) DEFS=$(INCLUDE) LIB=../lib/rset.a PROG= -PO=rset.o rstemp.o rsisam.o rsnull.o rsbool.o rssbool.o rsrel.o rsisamc.o +PO=rset.o rstemp.o rsisam.o rsnull.o rsbool.o rssbool.o \ + rsrel.o rsisamc.o rsm_or.o CPP=$(CC) -E all: $(LIB) diff --git a/rset/rsm_or.c b/rset/rsm_or.c new file mode 100644 index 0000000..e8b0047 --- /dev/null +++ b/rset/rsm_or.c @@ -0,0 +1,292 @@ +/* + * Copyright (C) 1994-1996, Index Data I/S + * All rights reserved. + * Sebastian Hammer, Adam Dickmeiss + * + * $Log: rsm_or.c,v $ + * Revision 1.1 1996-12-20 11:07:21 adam + * Implemented Multi-or result set. + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +static void *r_create(const struct rset_control *sel, void *parms, + int *flags); +static RSFD r_open (RSET ct, int flag); +static void r_close (RSFD rfd); +static void r_delete (RSET ct); +static void r_rewind (RSFD rfd); +static int r_count (RSET ct); +static int r_read (RSFD rfd, void *buf); +static int r_write (RSFD rfd, const void *buf); +static int r_score (RSFD rfd, int *score); + +static const rset_control control = +{ + "multi-or", + r_create, + r_open, + r_close, + r_delete, + r_rewind, + r_count, + r_read, + r_write, + r_score +}; + +const rset_control *rset_kind_m_or = &control; + +struct rset_mor_info { + int key_size; + int no_rec; + int (*cmp)(const void *p1, const void *p2); + ISAMC isc; + ISAM_P *isam_positions; + + int no_isam_positions; + struct rset_mor_rfd *rfd_list; +}; + +struct trunc_info { + int *ptr; + int *indx; + char **heap; + int heapnum; + int (*cmp)(const void *p1, const void *p2); + int keysize; + char *swapbuf; + char *tmpbuf; + char *buf; +}; + +struct rset_mor_rfd { + int flag; + ISAMC_PP *ispt; + struct rset_mor_rfd *next; + struct rset_mor_info *info; + struct trunc_info *ti; +}; + +static void heap_swap (struct trunc_info *ti, int i1, int i2) +{ + int swap; + + swap = ti->ptr[i1]; + ti->ptr[i1] = ti->ptr[i2]; + ti->ptr[i2] = swap; +} + +static void heap_delete (struct trunc_info *ti) +{ + int cur = 1, child = 2; + + heap_swap (ti, 1, ti->heapnum--); + while (child <= ti->heapnum) { + if (child < ti->heapnum && + (*ti->cmp)(ti->heap[ti->ptr[child]], + ti->heap[ti->ptr[1+child]]) > 0) + child++; + if ((*ti->cmp)(ti->heap[ti->ptr[cur]], + ti->heap[ti->ptr[child]]) > 0) + { + heap_swap (ti, cur, child); + cur = child; + child = 2*cur; + } + else + break; + } +} + +static void heap_insert (struct trunc_info *ti, const char *buf, int indx) +{ + int cur, parent; + + cur = ++(ti->heapnum); + memcpy (ti->heap[ti->ptr[cur]], buf, ti->keysize); + ti->indx[ti->ptr[cur]] = indx; + parent = cur/2; + while (parent && (*ti->cmp)(ti->heap[ti->ptr[parent]], + ti->heap[ti->ptr[cur]]) > 0) + { + heap_swap (ti, cur, parent); + cur = parent; + parent = cur/2; + } +} + +static +struct trunc_info *heap_init (int size, int key_size, + int (*cmp)(const void *p1, const void *p2)) +{ + struct trunc_info *ti = xmalloc (sizeof(*ti)); + int i; + + ++size; + ti->heapnum = 0; + ti->keysize = key_size; + ti->cmp = cmp; + ti->indx = xmalloc (size * sizeof(*ti->indx)); + ti->heap = xmalloc (size * sizeof(*ti->heap)); + ti->ptr = xmalloc (size * sizeof(*ti->ptr)); + ti->swapbuf = xmalloc (ti->keysize); + ti->tmpbuf = xmalloc (ti->keysize); + ti->buf = xmalloc (size * ti->keysize); + for (i = size; --i >= 0; ) + { + ti->ptr[i] = i; + ti->heap[i] = ti->buf + ti->keysize * i; + } + return ti; +} + +static void heap_close (struct trunc_info *ti) +{ + xfree (ti->ptr); + xfree (ti->indx); + xfree (ti->heap); + xfree (ti->swapbuf); + xfree (ti->tmpbuf); + xfree (ti); +} + + +static void *r_create (const struct rset_control *sel, void *parms, + int *flags) +{ + rset_m_or_parms *r_parms = parms; + struct rset_mor_info *info; + + *flags |= RSET_FLAG_VOLATILE; + info = xmalloc (sizeof(*info)); + info->key_size = r_parms->key_size; + assert (info->key_size > 1); + info->cmp = r_parms->cmp; + + info->isc = r_parms->isc; + info->no_isam_positions = r_parms->no_isam_positions; + info->isam_positions = xmalloc (sizeof(*info->isam_positions) * + info->no_isam_positions); + memcpy (info->isam_positions, r_parms->isam_positions, + sizeof(*info->isam_positions) * info->no_isam_positions); + info->rfd_list = NULL; + + return info; +} + +static RSFD r_open (RSET ct, int flag) +{ + struct rset_mor_rfd *rfd; + struct rset_mor_info *info = ct->buf; + int i; + + if (flag & RSETF_WRITE) + { + logf (LOG_FATAL, "m_or set type is read-only"); + return NULL; + } + rfd = xmalloc (sizeof(*rfd)); + rfd->flag = flag; + rfd->next = info->rfd_list; + rfd->info = info; + info->rfd_list = rfd; + + rfd->ispt = xmalloc (sizeof(*rfd->ispt) * info->no_isam_positions); + + rfd->ti = heap_init (info->no_isam_positions, info->key_size, info->cmp); + + for (i = 0; ino_isam_positions; i++) + { + rfd->ispt[i] = isc_pp_open (info->isc, info->isam_positions[i]); + if (isc_pp_read (rfd->ispt[i], rfd->ti->tmpbuf)) + heap_insert (rfd->ti, rfd->ti->tmpbuf, i); + else + { + isc_pp_close (rfd->ispt[i]); + rfd->ispt[i] = NULL; + } + } + r_rewind (rfd); + return rfd; +} + +static void r_close (RSFD rfd) +{ + struct rset_mor_info *info = ((struct rset_mor_rfd*)rfd)->info; + struct rset_mor_rfd **rfdp; + int i; + + for (rfdp = &info->rfd_list; *rfdp; rfdp = &(*rfdp)->next) + if (*rfdp == rfd) + { + *rfdp = (*rfdp)->next; + + heap_close (((struct rset_mor_rfd *) rfd)->ti); + for (i = 0; ino_isam_positions; i++) + if (((struct rset_mor_rfd *) rfd)->ispt[i]) + isc_pp_close (((struct rset_mor_rfd *) rfd)->ispt[i]); + free (((struct rset_mor_rfd *)rfd)->ispt); + free (rfd); + return; + } + logf (LOG_FATAL, "r_close but no rfd match!"); + assert (0); +} + +static void r_delete (RSET ct) +{ + struct rset_mor_info *info = ct->buf; + + assert (info->rfd_list == NULL); + xfree (info->isam_positions); + xfree (info); +} + +static void r_rewind (RSFD rfd) +{ +} + +static int r_count (RSET ct) +{ + return 0; +} + +static int r_read (RSFD rfd, void *buf) +{ + struct trunc_info *ti = ((struct rset_mor_rfd *) rfd)->ti; + int n = ti->indx[ti->ptr[1]]; + + if (!ti->heapnum) + return 0; + memcpy (buf, ti->heap[ti->ptr[1]], ti->keysize); + heap_delete (ti); + if (isc_pp_read (((struct rset_mor_rfd *) rfd)->ispt[n], ti->tmpbuf)) + heap_insert (ti, ti->tmpbuf, n); + else + { + isc_pp_close (((struct rset_mor_rfd *) rfd)->ispt[n]); + ((struct rset_mor_rfd*) rfd)->ispt[n] = NULL; + } + return 1; +} + +static int r_score (RSFD rfd, int *score) +{ + *score = -1; + return -1; +} + +static int r_write (RSFD rfd, const void *buf) +{ + logf (LOG_FATAL, "mor set type is read-only"); + return -1; +}