ind_scan.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:18k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  ind_scan.c  - Index Control Programm
  3.  *               functions dealing with scanning of an index
  4.  *               Kernel of GNU SQL-server
  5.  *
  6.  * This file is a part of GNU SQL Server
  7.  *
  8.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  9.  *  Developed at the Institute of System Programming
  10.  *  This file is written by  Vera Ponomarenko
  11.  *
  12.  *  This program is free software; you can redistribute it and/or modify
  13.  *  it under the terms of the GNU General Public License as published by
  14.  *  the Free Software Foundation; either version 2 of the License, or
  15.  *  (at your option) any later version.
  16.  *
  17.  *  This program is distributed in the hope that it will be useful,
  18.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  *  GNU General Public License for more details.
  21.  *
  22.  *  You should have received a copy of the GNU General Public License
  23.  *  along with this program; if not, write to the Free Software
  24.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25.  *
  26.  *  Contacts:   gss@ispras.ru
  27.  *
  28.  */
  29. /* $Id: ind_scan.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  30. #include "xmem.h"
  31. #include "destrn.h"
  32. #include "sctp.h"
  33. #include "strml.h"
  34. #include "fdcltrn.h"
  35. extern struct des_field *d_f, *d_f2;
  36. extern u2_t seg_n;
  37. extern u2_t *afn;
  38. extern u2_t k_n;
  39. extern i4_t k2sz;
  40. static char *
  41. find_first_key (struct A *pg, u2_t pn)
  42. {
  43.   char *asp = NULL, *a;
  44.   u2_t cpn, ppn;
  45.   struct ind_page *indph;
  46.   while ((asp = getpg (pg, seg_n, pn, 's')) == NULL);
  47.   indph = (struct ind_page *) asp;
  48.   for (; indph->ind_wpage != LEAF;)
  49.     {
  50.       a = asp + indphsize + size2b;
  51.       a += kszcal (a, afn, d_f) + k2sz;
  52.       cpn = t2bunpack (a);
  53.       putwul (pg, 'n');
  54.       ppn = pg->p_pn;
  55.       while ((asp = getpg (pg, seg_n, cpn, 's')) == NULL);
  56.       indph = (struct ind_page *) asp;
  57.       BUF_unlock (seg_n, 1, &ppn);
  58.     }
  59.   return (asp);
  60. }
  61. #define BETWEEN_CMP  (t == SS || t == SES || t == SSE || t == SESE)
  62. static int
  63. cmp_with_dia (char *key, char *diasc, char *diaval)
  64. {
  65.   char *kval, *keyval;
  66.   i4_t sst, k1, ftype, v, v1;
  67.   char *a1, *a2;
  68.   u2_t k, nk, n1, n2;
  69.   unsigned char t;
  70.   sst = 1;
  71.   kval = keyval = key + scscal (key);
  72.   t = selsc1 (&diasc, sst++);
  73.   v = v1 = 0;
  74.   for (k = 0, k1 = 0; t != ENDSC && k < k_n && key < keyval; k++, k1++)
  75.     {
  76.       if (k1 == 7)
  77. {
  78.   k1 = 0;
  79.   key++;
  80. }
  81.       if ((*key & BITVL(k1)) != 0)
  82. {
  83.   if (t == EQUN)
  84.     return (1);
  85.   ftype = (d_f + afn[k])->field_type;
  86.   if (t == NEQUN || t == ANY)
  87.     kval = proval (kval, ftype);
  88.   else
  89.     {
  90.       switch (ftype)
  91. {
  92. case T1B:
  93.   diaval = ftint (t, diaval, &a1, &a2, size1b);
  94.   v = f1b (kval, a1, size1b, size1b);
  95.   if (BETWEEN_CMP)
  96.     v1 = f1b (kval, a2, size1b, size1b);
  97.   kval++;
  98.   break;
  99. case T2B:
  100.   diaval = ftint (t, diaval, &a1, &a2, size2b);
  101.   v = f2b (kval, a1, size2b, size2b);
  102.   if (BETWEEN_CMP)
  103.     v1 = f2b (kval, a2, size2b, size2b);
  104.   kval += size2b;
  105.   break;
  106. case T4B:
  107.   diaval = ftint (t, diaval, &a1, &a2, size4b);
  108.   v = f4b (kval, a1, size4b, size4b);
  109.   if (BETWEEN_CMP)
  110.     v1 = f4b (kval, a2, size4b, size4b);
  111.   kval += size4b;
  112.   break;
  113. case TFLOAT:
  114.   diaval = ftint (t, diaval, &a1, &a2, size4b);
  115.   v = flcmp (kval, a1, size4b, size4b);
  116.   if (BETWEEN_CMP)
  117.     v1 = flcmp (kval, a2, size4b, size4b);
  118.   kval += size4b;
  119.   break;
  120. case TFL:
  121.   nk = t2bunpack (kval);
  122.   kval += size2b;
  123.   diaval = ftch (t, diaval, &a1, &a2, &n1, &n2);
  124.   v = ffloat (kval, a1, nk, n1);
  125.   if (BETWEEN_CMP)
  126.     v1 = ffloat (kval, a2, nk, n2);
  127.   kval += nk;
  128.   break;
  129. case TCH:
  130.   nk = t2bunpack (kval);
  131.   kval += size2b;
  132.   diaval = ftch (t, diaval, &a1, &a2, &n1, &n2);
  133.   v = chcmp (kval, a1, nk, n1);
  134.   if (BETWEEN_CMP)
  135.     v1 = chcmp (kval, a2, nk, n2);
  136.   kval += nk;
  137.   break;
  138. default:
  139.   break;
  140. }
  141.       if (v == 0) /* current == first */
  142. {
  143.   if (t == SML)
  144.     return (EOI);
  145.   if (t == NEQ || t == GRT || t == SS || t == SSE)
  146.     return (1);
  147. }
  148.       else
  149. if (v > 0) /* current > first */
  150.   {
  151.     if (t == EQ || t == SML || t == SMLEQ)
  152.       return (EOI);
  153.     
  154.     if (BETWEEN_CMP)
  155.       if (v1 == 0) /* current == last */
  156. if (t == SS || t == SES)
  157.   return (EOI);
  158. else {}
  159.       else if (v1 > 0) /* current > last */
  160. return (EOI);
  161.   }
  162. else /* current < first */
  163.   {
  164.     if (!(t == NEQ || t == SML || t == SMLEQ))
  165.       return (1);
  166. }
  167.     }
  168. }
  169.       else
  170. { /* values are absent into the key */
  171.   if (!(t == EQUN || t == ANY))
  172.     return (EOI);
  173. }
  174.       t = selsc1 (&diasc, sst++);
  175.     }
  176.   if (key == keyval && t != ENDSC)
  177.     return (EOI);
  178.   return (OK);
  179. }
  180. #undef BETWEEN_CMP
  181. static char *
  182. find_next_agr (struct A *pg, char *diasc, char *diaval,
  183.                i4_t elsz, char *key, i4_t *agrloc)
  184. {
  185.   char *lastb, *agr, *asp = NULL;
  186.   struct ind_page *indph;
  187.   u2_t pn, ppn, n, off;
  188.   i4_t keysz, l;
  189.   asp = pg->p_shm;
  190.   pn = pg->p_pn;
  191.   indph = (struct ind_page *) asp;
  192.   for (;;)
  193.     {
  194.       off = indph->ind_off;
  195.       lastb = asp + off;
  196.       for (; key < lastb; key += keysz + n * elsz)
  197. {
  198.   agr = key;
  199.   n = t2bunpack (key);
  200.   key += size2b;
  201.   keysz = kszcal (key, afn, d_f);
  202.   if (diasc == NULL)
  203.     {
  204.       *agrloc = agr - asp;
  205.       return (key + keysz);
  206.     }
  207.   if ((l = cmp_with_dia (key, diasc, diaval)) == EOI)
  208.             return (NULL);
  209.   if (l == OK)
  210.     {
  211.       *agrloc = agr - asp;
  212.       return (key + keysz);
  213.     }
  214. }
  215.       pn = indph->ind_nextpn;
  216.       if (pn == (u2_t) ~ 0)
  217.         return (NULL);
  218.       putwul (pg, 'n');
  219.       ppn = pg->p_pn;
  220.       while ((asp = getpg (pg, seg_n, pn, 's')) == NULL);
  221.       indph = (struct ind_page *) asp;
  222.       BUF_unlock (seg_n, 1, &ppn);
  223.       key = asp + indphsize;
  224.     }
  225. }
  226. static char *
  227. first_key_frm (char *diasc, char *diaval, char *mas)
  228. {
  229.   char *a;
  230.   i4_t ftype;
  231.   u2_t size;
  232.   unsigned char t;
  233.   t = selsc1 (&diasc, 1);
  234.   if (t == EQ || t == GRT || t == GRTEQ || t == SS || t == SES || t == SSE || t == SESE)
  235.     {
  236.       a = mas;
  237.       ftype = (d_f + afn[0])->field_type;
  238.       if (ftype == TCH || ftype == TFL)
  239. {
  240.   size = t2bunpack (diaval);
  241.   diaval += size2b;
  242.   t2bpack (size, a);
  243.   a += size2b;
  244. }
  245.       else
  246. size = (d_f + afn[0])->field_size;
  247.       bcopy (diaval, a, size);
  248.     }
  249.   else
  250.     mas = NULL;
  251.   return (mas);
  252. }
  253. static int
  254. cmpfval (char *key, char *aval)
  255.      /* key - in the index, aval - from diasc */
  256. {
  257.   char *kval;
  258.   i4_t ftype, v = 0;
  259.   u2_t nk, n1;
  260.   kval = key + scscal (key);
  261.   if ((*key & BITVL(0)) != 0)
  262.     {
  263.       ftype = (d_f + afn[0])->field_type;
  264.       switch (ftype)
  265. {
  266. case T1B:
  267.   v = f1b (kval, aval, size1b, size1b);
  268.   break;
  269. case T2B:
  270.   v = f2b (kval, aval, size2b, size2b);
  271.   break;
  272. case T4B:
  273.   v = f4b (kval, aval, size4b, size4b);
  274.   break;
  275. case TFLOAT:
  276.   v = flcmp (kval, aval, size4b, size4b);
  277.   break;
  278. case TFL:
  279.   nk = t2bunpack (kval);
  280.   kval += size2b;
  281.   n1 = t2bunpack (aval);
  282.   aval += size2b;
  283.   v = ffloat (kval, aval, nk, n1);
  284.   break;
  285. case TCH:
  286.   nk = t2bunpack (kval);
  287.   kval += size2b;
  288.   n1 = t2bunpack (aval);
  289.   aval += size2b;
  290.   v = chcmp (kval, aval, nk, n1);
  291.   break;
  292. default:
  293.   break;
  294. }
  295.     }
  296.   else
  297.     v = 1;
  298.   return (v);
  299. }
  300. static char *
  301. flookup (struct A *pg, u2_t pn, char *key, i4_t infsz, char **rasp)
  302. {
  303.   char *asp = NULL, *a, *lastb;
  304.   u2_t ppn, off;
  305.   i4_t elsz;
  306.   u2_t n;
  307.   struct ind_page *indph;
  308.   while ((asp = getpg (pg, seg_n, pn, 's')) == NULL);
  309.   indph = (struct ind_page *) asp;
  310.   for (; indph->ind_wpage != LEAF;)
  311.     {
  312.       off = indph->ind_off;
  313.       lastb = asp + off;
  314.       elsz = k2sz + size2b;
  315.       for (a = asp + indphsize; a < lastb; a += kszcal (a, afn, d_f) + n * elsz)
  316. {
  317.   n = t2bunpack (a);
  318.   a += size2b;
  319.   if (cmpfval (a, key) >= 0)
  320.     {
  321.       a += kszcal (a, afn, d_f) + k2sz;
  322.       break;
  323.     }
  324. }
  325.       if (a == lastb)
  326. {
  327.   *rasp = asp;
  328.   return (a);
  329. }
  330.       pn = t2bunpack (a);
  331.       a += size2b;
  332.       putwul (pg, 'n');
  333.       ppn = pg->p_pn;
  334.       while ((asp = getpg (pg, seg_n, pn, 's')) == NULL);
  335.       indph = (struct ind_page *) asp;
  336.       BUF_unlock (seg_n, 1, &ppn);
  337.     }
  338.   elsz = k2sz + infsz;
  339.   off = indph->ind_off;
  340.   lastb = asp + off;
  341.   for (a = asp + indphsize; a < lastb; a += kszcal (a, afn, d_f) + n * elsz)
  342.     {
  343.       n = t2bunpack (a);
  344.       a += size2b;
  345.       if (cmpfval (a, key) >= 0)
  346. {
  347.   a -= size2b;
  348.   break;
  349. }
  350.     }
  351.   *rasp = asp;
  352.   return (a);
  353. }
  354. int
  355. fscan_ind (struct ldesscan *desscn, char *key2, char *inf, i4_t infsz, char modescan)
  356. {
  357.   char *a, *diasc, *diaval, *ckey;
  358.   u2_t rootpn, d_fn;
  359.   struct ldesind *desind;
  360.   struct A pg;
  361.   i4_t agrloc, keysz;
  362.   char *asp, *key;
  363.   char mas[BD_PAGESIZE];
  364.   desind = desscn->pdi;
  365.   rootpn = desind->ldi.rootpn;
  366.   seg_n = desind->i_segn;
  367.   diasc = desscn->dpnsc;
  368.   diaval = desscn->dpnsval;
  369.   afn = (u2_t *) (desind + 1);
  370.   k_n = desind->ldi.kifn & ~UNIQ & MSK21B;
  371.   d_f = desind->pdf;
  372.   d_fn = k_n;
  373.   if ((k_n % 2) != 0)
  374.     d_fn += 1;
  375.   d_f2 = (struct des_field *) (afn + d_fn);
  376.   k2sz = d_f2->field_size;
  377.   if (diasc != NULL)
  378.     {
  379.       diasc += size2b;
  380.       key = first_key_frm (diasc, diaval, mas);
  381.       if (key != NULL)
  382. {
  383.   a = flookup (&pg, rootpn, key, infsz, &asp);
  384. }
  385.       else
  386. {
  387.   asp = find_first_key (&pg, rootpn);
  388.   a = asp + indphsize;
  389. }
  390.       a = find_next_agr (&pg, diasc, diaval, k2sz + infsz, a, &agrloc);
  391.       asp = pg.p_shm;
  392.       if (a == NULL)
  393. {
  394.   desscn->curlpn = (u2_t) ~ 0;
  395.   putpg (&pg, 'n');
  396.   return (EOI);
  397. }
  398.     }
  399.   else
  400.     {
  401.       asp = find_first_key (&pg, rootpn);
  402.       if (((struct ind_page *) asp)->ind_off == indphsize)
  403. {
  404.   desscn->curlpn = (u2_t) ~ 0;
  405.   putpg (&pg, 'n');
  406.   return (EOI);
  407. }
  408.       a = asp + indphsize;
  409.       agrloc = a - asp;
  410.       a += size2b; 
  411.       a += kszcal (a, afn, d_f);
  412.     }
  413.   bcopy (a, key2, k2sz);
  414.   a += k2sz;
  415.   if (inf != NULL)
  416.     {
  417.       bcopy (a, inf, infsz);
  418.       a += infsz;
  419.     }
  420.   /* write cursors into desscn */
  421.   desscn->curlpn = pg.p_pn;
  422.   desscn->offa = agrloc;
  423.   desscn->offp = a - asp - k2sz - infsz;
  424.   desscn->sidmod = ((struct p_head *) asp)->idmod;
  425.   a = asp + agrloc + size2b;
  426.   keysz = kszcal (a, afn, d_f);
  427.   ckey = (char *) xmalloc (keysz);
  428.   desscn->cur_key = ckey;
  429.   bcopy (a, ckey, keysz);
  430.   if (modescan == FASTSCAN)
  431.     putwul (&pg, 'n');
  432.   else
  433.     putpg (&pg, 'n');
  434.   return (OK);
  435. }
  436. static
  437. int
  438. find_next_key(struct ldesscan *desscn, struct A *pg, char *diasc, char *diaval, i4_t elsz, char *agr, char *pnt, i4_t *agrloc, i4_t *lockey)
  439. {
  440.   i4_t agsz;
  441.   u2_t n;
  442.   char *asp;
  443.   asp = pg->p_shm;
  444.   *agrloc = agr - asp;
  445.   n = t2bunpack (agr);
  446.   agsz = size2b + kszcal (agr + size2b, afn, d_f) + n * elsz;
  447.   pnt += elsz;
  448.   if (pnt == agr + agsz)
  449.     {
  450.       pnt = find_next_agr (pg, diasc, diaval, elsz, pnt, agrloc);
  451.       if (pnt == NULL)
  452. {
  453.   putpg (pg, 'n');
  454.   desscn->curlpn = (u2_t) ~ 0;
  455.   return (EOI);
  456. }
  457.       asp = pg->p_shm;
  458.     }
  459.   *lockey = pnt - asp;
  460.   return (OK);
  461. }
  462. static
  463. char *
  464. look_up(struct A *pg, u2_t pn, char *key, char *key2, i4_t infsz, char **agr, char **loc)
  465. {
  466.   char *a, *lastb, *asp = NULL;
  467.   i4_t elsz, l, l2 = 0, ksz;
  468.   u2_t n, ppn;
  469.   struct ind_page *indph;
  470.   while ((asp = getpg (pg, seg_n, pn, 's')) == NULL);
  471.   indph = (struct ind_page *) asp;
  472.   elsz = k2sz + size2b;
  473.   for (; indph->ind_wpage != LEAF;)
  474.     {
  475.       lastb = asp + indph->ind_off;
  476.       for (a = asp + indphsize; a < lastb; )
  477. {
  478.   n = t2bunpack (a);
  479.   a += size2b;
  480.           ksz = kszcal (a, afn, d_f);
  481.   if ((l = cmpkeys (k_n, afn, d_f, a, key)) == 0)
  482.     {
  483.       a += ksz;
  484.               for (; n != 0; n--, a += elsz)
  485.                 if ((l2 = cmp2keys (d_f2->field_type, a, key2)) < 0)
  486.                   continue;
  487.                 else
  488.                   break;
  489.               if (n == 0 && l2 < 0)
  490.                 continue;
  491.               if (n == 0)
  492.                 a -= elsz;
  493.       break;
  494.     }
  495.           else if (l > 0)
  496.     {
  497.       a += ksz;
  498.       break;
  499.     }
  500.           a += ksz + n * elsz;
  501. }
  502.       if (a == lastb)
  503. {
  504.   *loc = NULL;
  505.   return (NULL);
  506. }
  507.       a += k2sz;
  508.       ppn = pn;
  509.       pn = t2bunpack (a);
  510.       putwul (pg, 'n');
  511.       while ((asp = getpg (pg, seg_n, pn, 's')) == NULL);
  512.       indph = (struct ind_page *) asp;
  513.       BUF_unlock (seg_n, 1, &ppn);
  514.     }
  515.   lastb = asp + indph->ind_off;
  516.   a = asp + indphsize;
  517.   if (a == lastb)
  518.     {
  519.       *loc = NULL;
  520.       return (NULL);
  521.     }
  522.   elsz = k2sz + infsz;
  523.   for (; a < lastb; a += kszcal (a, afn, d_f) + n * elsz)
  524.     {
  525.       *agr = a;
  526.       n = t2bunpack (a);
  527.       a += size2b;
  528.       if ((l = cmpkeys (k_n, afn, d_f, a, key)) == 0)
  529. {
  530.   a += kszcal (a, afn, d_f);
  531.   for (; n != 0; n--, a += elsz)
  532.     {
  533.       if ((l2 = cmp2keys (d_f2->field_type, a, key2)) < 0)
  534. continue;
  535.               if (l2 == 0)
  536.                 {
  537.                   *loc = a;
  538.                   return (a);
  539.                 }
  540.               *loc = a;
  541.               return (NULL);
  542.     }
  543.   *loc = a;
  544.           return (NULL);
  545. }
  546.       else if (l > 0)
  547. {
  548.   a += kszcal (a, afn, d_f);
  549.           *loc = a;
  550.   return (NULL);
  551. }
  552.     }
  553.   *loc = NULL;
  554.   return (NULL);
  555. }
  556. int
  557. scan_ind (struct ldesscan *desscn, char *key2, char *inf, i4_t infsz, char modescan)
  558. {
  559.   char *asp = NULL, *a, *lastb, *diasc, *diaval, *ckey;
  560.   u2_t pn, n, d_fn, off;
  561.   i4_t elsz, agrloc, loc;
  562.   struct ind_page *indph;
  563.   struct ldesind *desind;
  564.   struct A pg;
  565.   char *agr, *lockey;
  566.   i4_t keysz;
  567.   i4_t l, l2=0;
  568.   pn = desscn->curlpn;
  569.   if (pn == (u2_t) ~ 0)
  570.     return (EOI);
  571.   diasc = desscn->dpnsc + size2b;
  572.   diaval = desscn->dpnsval;
  573.   desind = desscn->pdi;
  574.   seg_n = desind->i_segn;
  575.   afn = (u2_t *) (desind + 1);
  576.   k_n = desind->ldi.kifn & ~UNIQ & MSK21B;
  577.   d_f = desind->pdf;
  578.   d_fn = k_n;
  579.   if ((k_n % 2) != 0)
  580.     d_fn += 1;
  581.   d_f2 = (struct des_field *) (afn + d_fn);
  582.   k2sz = d_f2->field_size;
  583.   elsz = k2sz + infsz;
  584.   if (modescan == FASTSCAN)
  585.     asp = getwl (&pg, seg_n, pn);
  586.   else
  587.     while ((asp = getpg (&pg, seg_n, pn, 's')) == NULL);
  588.   indph = (struct ind_page *) asp;
  589.   off = indph->ind_off;
  590.   lastb = asp + off;
  591.   if (desscn->sidmod != indph->ind_ph.idmod)
  592.     {
  593.       ckey = desscn->cur_key;
  594.       a = asp + indphsize;
  595.       if (a < lastb && cmpkeys (k_n, afn, d_f, a + size2b, ckey) <= 0)
  596.         {         /* look up in this page */
  597.           for (; a < lastb; a += kszcal (a, afn, d_f) + n * elsz)
  598.             {
  599.               agr = a;
  600.               n = t2bunpack (a);
  601.               a += size2b;
  602.               if ((l = cmpkeys (k_n, afn, d_f, a, ckey)) >= 0)
  603.                 {
  604.                   a += kszcal (a, afn, d_f);
  605.                   if (l == 0)         /* current key is present */
  606.                     {
  607.                       for (; n != 0; n--, a += elsz)
  608.                         if ((l2 = cmp2keys (d_f2->field_type, a, key2)) < 0)
  609.                           continue;
  610.                         else
  611.                           break;
  612.                       if (l2 == 0)     /* current key2 is present */
  613.                         {
  614.                           if (find_next_key (desscn, &pg, diasc, diaval, elsz, agr, a, &agrloc, &loc) == EOI)
  615.                             return (EOI);
  616.                           goto m1;
  617.                         }
  618.                       else             /* current key2 is absent */
  619.                         {
  620.                           agrloc = agr - asp;
  621.                           loc = a - asp;
  622.                           goto m1;
  623.                         }
  624.                     }
  625.                   else                 /* current key is absent */
  626.                     {
  627.                       if (cmp_with_dia (agr + size2b, diasc, diaval) == EOI)
  628.                         {
  629.                           putpg (&pg, 'n');
  630.                           return (EOI);
  631.                         }
  632.                       agrloc = agr - asp;      /* next key */
  633.                       loc = a - asp;
  634.                       goto m1;
  635.                     }
  636.                 }
  637.             }
  638.         }
  639.       putpg (&pg, 'n');
  640.       look_up(&pg, desind->ldi.rootpn, desscn->cur_key, key2, infsz, &agr, &lockey);
  641.       /*      a = icp_lookup (&pg, desind, desscn->cur_key, key2, infsz, &agr, &lockey);*/
  642.       asp = pg.p_shm;
  643.       if (lockey == NULL)
  644.         {
  645.           desscn->curlpn = (u2_t) ~ 0;
  646.           putpg (&pg, 'n');
  647.           return (EOI);
  648.         }
  649.       if (a == NULL)    /* current key is absent */
  650.         {
  651.           if (cmp_with_dia (agr + size2b, diasc, diaval) == EOI)
  652.             {
  653.               putpg (&pg, 'n');
  654.               return (EOI);
  655.             }
  656.           loc = lockey - asp;
  657.           agrloc = agr - asp;
  658.         }
  659.       else              /* current key is present */
  660.         {
  661.           if (find_next_key (desscn, &pg, diasc, diaval, elsz, agr, lockey, &agrloc, &loc) == EOI)
  662.             return (EOI);
  663.         }
  664.     }
  665.   else
  666.     {
  667.       agr = asp + desscn->offa;
  668.       a = asp + desscn->offp;
  669.       if (find_next_key (desscn, &pg, diasc, diaval, elsz, agr, a, &agrloc, &loc) == EOI)
  670.         return (EOI);
  671.     }
  672. m1:
  673.   asp = pg.p_shm;
  674.   a = asp + loc;
  675.   bcopy (a, key2, k2sz);
  676.   a += k2sz;
  677.   if (inf != NULL)
  678.     bcopy (a, inf, infsz);
  679.   /* write cursors into desscn */
  680.   desscn->curlpn = pg.p_pn;
  681.   desscn->offa = agrloc;
  682.   desscn->offp = loc;
  683.   desscn->sidmod = ((struct p_head *) asp)->idmod;
  684.   if (desscn->cur_key != NULL)
  685.     xfree (desscn->cur_key);
  686.   a = asp + agrloc + size2b;
  687.   keysz = kszcal (a, afn, d_f);
  688.   ckey = (char *) xmalloc (keysz);
  689.   desscn->cur_key = ckey;
  690.   bcopy (a, ckey, keysz);
  691.   if (modescan == SLOWSCAN)
  692.     putpg (&pg, 'n');
  693.   else
  694.     putwul (&pg, 'n');
  695.   return (OK);
  696. }
  697. char *
  698. icp_lookup (struct A *pg, struct ldesind *desind, char *key, char *key2, i4_t infsz, char **agr, char **loc)
  699. {
  700.   u2_t d_fn;
  701.   seg_n = desind->i_segn;
  702.   afn = (u2_t *) (desind + 1);
  703.   k_n = desind->ldi.kifn & ~UNIQ & MSK21B;
  704.   d_f = desind->pdf;
  705.   d_fn = k_n;
  706.   if ((k_n % 2) != 0)
  707.     d_fn += 1;
  708.   d_f2 = (struct des_field *) (afn + d_fn);
  709.   k2sz = d_f2->field_size;
  710.   return (look_up(pg, desind->ldi.rootpn, key, key2, infsz, agr, loc));
  711. }