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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  ordins.c  - Ordinary insertion
  3.  *              Kernel of GNU SQL-server 
  4.  *
  5.  *  This file is a part of GNU SQL Server
  6.  *
  7.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  8.  *  Developed at the Institute of System Programming
  9.  *  This file is written by  Vera Ponomarenko
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  24.  *
  25.  *  Contacts:   gss@ispras.ru
  26.  *
  27.  */
  28. /* $Id: ordins.c,v 1.248 1997/04/15 11:45:41 vera Exp $ */
  29. #include <assert.h>
  30. #include "destrn.h"
  31. #include "strml.h"
  32. #include "fdcltrn.h"
  33. #include "xmem.h"
  34. extern struct ldesind **TAB_IFAM;
  35. extern struct ADBL adlj;
  36. extern i4_t ljmsize;
  37. extern struct d_r_t *firstrel;
  38. extern u2_t S_SC_S;
  39. static u2_t wild_pn = (u2_t) ~0;
  40. ARR_DECL(l_emp,u2_t,static); /* declaration of local dynamic stack/array 'l_emp'.*/
  41. ARR_PROC_DECL(l_emp,u2_t,static); /* declaration of routines for it              */
  42. static u2_t
  43. along_leaf_pages (struct A *pg, u2_t necessary_size, char *pnt, u2_t n,
  44.                   u2_t *pfms, u2_t *loc, char *key)
  45. {
  46.   u2_t pn, table_pn, ksz = size4b +1, sn;
  47.   struct ind_page *indph;
  48.   char *asp = NULL, *lastb;
  49.   asp = pg->p_shm;
  50.   sn = pg->p_sn;
  51.   for (;; pnt += ksz)
  52.     {
  53.       indph = (struct ind_page *) asp;
  54.       lastb = asp + indph->ind_off;
  55.       for (; n != 0; n--)
  56.         {
  57.           table_pn = t2bunpack (pnt);
  58.           pnt += size2b;
  59.           *pfms = t2bunpack (pnt);
  60.           pnt += size2b;
  61.           if (*pfms >= necessary_size)
  62.             {
  63.               *loc = pnt - size2b - asp;
  64.               return (table_pn);
  65.             }
  66.         }
  67.       if (pnt < lastb)
  68.         {
  69.           putpg(pg, 'n');
  70.           return (wild_pn);
  71.         }
  72.       pn = indph->ind_nextpn;
  73.       putpg(pg, 'n'); /* make asp & indph etc undefined */
  74.       if (pn == wild_pn)
  75.         return wild_pn;
  76.       while ((asp = getpg (pg, sn, pn, 's')) == NULL);
  77.       pnt = asp + indphsize;
  78.       n = t2bunpack (pnt);
  79.       pnt += size2b;
  80.       if (f4b (pnt + 1, key, size4b, size4b) != 0)
  81.         {
  82.           putpg(pg, 'n');
  83.           return (wild_pn);
  84.         }
  85.     }
  86. }
  87. static u2_t
  88. find_suit_page (struct A *pg, u2_t sn, char *key, u2_t necessary_size,
  89.                 u2_t *pfms, u2_t *loc)
  90. {
  91.   char *aggr = NULL, *a, *lastb, *asp = NULL;
  92.   u2_t pn, n = 0;
  93.   i4_t ksz = size4b + 1, elsz = 2*size2b, l = 0;
  94.   struct ind_page *indph;
  95.   
  96.   pn = S_SC_S;     /* rootpn for Allocation Memory Index */
  97.   for (;;)
  98.     {
  99.       while ((asp = getpg (pg, sn, pn, 's')) == NULL);
  100.       indph = (struct ind_page *) asp;
  101.       lastb = asp + indph->ind_off;
  102.       for (a = asp + indphsize; a < lastb; a += ksz + n * elsz)
  103.         {
  104.           aggr = a;
  105.           n = t2bunpack (a);
  106.           a += size2b;
  107.           if ((l = f4b (a + 1, key, size4b, size4b)) >= 0)
  108.             break;
  109.         }
  110.       if (a == lastb)
  111.         {
  112.           putpg(pg, 'n');
  113.           return (wild_pn);
  114.         }
  115.       if (indph->ind_wpage == LEAF)
  116.         break;
  117.       pn = t2bunpack (aggr + size2b + ksz + size2b);     /* pn down */
  118.       putpg(pg, 'n');
  119.     }
  120.   if (l != 0)
  121.     {
  122.       putpg(pg, 'n');
  123.       return (wild_pn);
  124.     }
  125.   a += ksz;
  126.   return (along_leaf_pages (pg, necessary_size, a, n, pfms, loc, key));
  127. }
  128. static u2_t
  129. cont_search_suit_page (struct A *pg, char *key, u2_t necessary_size,
  130.                        u2_t *pfms, u2_t *loc)
  131. {
  132.   char *aggr = NULL, *a, *lastb, *asp;
  133.   u2_t n = 0;
  134.   i4_t ksz = size4b + 1, elsz = 2*size2b, l = 0;
  135.   
  136.   asp = pg->p_shm;
  137.   lastb = asp + ((struct ind_page *) asp)->ind_off;
  138.   for (a = asp + indphsize; a < lastb; a += ksz + n * elsz)
  139.     {
  140.       aggr = a;
  141.       n = t2bunpack (a);
  142.       a += size2b;
  143.       if ((l = f4b (a + 1, key, size4b, size4b)) >= 0)
  144.         break;
  145.     }
  146.   assert (a != lastb);
  147.   if (l != 0)
  148.     {
  149.       putpg(pg, 'n');
  150.       return (wild_pn);
  151.     }
  152.   a = asp + *loc + size2b;
  153.   n -= (a - (aggr + size2b + ksz)) / elsz; 
  154.   return (along_leaf_pages (pg, necessary_size, a, n, pfms, loc, key));
  155. }
  156. static void
  157. mod_free_size (struct A *pg, u2_t offloc, u2_t size)
  158. {
  159.   char *asp, *a;
  160.   i4_t idm;
  161.   u2_t sn, pn;
  162.   sn = pg->p_sn;
  163.   pn = pg->p_pn;
  164.   while (BUF_enforce (sn, pn) < 0);
  165.   asp = pg->p_shm;
  166.   a = asp + offloc;
  167.   idm = begmop (asp);
  168.   recmjform (OLD, sn, pn, idm, offloc, size2b, a, 0);
  169.   MJ_PUTBL ();
  170.   t2bpack (size, a);
  171.   putpg (pg, 'm');
  172. }
  173. static void
  174. free_pages (u2_t sn, i4_t rn, i4_t i)
  175. {
  176.   u2_t empn;
  177.   i4_t i1;
  178.   char *a;
  179.   char key[size4b + 1], key2[size2b];
  180.   a = key;
  181.   *a++ = BITVL(0) | EOSC;
  182.   t4bpack (rn, a);
  183.   for (i1 = i; i1 < l_emp.count; i1++)
  184.     {
  185.       empn = l_emp.arr[i1];
  186.       t2bpack (empn, key2);
  187.       icp_rem (TAB_IFAM[sn], key, key2, size2b);
  188.       /*      delrec (TAB_IFAM[sn], rn, empn);*/
  189.       emptypg (sn, empn, 'f');
  190.     }
  191.   BUF_unlock (sn, l_emp.count - i , l_emp.arr + i);
  192.   l_emp_ini();
  193. }
  194. struct des_tid
  195. ordins (u2_t sn, i4_t rn, char *cort, u2_t corsize, char type)
  196. {
  197.   struct page_head *ph;
  198.   struct d_r_t *desrel;
  199.   u2_t pn, pfms, offloc;
  200.   i2_t delta;
  201.   struct des_tid tid;
  202.   char *asp = NULL;
  203.   struct A pg, pg_ifam;
  204.   char key[size4b];
  205.   struct id_rel idr;
  206.   for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist)
  207.     if (desrel->desrbd.relnum == rn)
  208.       break;
  209.   idr.urn.segnum = sn;
  210.   idr.urn.obnum = rn;
  211.   if (rn != RDRNUM)
  212.     {
  213.       idr.pagenum = desrel->pn_r;
  214.       idr.index = desrel->ind_r;
  215.     }
  216.   delta = corsize + size2b;
  217.   tab_difam (sn);
  218.   l_emp_ini_check();
  219.   t4bpack (rn, key);
  220.   pn = find_suit_page (&pg_ifam, sn, key, delta, &pfms, &offloc);
  221. m1:
  222.   if (pn != wild_pn)
  223.     {
  224.       u2_t lind, *ai, ind, fs;
  225.       i4_t idm;
  226.       while ((asp = getpg (&pg, sn, pn, 'x')) == NULL);
  227.       lind = ((struct page_head *) asp)->lastin;
  228.       fs = *((u2_t *) (asp + phsize) + lind) - (phsize + size2b * (lind + 1));
  229.       assert (fs <= BD_PAGESIZE - phsize);
  230.       if (fs < pfms)
  231.         {
  232.           i4_t i;
  233.           if ((i = testfree (asp, fs, delta)) == 1)
  234.             { /* this page is empty */
  235.               putwul (&pg, 'n');
  236.               l_emp_put (pn);
  237.               pn = cont_search_suit_page (&pg_ifam, key, delta, &pfms, &offloc);
  238.               goto m1;
  239.             }
  240.           else if (i == -1)    /* no allocation */
  241.             {
  242.               putpg (&pg, 'n');
  243.               pn = cont_search_suit_page (&pg_ifam, key, delta, &pfms, &offloc);
  244.               goto m1;
  245.             }
  246.         }
  247.       idm = begmop (asp);
  248.       if (fs < pfms)
  249.         rempbd (asp, sn, pn, idm);
  250.       ai = (u2_t *) (asp + phsize);
  251.       for (ind = 0; ind <= lind && *ai != 0; ai++, ind++);
  252.       tid.tindex = ind;
  253.       tid.tpn = pn;
  254.       if (type == 'w')
  255. wmlj (INSLJ, ljmsize + corsize, &adlj, &idr, &tid, 0);
  256.       inscort (sn, &tid, idm, asp, cort, corsize);
  257.       MJ_PUTBL ();
  258.       putpg (&pg, 'm');
  259.       mod_free_size (&pg_ifam, offloc, pfms - corsize - size2b);
  260.       if (l_emp.count != 0)
  261.         free_pages (sn, rn, 0);
  262.     }
  263.   else
  264.     {
  265.       u2_t size;
  266.       if (l_emp.count != 0)
  267.         {
  268.           pn = l_emp.arr[0];
  269.           asp = getwl (&pg, sn, pn);
  270.         }
  271.       else
  272.         {
  273.           pn = getempt (sn);
  274.           asp = getnew (&pg, sn, pn);
  275.         }
  276.       tid.tpn = pn;
  277.       tid.tindex = 0;
  278.       if (type == 'w')
  279.         wmlj (INSLJ, ljmsize + corsize, &adlj, &idr, &tid, 0);
  280.       size = BD_PAGESIZE - corsize;
  281.       bcopy (cort, asp + size, corsize);
  282.       ph = (struct page_head *) asp;
  283.       ph->lastin = 0;
  284.       t2bpack (size, asp + phsize);
  285.       ++ph->ph_ph.idmod;
  286.       if (l_emp.count != 0)
  287.         {
  288.           putpg (&pg, 'm');
  289.           modrec (sn, rn, pn, -(corsize + size2b));
  290.           free_pages (sn, rn, 1);
  291.         }
  292.       else
  293.         {
  294.           putwul (&pg, 'm');
  295.           insrec (TAB_IFAM[sn], rn, pn, size - phsize - size2b);
  296.         }
  297.     }
  298.   l_emp_ini();
  299.   return (tid);
  300. }