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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  ind_rem.c  - Index Control Programm
  3.  *               functions dealing with key deletion from 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_rem.c,v 1.246 1997/04/15 11:45:41 vera Exp $ */
  30. #include "xmem.h"
  31. #include <assert.h>
  32. #include "destrn.h"
  33. #include "strml.h"
  34. #include "fdcltrn.h"
  35. extern struct des_field *d_f, *d_f2;
  36. extern u2_t *afn;
  37. extern u2_t k_n;
  38. extern u2_t seg_n;
  39. extern i4_t k2sz;
  40. extern i4_t inf_size;
  41. extern char uniq_key;
  42. i4_t  check_ind_page (char *asp);
  43. ARR_DECL(thread_s,u2_t,no_static); /* declaration of dynamic stack/array 'thread_s'. */
  44. ARR_PROC_PROTO(thread_s,u2_t);  /* declaration of routines for it               */
  45. ARR_DECL(l_emp,u2_t,static); /* declaration of local dynamic stack/array 'l_emp'. */
  46. ARR_PROC_DECL(l_emp,u2_t,static); /* declaration of routines for it               */
  47. static void
  48. alter_pn (i4_t remsz, i4_t elsz, char *rbeg, char *rloc, u2_t pn, i4_t idm,
  49.           char *asp, char *inf)   /* after removing */
  50. {
  51.   char *a;
  52.   u2_t n;
  53.   i4_t agsz, ksz;
  54.   n = t2bunpack (rbeg);
  55.   ksz = kszcal (rbeg + size2b, afn, d_f); 
  56.   agsz = size2b + ksz + n * elsz;
  57.   if (remsz == elsz && rloc != rbeg + agsz) /* the key was not last in the aggregate */
  58.     a = rloc + k2sz;
  59.   else
  60.     a = rbeg + size2b + ksz + k2sz;
  61.   recmjform (OLD, seg_n, pn, idm, a - asp, size2b, a, 0);
  62.   bcopy (inf, a, size2b);
  63. }
  64. static void
  65. remove_level (char *asp, u2_t rootpn, struct A *pg_down) 
  66. {
  67.   char *pnt, *asp_down;
  68.   u2_t off_down;
  69.   i4_t idm;
  70.   struct ind_page *indph, *indph_down;
  71.   asp_down = pg_down->p_shm;
  72.   idm = ++((struct p_head *) asp)->idmod;
  73.   indph = (struct ind_page *) asp;
  74.   pnt = asp + indphsize; 
  75.   recmjform (OLD, seg_n, rootpn, idm, indphsize, indph->ind_off - indphsize, pnt, 0);
  76.   indph_down = (struct ind_page *) asp_down;
  77.   if (indph_down->ind_wpage == LEAF)
  78.     {
  79.       pnt = (char *) &indph->ind_wpage;
  80.       recmjform (OLD, seg_n, rootpn, idm, pnt - asp, size2b, pnt, 0);
  81.       indph->ind_wpage = LEAF;
  82.     }
  83.   off_down = indph_down->ind_off;
  84.   pnt = asp + indphsize;
  85.   bcopy (asp_down + indphsize, pnt, off_down - indphsize);
  86.   pnt = (char *) &indph->ind_off;
  87.   recmjform (OLD, seg_n, rootpn, idm, pnt - asp, size2b, pnt, 0);
  88.   indph->ind_off = off_down;
  89.   putwul (pg_down, 'n');
  90.   l_emp_put (pg_down->p_pn);
  91. }
  92. static int
  93. rem_rec (struct A *pg, char *key, char *key2, i4_t infsz, char *newinf);
  94. static int
  95. rem_page (char *key, char *key2, u2_t *uppn, u2_t pn)
  96. {   /* remove a record about page from a middle level */
  97.   char *asp, inf[size2b];
  98.   struct A pg;
  99.   i4_t ans = 0;
  100.   struct ind_page *indph;
  101.   *uppn = *(--thread_s.u);
  102.   asp = getwl (&pg, seg_n, *uppn); /* get uppn without lock */
  103.   indph = (struct ind_page *) asp;
  104.   t2bpack (pn, inf);
  105.   if (indph->ind_wpage == IROOT)
  106.     {
  107.       char *a, *lastb, *rbeg, *rloc;
  108.       u2_t n, elsz;
  109.       i4_t remsz, offbef;
  110.       i4_t idm;
  111.       
  112.       elsz = k2sz + size2b;
  113.       remsz = remrep (asp, key, key2, elsz, &rbeg, &rloc, &offbef);
  114.       if (lenforce ()< 0)
  115. {
  116.   putwul (&pg, 'n');
  117.   return (-1);
  118. }
  119.       lastb = asp + indph->ind_off;
  120.       idm = ++((struct p_head *) asp)->idmod;
  121.       icp_remrec (rbeg, rloc, remsz, lastb, elsz, *uppn, asp, idm);
  122.       alter_pn (remsz, elsz, rbeg, rloc, *uppn, idm, asp, inf);
  123.       lastb -= remsz;
  124.       a = asp + indphsize;
  125.       n = t2bunpack (a);
  126.       a += size2b;
  127.       a += kszcal (a, afn, d_f) + n * elsz;
  128.       rloc = (char *) &indph->ind_off;
  129.       recmjform (OLD, seg_n, *uppn, idm, rloc - asp, size2b, rloc, 0);
  130.       indph->ind_off -= remsz;
  131.       if (a == lastb && n == 1) /* remove one level */
  132.         ans = 1;
  133.       assert (check_ind_page (asp) == 0);
  134.       putwul (&pg, 'm');
  135.     }
  136.   else
  137.     ans = rem_rec (&pg, key, key2, size2b, inf);
  138.   return (ans);
  139. }
  140. static int
  141. rem_last_page (char *key, char *key2, u2_t *prevpn_array, i4_t lev_num)
  142. /* remove a record about last page */
  143. {
  144.   char *a, *asp;
  145.   char *rbeg, *rloc, *newkey;
  146.   i4_t remsz, offbef, elsz, off, offbeg, offloc, i;
  147.   u2_t uppn, prevpn, n, prevpn_down;
  148.   struct ind_page *indph;
  149.   struct A pg;
  150.   char new_key[BD_PAGESIZE];
  151.   char newk2[BD_PAGESIZE];
  152.   i4_t idm;
  153.   uppn = *(--thread_s.u);
  154.   asp = getwl (&pg, seg_n, uppn); /* get uppn without lock */
  155.   indph = (struct ind_page *) asp;
  156.   elsz = k2sz + size2b;
  157.   remsz = remrep (asp, key, key2, elsz, &rbeg, &rloc, &offbef);
  158.   off = indph->ind_off;
  159.   if (off - remsz == indphsize && indph->ind_wpage != IROOT)
  160.     {
  161.       putwul (&pg, 'n');
  162.       return (rem_last_page (key, key2, prevpn_array, lev_num + 1));
  163.     }
  164.   a = (remsz!=elsz ? rbeg : rloc) - size2b;
  165.   prevpn = t2bunpack (a);
  166.   for (prevpn_down = prevpn, i = lev_num; i >= 0; i--)
  167.     {
  168.       struct A pg_down;
  169.       char *asp_down;
  170.       thread_s_put (prevpn_down);
  171.       prevpn_array[i] = prevpn_down;
  172.       if ((asp_down = getpg (&pg_down, seg_n, prevpn_down, 's')) == NULL)
  173.         return ( -1);
  174.       if (i > 0 )
  175.         prevpn_down = t2bunpack (asp_down + ((struct ind_page *) asp_down)->ind_off - size2b);
  176.       putwul (&pg_down, 'n');
  177.     }
  178.   if (indph->ind_wpage == IROOT)
  179.     {
  180.       if (lenforce ()< 0)
  181.         {
  182.           putwul (&pg, 'n');
  183.           return (-1);
  184.         }
  185.       idm = ++((struct p_head *) asp)->idmod;
  186.       icp_remrec (rbeg, rloc, remsz, asp + off, elsz, uppn, asp, idm);
  187.       a = (char *) &indph->ind_off;
  188.       recmjform (OLD, seg_n, uppn, idm, a - asp, size2b, a, 0);
  189.       indph->ind_off -= remsz;
  190.       a = asp + indphsize;
  191.       n = t2bunpack (a);
  192.       a += size2b;
  193.       a += kszcal (a, afn, d_f) + n * elsz;
  194.       if (a == asp + indph->ind_off && n == 1) /* remove one level */
  195.         {
  196.           struct A pg_down;
  197.           getwl (&pg_down, seg_n, prevpn);
  198.           remove_level (asp, uppn, &pg_down);
  199.         }
  200.     }
  201.   else
  202.     {
  203.       offbeg = rbeg - asp;
  204.       offloc = rloc - asp;
  205.       if (remsz != elsz)
  206.         {
  207.           a = asp + offbef + size2b;
  208.           newkey = new_key;
  209.           bcopy (a, newkey, kszcal (a, afn, d_f));
  210.           a = rbeg - elsz;
  211.         }
  212.       else
  213.         {
  214.           newkey = key;
  215.           a = asp + off - 2 * elsz;
  216.         }
  217.       bcopy (a, newk2, k2sz);
  218.       putwul (&pg, 'n');
  219.       if (modlast (key, key2, newkey, newk2, uppn) < 0)
  220.         return (-1);
  221.       asp = getwl (&pg, seg_n, uppn); /* get pn without lock */
  222.       indph = (struct ind_page *) asp;
  223.       rbeg = offbeg + asp;
  224.       rloc = offloc + asp;
  225.       idm = ++((struct p_head *) asp)->idmod;
  226.       icp_remrec (rbeg, rloc, remsz, asp + off, elsz, uppn, asp, idm);
  227.       a = (char *) &indph->ind_off;
  228.       recmjform (OLD, seg_n, uppn, idm, a - asp, size2b, a, 0);
  229.       indph->ind_off -= remsz;
  230.     }
  231.   assert (check_ind_page (asp) == 0);
  232.   putwul (&pg, 'm');
  233.   for (; lev_num >= 0; lev_num--)
  234.     {
  235.       u2_t pn;
  236.       prevpn = prevpn_array[lev_num];
  237.       asp = getwl (&pg, seg_n, prevpn);
  238.       indph = (struct ind_page *) asp;
  239.       idm = ++((struct p_head *) asp)->idmod;
  240.       a = (char *) &indph->ind_nextpn;
  241.       recmjform (OLD, seg_n, prevpn, idm, a - asp, size2b, a, 0);
  242.       pn = indph->ind_nextpn;
  243.       indph->ind_nextpn = (u2_t) ~ 0;
  244.       l_emp_put (pn);
  245.       assert (check_ind_page (asp) == 0);
  246.       putwul (&pg, 'm');
  247.     }
  248.   return (0);
  249. }
  250. static int
  251. rem_rec (struct A *pg, char *key, char *key2, i4_t infsz, char *newinf)
  252. {
  253.   char *a, *lastb, *asp;
  254.   char *rbeg, *rloc, *lkey, *lkey2;
  255.   char *aspr = NULL, *bbeg;
  256.   i4_t remsz, offbef, off, n1, elsz, off2 = 0;
  257.   i4_t n2 = 0, ans = 0, lbeg = 0; 
  258.   struct ind_page *indph, *indphr = NULL;
  259.   u2_t rbrpn, pn, uppn;
  260.   i4_t pr_merge = 0, off_rbr = 0;
  261.   struct A pgr;
  262.   i4_t idm, idmr;
  263.   asp = pg->p_shm;
  264.   elsz = k2sz + infsz;
  265.   remsz = remrep (asp, key, key2, elsz, &rbeg, &rloc, &offbef);
  266.   indph = (struct ind_page *) asp;
  267.   off = indph->ind_off;
  268.   lastb = asp + off;
  269.   rbrpn = indph->ind_nextpn;
  270.   n1 = off - remsz;
  271.   pn = pg->p_pn;
  272.   if (n1 < BD_PAGESIZE / 2 && rbrpn != (u2_t) ~ 0)
  273.     { /* merging or transfusion */
  274.       u2_t keysz, n;
  275.       a = rbeg;
  276.       do
  277.         {
  278.           lbeg = lastb - a;
  279.           n = t2bunpack (a);
  280.           a += size2b;
  281.           lkey = a;
  282.           keysz = kszcal (lkey, afn, d_f);
  283.           a += keysz + n * elsz;
  284.         }
  285.       while(a < lastb);
  286.       lkey2 = lastb - elsz;
  287.       if ((aspr = getpg (&pgr, seg_n, rbrpn, 's')) == NULL) /* Lock and request */
  288.         {
  289.           putwul (pg, 'n');
  290.           return (-1);
  291.         }
  292.       indphr = (struct ind_page *) aspr;
  293.       off2 = indphr->ind_off;
  294.       if (off2 > (2 * BD_PAGESIZE / 3))
  295.         { /*transfusion from rigth brother*/
  296.           char *middleb;
  297.           i4_t agsz;
  298.           char *nkey, *nkey2;
  299.           middleb = aspr + ((off + off2 - indphsize) / 2 - off);
  300.           agsz = 0;
  301.           for (bbeg = a = aspr + indphsize; a + agsz < middleb;)
  302.             {
  303.               a += agsz;
  304.               n = t2bunpack (a);
  305.               agsz = size2b + kszcal (a + size2b, afn, d_f) + n * elsz;
  306.             }
  307.           nkey = a + size2b;
  308.           nkey2 = a + agsz - elsz;
  309.           n2 = a + agsz - aspr - indphsize;
  310.           if (n2 + n1 > BD_PAGESIZE)
  311.             n2 = 0;
  312.           if (n2 != 0)
  313.             {
  314.               thread_s_put (rbrpn);
  315.               
  316.               if (mlreddi (lkey, lkey2, nkey, nkey2, pn) < 0)
  317.                 return (-1);
  318.              }
  319.           else
  320.             putpg (&pgr, 'n');
  321.         }
  322.       else if (n1 + off2 - indphsize < BD_PAGESIZE)
  323.         { /* merging with r_br*/
  324.           thread_s_put (rbrpn);
  325.           n2 = off2 - indphsize;
  326.           ans = rem_page (lkey, lkey2, &uppn, pn);
  327.           if (ans < 0)
  328.             return (-1);
  329.           pr_merge = 1;
  330.         }
  331.       else
  332.         putpg (&pgr, 'n');
  333.     }
  334.   if (n2 == 0) /* don't touch right brother */
  335.     if (rloc + elsz == lastb )
  336.       {
  337.         char *newkey, *newk2;
  338.         if (newinf != NULL && rbrpn != (u2_t) ~ 0)
  339.           {
  340.             if (BUF_lockpage (seg_n, rbrpn, 's') == -1) /* Lock rbrpn */
  341.               {
  342.                 putwul (pg, 'n');
  343.                 return (-1);
  344.               }
  345.             thread_s_put (rbrpn);
  346.           }
  347.         if ( rbeg == asp + indphsize && t2bunpack (rbeg) == 1 && indph->ind_wpage != IROOT)
  348.           {
  349.             u2_t *prevpn_array;
  350.             prevpn_array = (u2_t *) xmalloc(thread_s.count * size2b);
  351.             putwul (pg, 'n');
  352.             ans = rem_last_page(key, key2, prevpn_array, 0);
  353.             xfree(prevpn_array);
  354.             return (ans);
  355.           }
  356.         if (remsz == elsz)
  357.           {
  358.             newkey = key;
  359.             newk2 = key2 - elsz;
  360.           }
  361.         else
  362.           {
  363.             newkey = asp + offbef + size2b;
  364.             newk2 = rbeg - elsz;
  365.           }
  366.         if (rbrpn != (u2_t) ~ 0)
  367.           {
  368.             if (mlreddi (key, key2, newkey, newk2, pn) < 0)
  369.               return (-1);
  370.           }
  371.         else
  372.           {
  373.             if (modlast (key, key2, newkey, newk2, pn) < 0)
  374.               return (-1);
  375.           }
  376.       }
  377.     else
  378.       {
  379.         upunlock ();
  380.         if (lenforce ()< 0)
  381.           return (-1);
  382.       }
  383.   idm = ++((struct p_head *) asp)->idmod;
  384.   icp_remrec (rbeg, rloc, remsz, lastb, elsz, pn, asp, idm);
  385.   if (n2 != 0)
  386.     {
  387.       if (remsz != elsz && rbeg - remsz == lastb)
  388. bbeg = asp + offbef;
  389.       else
  390. bbeg = lastb - lbeg;
  391.       lkey = bbeg + size2b;
  392.       a = aspr + indphsize;
  393.       if (cmpkeys (k_n, afn, d_f, lkey, a + size2b) == 0 && n1 != indphsize)
  394. {
  395.           u2_t keysz;
  396.   recmjform (OLD, seg_n, pn, idm, bbeg - asp, size2b, bbeg, 0);
  397.           mod_nels (t2bunpack (a), bbeg);
  398.   keysz = kszcal (a + size2b, afn, d_f);
  399.           off_rbr = keysz + size2b;
  400.           /*   n2 -= keysz + size2b;*/
  401. }
  402.       lastb -= remsz;
  403.       bcopy (a + off_rbr, lastb, n2 - off_rbr);
  404.       if (newinf != NULL)
  405.         alter_pn (remsz, elsz, rbeg, rloc, pn, idm, asp, newinf);
  406.       if (pr_merge == 1)
  407. {
  408.   a = (char *) &indph->ind_nextpn;
  409.   recmjform (OLD, seg_n, pn, idm, a - asp, size2b, a, 0);
  410.           indph->ind_nextpn = indphr->ind_nextpn;
  411.           putwul (&pgr, 'n');
  412.           l_emp_put (rbrpn);
  413.           if (ans == 1)
  414.             { /* remove one level */
  415.               struct A pg1;
  416.               char *asp1; 
  417.               a = (char *) &indph->ind_off;
  418.               recmjform (OLD, seg_n, pn, idm, a - asp, size2b, a, 0);
  419.               indph->ind_off += n2 - remsz;
  420.               asp1 = getwl (&pg1, seg_n, uppn);
  421.               remove_level (asp1, uppn, pg);
  422.               assert (check_ind_page (asp1) == 0);
  423.               putwul (&pg1, 'm');
  424.               return (0);
  425.             }
  426. }
  427.       else
  428. {
  429.           i4_t size;
  430.   a = aspr + indphsize;
  431.           idmr = ++((struct p_head *) aspr)->idmod;
  432.           size = off2 - indphsize - n2;
  433.   recmjform (COMBL, seg_n, rbrpn, idmr, indphsize, size, a, n2);
  434.           bcopy (a + n2, a, size);
  435.   a = (char *) &indphr->ind_off;
  436.   recmjform (OLD, seg_n, rbrpn, idmr, a - aspr, size2b, a, 0);
  437.   indphr->ind_off -= n2;
  438.           assert (check_ind_page (aspr) == 0);
  439.           putwul (&pgr, 'm');
  440. }
  441.     }
  442.   else if (newinf != NULL)
  443.     {
  444.       if (rloc + elsz == lastb)
  445. {
  446.   aspr = getwl (&pgr, seg_n, rbrpn); /* get rbrpn without lock */
  447.   idmr = ++((struct p_head *) aspr)->idmod;
  448.   a = aspr + indphsize + size2b;
  449.   a += kszcal (a, afn, d_f);
  450.   a += k2sz;
  451.   recmjform (OLD, seg_n, rbrpn, idmr, a - aspr, size2b, a, 0);
  452.           bcopy (newinf, a, size2b);
  453.           assert (check_ind_page (aspr) == 0);
  454.   putwul (&pgr, 'm');
  455. }
  456.       else
  457.         alter_pn (remsz, elsz, rbeg, rloc, pn, idm, asp, newinf);
  458.     }
  459.   a = (char *) &indph->ind_off;
  460.   recmjform (OLD, seg_n, pn, idm, a - asp, size2b, a, 0);
  461.   indph->ind_off += n2 - off_rbr - remsz;
  462.   assert (check_ind_page (asp) == 0);
  463.   putwul (pg, 'm');
  464.   return (0);
  465. }
  466. int
  467. icp_rem (struct ldesind *desind, char *key, char *key2, i4_t infsz)
  468. {
  469.   char *asp = NULL;
  470.   u2_t rootpn, d_fn;
  471.   struct ind_page *indph;
  472.   struct A pg;
  473.   
  474.   thread_s_ini_check();
  475.   l_emp_ini_check();
  476.   
  477.   seg_n = desind->i_segn;
  478.   afn = (u2_t *) (desind + 1);
  479.   k_n = desind->ldi.kifn & ~UNIQ & MSK21B;
  480.   uniq_key = UNIQ & desind->ldi.kifn;
  481.   d_f = desind->pdf;
  482.   d_fn = k_n;
  483.   if ((k_n % 2) != 0)
  484.     d_fn += 1;
  485.   d_f2 = (struct des_field *) (afn + d_fn);
  486.   k2sz = d_f2->field_size;
  487.   inf_size = infsz;
  488.   rootpn = desind->ldi.rootpn;
  489.   beg_mop ();
  490. try_again:
  491.   while ((asp = getpg (&pg, seg_n, rootpn, 's')) == NULL);/* Lock and request */
  492.   
  493.   thread_s_ini();
  494.   thread_s_put (rootpn);
  495.   
  496.   indph = (struct ind_page *) asp;
  497.   if (indph->ind_wpage == LEAF)
  498.     {
  499.       i4_t lagelsz, remsz, offbef;
  500.       char  *rbeg, *rloc;
  501.       i4_t idm;
  502.       if (BUF_enforce (seg_n, rootpn) < 0)
  503. {
  504.   putwul (&pg, 'n');
  505.   downunlock ();
  506.   goto try_again;
  507. }
  508.       lagelsz = k2sz + infsz;
  509.       remsz = remrep (asp, key, key2, lagelsz, &rbeg, &rloc, &offbef);
  510.       idm = ++((struct p_head *) asp)->idmod;
  511.       icp_remrec (rbeg, rloc, remsz, asp + indph->ind_off, lagelsz, rootpn, asp, idm);
  512.       rloc = (char *) &indph->ind_off;
  513.       recmjform (OLD, seg_n, rootpn, idm, rloc - asp, size2b, rloc, 0);
  514.       indph->ind_off -= remsz;
  515.       assert (check_ind_page (asp) == 0);
  516.       putwul (&pg, 'm');
  517.     }
  518.   else
  519.     {
  520.       if (icp_spusk (&pg, k2sz + size2b, key, key2) == -1)
  521. {
  522.   all_unlock ();
  523.   goto try_again;
  524. }
  525.       else
  526. {
  527.   if (rem_rec (&pg, key, key2, infsz, NULL) < 0)
  528.     {
  529.       all_unlock ();
  530.               l_emp_ini();
  531.       goto try_again;
  532.     }
  533. }
  534.     }
  535.   MJ_PUTBL ();
  536.   {
  537.     i4_t  i;
  538.     for (i = 0; i < l_emp.count; i++)
  539.       emptypg (seg_n, l_emp.arr[i], 'f');
  540.     l_emp_ini();
  541.   }
  542.   downunlock ();
  543.   thread_s_ini();
  544.   return (0);
  545. }
  546. int
  547. kszcal (char *key, u2_t * mfn, struct des_field *ad_f)
  548. {
  549.   i4_t k, keysz;
  550.   char *a, *aval;
  551.   u2_t nk;
  552.   keysz = scscal (key);
  553.   assert (keysz < BD_PAGESIZE);
  554.   a = aval = key + keysz;
  555.   for (nk = 0, k = 0; nk < k_n && key < aval; nk++, k++)
  556.     {
  557.       if (k == 7)
  558. {
  559.   k = 0;
  560.   key++;
  561. }
  562.       if ((*key & BITVL(k)) != 0)
  563. a = proval (a, (ad_f + mfn[nk])->field_type);
  564.     }
  565.   keysz += a - aval;
  566.   assert (keysz < BD_PAGESIZE);  
  567.   return (keysz);
  568. }
  569. static void
  570. roll_level (u2_t nextpn)
  571. {
  572.   char *asp;
  573.   struct A pg;
  574.   while (nextpn != (u2_t) ~ 0)
  575.     {
  576.       l_emp_put (nextpn);
  577.       thread_s_put (nextpn);
  578.       asp = getpg (&pg, seg_n, nextpn, 's');
  579.       nextpn = ((struct ind_page *) asp)->ind_nextpn;
  580.       putwul (&pg, 'n');
  581.     }
  582. }
  583. int
  584. killind (struct ldesind *desind)
  585. {
  586.   char *asp, *a;
  587.   u2_t pn, nextpn, d_fn;
  588.   struct ind_page *indph;
  589.   struct A pg;
  590.   l_emp_ini_check();
  591.   thread_s_ini_check();
  592.   
  593.   seg_n = desind->i_segn;
  594.   afn = (u2_t *) (desind + 1);
  595.   k_n = desind->ldi.kifn & ~UNIQ & MSK21B;
  596.   d_f = desind->pdf;
  597.   d_fn = k_n;
  598.   if ((k_n % 2) != 0)
  599.     d_fn += 1;
  600.   d_f2 = (struct des_field *) (afn + d_fn);
  601.   k2sz = d_f2->field_size;
  602.   pn = desind->ldi.rootpn;
  603.   for (;;)
  604.     {
  605.       l_emp_put (pn);
  606.       asp = getpg (&pg, seg_n, pn, 's');
  607.       thread_s_put (pn);
  608.       indph = (struct ind_page *) asp;
  609.       if (indph->ind_wpage == LEAF)
  610. break;
  611.       a = asp + indphsize + size2b;
  612.       a += kszcal (a, afn, d_f) + k2sz;
  613.       pn = t2bunpack (a);
  614.       nextpn = indph->ind_nextpn;
  615.       putwul (&pg, 'n');
  616.       roll_level (nextpn);
  617.     }
  618.   nextpn = indph->ind_nextpn;
  619.   putwul (&pg, 'n');
  620.   roll_level (nextpn);
  621.   {
  622.     i4_t i;
  623.     for (i = 0; i < l_emp.count; i++)
  624.       emptypg (seg_n, l_emp.arr[i], 'f');
  625.     l_emp_ini();
  626.   }
  627.   
  628.   downunlock ();
  629.   thread_s_ini();
  630.   return (0);
  631. }