Annotation of 43BSD/ingres/source/iutil/ndxsearch.c, revision 1.1

1.1     ! root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.