1: # include   <ingres.h>
   2: # include   <aux.h>
   3: # include   <symbol.h>
   4: # include   <access.h>
   5: # include   <lock.h>
   6: # include   <sccs.h>
   7: 
   8: SCCSID(@(#)ndxsearch.c	8.1	12/31/84)
   9: 
  10: 
  11: /*
  12: **  NDXSEARCH -- search an ISAM directory
  13: **
  14: **	Looks for an available page, if this would force out a page from
  15: **	the relation it adds its own.  Searches each level of the dirctory
  16: **	for the lowest (highest) page on which the key could occur if mode
  17: **	is < (>) 0.  At each level the number of keys on the page is checked
  18: **	if it is <= SEARCHFUDGE a linear sharch is done, otherwize a binary
  19: **	search is preformed.  If the full key matches exactly the seach
  20: **	can stop.  Note that the keys tell the minimum value on that page.
  21: **
  22: **	Parameters:
  23: **		d	- pointer to descriptor of open relation
  24: **		tid	- returns tid of page to start (end) looking
  25: **		key	- to look for
  26: **		mode	- < 0 lowkey, > 0 hikey
  27: **		keyok	- true if all keys are assumed to be set
  28: **
  29: **	Returns:
  30: **		-2	- pageflush failure
  31: **		-1	- get_page failure
  32: **		0	- success
  33: **
  34: **	Side Effects:
  35: **		causes I/O
  36: */
  37: 
  38: # define    SEARCHFUDGE 6   /* # of linenos to do a binary search */
  39: 
  40: ndxsearch(d, tid, tuple, mode, keyok)
  41: DESC        *d;
  42: register TID    *tid;
  43: char        tuple[];
  44: int     mode;
  45: int     keyok;
  46: {
  47:     register int        i;
  48:     long            pageid;
  49:     int         j, keylen, dno, partialkey;
  50:     char            *p;
  51:     int         pagerr;
  52:     struct accessparam  relparm;
  53:     int         top;
  54:     register        bottom;
  55:     extern char     *get_addr();
  56: 
  57:     pagerr = 0;
  58:     paramd(d, &relparm);    /* get domains in key order */
  59: 
  60:     /* assume fullkey is given */
  61:     partialkey = FALSE;
  62: 
  63:     /* remove any key domains not given by the user */
  64:     if (!keyok)
  65:     {
  66:         for (i = 0; dno = relparm.keydno[i]; i++)
  67:         {
  68:             if (d->relgiven[dno])
  69:                 continue;
  70:             relparm.keydno[i] = 0;
  71:             partialkey = TRUE;
  72:             break;
  73:         }
  74:     }
  75: 
  76:     /* if the first key isn't given, just return else search directory */
  77:     if (relparm.keydno[0] != 0)
  78:     {
  79:         /* The actual ISAM directory search must be performed */
  80:         pageid = d->reldum.relprim;
  81:         stuff_page(tid, &pageid);
  82: 
  83:         Acclock = FALSE;
  84: 
  85:         do
  86:         {
  87:             if (pagerr = get_page(d, tid))
  88:                 break;  /* fatal error */
  89:             Acc_head->bufstatus |= BUF_DIRECT;  /* don't get confused */
  90:             bottom = 0;
  91:             top = Acc_head->nxtlino - 1;
  92: 
  93:             if (top >= SEARCHFUDGE)  /* we are past breakeven */
  94:             {
  95:                 while (top != bottom)   /* binary search */
  96:                 {
  97:                     tid->line_id = ((1 + top - bottom) >> 1) + bottom;  /* get to half way point */
  98:                     p = get_addr(tid);
  99:                     for (j = 0; dno = relparm.keydno[j]; j++)
 100:                     {
 101:                         keylen = d->relfrml[dno] & I1MASK;
 102:                         if (i = icompare(&tuple[d->reloff[dno]], p, d->relfrmt[dno], keylen))
 103:                             break;
 104:                         p += keylen;
 105:                     }
 106:                     /* if key is below directory, then we are in the bottom half */
 107:                     if (i < 0 || (i == 0 && partialkey && mode < 0))
 108:                         top = (tid->line_id & I1MASK) - 1;
 109: 
 110:                     else if (i == 0 && !partialkey)
 111:                     {
 112:                         bottom = (tid->line_id & I1MASK);
 113:                         break;
 114:                     }
 115:                     else
 116:                         bottom = (tid->line_id & I1MASK);
 117:                 }
 118:             }
 119:             else    /* do a linar search */
 120:             {
 121:                 for (tid->line_id = 0; (tid->line_id & I1MASK) < Acc_head->nxtlino; tid->line_id++)
 122:                 {
 123:                     p = get_addr(tid);
 124:                     for (i = 0; dno = relparm.keydno[i]; i++)
 125:                     {
 126:                         keylen = d->relfrml[dno] & I1MASK;
 127:                         if (j = icompare(&tuple[d->reloff[dno]], p, d->relfrmt[dno], keylen))
 128:                             break;
 129:                         p += keylen;
 130:                     }
 131:                     /* if key is below directory, then we have passed the position */
 132:                     if (j < 0)
 133:                         break;
 134: 
 135:                     /* if lowkey search on partial key matches, then done */
 136:                     if (j == 0 && partialkey && mode < 0)
 137:                         break;
 138:                     bottom = tid->line_id;
 139:                     if (j == 0 && mode < 0)
 140:                         break;
 141:                 }
 142:             }
 143:             pageid = Acc_head->ovflopg + bottom;
 144:             stuff_page(tid, &pageid);
 145:         } while (Acc_head->mainpg);  /* if at level zero then done */
 146:         Acclock = TRUE;
 147: 
 148:     }
 149:     tid->line_id = -1;
 150:     return (pagerr);
 151: }

Defined functions

ndxsearch defined in line 8; used 2 times

Defined macros

SEARCHFUDGE defined in line 38; used 1 times
  • in line 93
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 910
Valid CSS Valid XHTML 1.0 Strict