home *** CD-ROM | disk | FTP | other *** search
- /*
- * index search routines
- *
- * This program is the CONFIDENTIAL and PROPRIETARY property
- * of FairCom(R) Corporation. Any unauthorized use, reproduction or
- * transfer of this program is strictly prohibited.
- *
- * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989 FairCom Corporation
- * (Subject to limited distribution and
- * restricted disclosure only.)
- * *** ALL RIGHTS RESERVED ***
- *
- * 4006 West Broadway
- * Columbia, MO 65203
- *
- *
- * c-tree(R) Version 4.3
- * Release C
- * February 7, 1989 17:30
- *
- */
-
- #include "ctstdr.h" /* standard i/o header */
- #include "ctoptn.h" /* c-tree configuration options */
- #include "cterrc.h" /* c-tree error codes */
- #include "ctstrc.h" /* c-tree data structures */
- #include "ctgvar.h" /* c-tree global variables */
-
- COUNT compar();
-
- /* --------------------------------------------------------------------
- returns the "pointer" (ie, data record number or whatever) associated
- with the key value pointed to by target for the index file specified by
- keyno
- */
-
- POINTER EQLKEY(keyno,target)
-
- PFAST COUNT keyno;
- TEXT *target;
-
- {
- FAST KEYFILE *knum;
- LOCAL POINTER temp;
- POINTER fndkey();
- KEYFILE *tstfnm();
-
- uerr_cod = 0;
- if ((knum = tstfnm(keyno)) == NULL)
- return(DRNZERO);
-
- temp = fndkey(knum,target,'E');
- knum->retelm = ct_elm;
- knum->retnod = ct_fnode;
- return(temp);
- }
-
-
- /* -------------------------------------------------------------------
- returns the "pointer" associated with the first key value in the index
- file specified by keyno which is equal to or greater than the key value
- pointed to by target. if such an entry exists, then the variable pointed
- to by idxval is set equal to the key value found in the index file
- */
-
- POINTER GTEKEY(keyno,target,idxval)
-
- PFAST COUNT keyno;
- TEXT *target;
- TEXT *idxval;
-
- {
- FAST KEYFILE *knum;
- LOCAL POINTER temp;
- POINTER fndkey();
- KEYFILE *tstfnm();
-
- uerr_cod = 0;
- if ((knum = tstfnm(keyno)) == NULL)
- return(DRNZERO);
-
- if (temp = fndkey(knum,target,'G')) {
- knum->retelm = ct_elm;
- knum->retnod = ct_fnode;
- cpybuf(idxval,ct_indkey,knum->length);
- } else {
- knum->retelm = 0;
- knum->retnod = NODEZERO;
- setnul(idxval);
- }
- return(temp);
- }
-
-
- /* --------------------------------------------------------------------
- returns the "pointer" associated with the next key value (in ascending
- key value order) and sets the variable pointed to by idxval to this
- key value. this function is used to access the key values (and their
- associated "pointers" in ascending key value order.
- */
-
- POINTER NXTKEY(keyno,idxval)
-
- COUNT keyno;
- TEXT *idxval;
-
- {
- FAST KEYFILE *knum;
- FAST COUNT temp;
- FAST TREEBUFF *ret;
-
- POINTER drnpnt();
- TEXT *valpnt();
- TREEBUFF *getnod();
- KEYFILE *tstfnm();
-
- uerr_cod = 0;
- if ((knum = tstfnm(keyno)) == NULL)
- return(DRNZERO);
-
- again:
- if (!knum->retnod) {
- setnul(idxval);
- return(DRNZERO);
- }
- if ((ret = getnod(knum->retnod,knum)) == NULL) /* then error */
- return(DRNZERO);
- if ((temp = knum->retelm) < ret->nkv) {
- cpybuf(idxval,valpnt(ret,++temp),knum->length);
- knum->retelm = temp;
- return(drnpnt(ret,temp));
- } else {
- knum->retnod = ret->sucesr;
- knum->retelm = 0;
- goto again;
- }
- }
-
-
- /* --------------------------------------------------------------------
- returns the "pointer" associated with the previous key value and sets
- the variable pointed to by idxval equal to this key value. this function
- is used to access the key values (and their associated "pointers") in
- descending key value order.
- */
-
- POINTER PRVKEY(keyno,idxval)
-
- COUNT keyno;
- TEXT *idxval;
-
- {
- FAST TREEBUFF *ret;
- FAST COUNT prdtst,temp;
- FAST KEYFILE *knum;
- LONG oldnode;
-
- POINTER drnpnt();
- TEXT *valpnt();
- TREEBUFF *getnod();
- KEYFILE *tstfnm();
- COUNT uerr();
-
- uerr_cod = 0;
- if ((knum = tstfnm(keyno)) == NULL)
- return(DRNZERO);
-
- if(!knum->retnod) {
- setnul(idxval);
- return(DRNZERO);
- }
-
- prdtst = PRDRPEAT;
-
- split:
- if ((ret = getnod((oldnode = knum->retnod),knum)) == NULL)
- return(DRNZERO); /* then error */
- again2:
- if ((temp = knum->retelm) > 1) {
- cpybuf(idxval,valpnt(ret,--temp),knum->length);
- knum->retelm = temp;
- return(drnpnt(ret,temp));
- } else if (knum->retnod = ret->predsr) {
- if ((ret = getnod(knum->retnod,knum)) == NULL) /* then error */
- return(DRNZERO);
- if ((temp = ret->nkv) < 0)
- terr(211);
- if (oldnode != ret->sucesr) {
- if (!(prdtst--)) {
- uerr(PRDS_ERR);
- return(DRNZERO);
- }
- knum->retnod = oldnode;
- goto split; /* node splitting at time of request */
- }
- knum->retelm = temp;
- if (!temp) {
- oldnode = knum->retnod;
- goto again2;
- }
- cpybuf(idxval,valpnt(ret,temp),knum->length);
- return(drnpnt(ret,temp));
- } else {
- setnul(idxval);
- return(DRNZERO);
- }
- }
-
- /* --------------------------------------------------------------------
- find first index entry.
- */
-
- POINTER FRSKEY(keyno,idxval)
-
- PFAST COUNT keyno;
- TEXT *idxval;
-
- {
- LOCAL LONG node;
- FAST TREEBUFF *buffer;
- FAST KEYFILE *knum;
-
- TREEBUFF *getnod();
- COUNT uerr();
- KEYFILE *tstfnm();
- LONG gtroot(),nodpnt();
- TEXT *valpnt();
- POINTER drnpnt();
-
- uerr_cod = 0;
- if ((knum = tstfnm(keyno)) == NULL)
- return(DRNZERO);
-
- if (!(node = gtroot(knum)))
- goto empty;
-
- while (node) { /* walk down tree until leaf node found */
- if ((buffer = getnod(node,knum)) == NULL)
- return(DRNZERO);
- if (buffer->leaf == LEAF)
- break;
- node = nodpnt(buffer,1);
- }
- if (!node) /* => no leaf node found */
- terr(212);
-
- while (!buffer->nkv) /* walk across empty left most leaf nodes */
- if (!(node = buffer->sucesr))
- goto empty;
- else if ((buffer = getnod(node,knum)) == NULL)
- return(DRNZERO);
-
- knum->retnod = node;
- knum->retelm = 1;
- cpybuf(idxval,valpnt(buffer,1),knum->length);
- return(drnpnt(buffer,1));
-
- empty:
- setnul(idxval);
- knum->retelm = 0;
- knum->retnod = NODEZERO;
- return(DRNZERO);
-
- }
-
-
- /* --------------------------------------------------------------------
- find LAST index entry.
- */
-
- POINTER LSTKEY(keyno,idxval)
-
- FAST COUNT keyno;
- TEXT *idxval;
-
- {
- LOCAL LONG node;
- FAST TREEBUFF *buffer;
- FAST KEYFILE *knum;
- FAST COUNT tmpsiz;
-
- TREEBUFF *getnod();
- TEXT *valpnt();
- KEYFILE *tstfnm();
- LONG gtroot(),nodpnt();
- POINTER drnpnt();
-
- uerr_cod = 0;
- if ((knum = tstfnm(keyno)) == NULL)
- return(DRNZERO);
-
- if (!(node = gtroot(knum)))
- goto empty2;
-
- while (node) { /* walk down or across tree until leaf node found */
- if ((buffer = getnod(node,knum)) == NULL)
- return(DRNZERO);
- if (buffer->leaf == LEAF)
- break;
- if (!(node = buffer->sucesr))
- node = nodpnt(buffer,buffer->nkv);
- }
- if (!node) /* => no leaf node found */
- terr(213);
-
- while (!buffer->nkv) /* walk across empty rightmost leaf nodes */
- if(!(node = buffer->predsr))
- goto empty2;
- else if ((buffer = getnod(node,knum)) == NULL)
- return(DRNZERO);
-
- knum->retnod = node;
- knum->retelm = tmpsiz = buffer->nkv;
- cpybuf(idxval,valpnt(buffer,tmpsiz),knum->length);
- return(drnpnt(buffer,tmpsiz));
-
- empty2:
- setnul(idxval);
- knum->retelm = 0;
- knum->retnod = NODEZERO;
- return(DRNZERO);
- }
-
- /* ---------------------------------------------------------------------
- returns entry after target value
- */
-
- POINTER GTKEY(keyno,target,idxval)
-
- PFAST COUNT keyno;
- TEXT *target;
- TEXT *idxval;
-
-
- {
- POINTER GTEKEY(),NXTKEY();
- POINTER temp;
-
- if ((temp = GTEKEY(keyno,target,idxval)) == DRNZERO || ct_tky)
- return(temp);
- else
- return(NXTKEY(keyno,idxval));
- }
-
- /* ---------------------------------------------------------------------
- returns entry immediately before target
- */
-
- POINTER LTKEY(keyno,target,idxval)
-
- PFAST COUNT keyno;
- TEXT *target;
- TEXT *idxval;
-
-
- {
- POINTER EQLKEY(),PRVKEY();
-
- EQLKEY(keyno,target);
- return(PRVKEY(keyno,idxval));
- }
-
-
- /* ---------------------------------------------------------------------
- returns entry <= target
- */
-
- POINTER LTEKEY(keyno,target,idxval)
-
- PFAST COUNT keyno;
- TEXT *target;
- TEXT *idxval;
-
-
- {
- POINTER retval;
-
- POINTER EQLKEY(),PRVKEY();
-
- if (retval = EQLKEY(keyno,target)) {
- cpybuf(idxval,target,(ct_key + keyno)->length);
- return(retval);
- } else
- return(PRVKEY(keyno,idxval));
- }
-
-
- /* --------------------------------------------------------------------
- general purpose search routine. ordinarily not called by application
- program; but called from other searches: rtriev, search, etc.
- */
-
- POINTER fndkey(knum,idxval,stratg)
-
- PFAST KEYFILE *knum; /* pointer to ct_key structure (used like a ct_key #) */
- TEXT *idxval; /* pointer to target key value */
- TEXT stratg; /* search strategy indicator 'E'== equality
- 'G' == greater than or equal to search */
-
- {
- TREEBUFF *getnod();
- POINTER serlef();
- LONG gtroot(),nodpnt();
- TEXT *valpnt();
- COUNT nodser();
-
- LOCAL LONG node;
- LOCAL COUNT npoint;
- FAST TREEBUFF *buffer;
-
-
- ct_fnode = ct_lnode = 0; /* global var tracking last node visited */
- setnul(ct_indkey); /* set return key value to null */
- if (!(node = gtroot(knum))) { /* tree may be empty or error */
- ct_elm = 0;
- return(DRNZERO);
- }
-
- while (node) { /* walk down or across tree until leaf node found */
- ct_lnode = node;
- if ((buffer = getnod(node,knum)) == NULL) /* then error */
- return(DRNZERO);
- if (buffer->leaf == LEAF) /* then found bottom level of tree */
- break;
- if ((npoint = nodser(buffer,idxval,'L')) != -1) {
- if (npoint == -2) /* then corrupt tree */
- terr(214);
- /* get child node */
- node = nodpnt(buffer,npoint);
- } else
- /* move right because of incomplete tree update */
- node = buffer->sucesr;
- }
-
- if (!node) /* then no leaf node found */
- terr(215);
-
- return(serlef(idxval,knum,buffer,stratg)); /* search leaf node */
- }
-
-
- /* --------------------------------------------------------------------
- search leaf node
- */
-
- POINTER serlef(idxval,knum,buffer,stratg)
-
- TEXT *idxval; /* pointer to target key value */
- PFAST KEYFILE *knum; /* key number pointer */
- PFAST TREEBUFF *buffer; /* pointer to buffer containing leaf node */
- TEXT stratg; /* 'E/G': see fndkey */
-
- {
- LOCAL COUNT temp;
-
- COUNT nodser();
- POINTER drnpnt();
- TEXT *valpnt();
- TREEBUFF *getnod();
-
- /* see if it is necessary to move right along leaf nodes */
-
- while ((temp = nodser(buffer,idxval,stratg == 'E' ? 'E' : 'S')) == -1)
- if ((buffer = getnod((ct_lnode = buffer->sucesr),knum)) == NULL)
- return(DRNZERO); /* error in getnod */
-
- ct_fnode = ct_lnode;
- if (temp != -2) { /* then sucessful leaf search */
- cpybuf(ct_indkey,valpnt(buffer,temp),
- knum->length); /* copy key value found into ct_indkey. */
- return(drnpnt(buffer,temp));
- } else /* target not found */
- return(DRNZERO);
- }
-
- /* end of ctsrch.c */
-