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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  ordmod.c  - Ordinary Modification
  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: ordmod.c,v 1.247 1997/04/15 11:45:41 vera Exp $ */
  29. #include "destrn.h"
  30. #include "strml.h"
  31. #include "fdcltrn.h"
  32. #include "xmem.h"
  33. extern struct d_r_t *firstrel;
  34. void
  35. ordmod (u2_t sn, i4_t rn, struct des_tid *tid,
  36.         struct des_tid *ref_tid, u2_t oldsize, char *nc, u2_t newsize)
  37. {
  38.   char *asp = NULL;
  39.   i2_t delta;
  40.   u2_t pn, ind, pn2;
  41.   i4_t idm;
  42.   struct A pg;
  43.   delta = oldsize - newsize;
  44.   if (delta >= 0)
  45.     {
  46.       u2_t *ai;
  47.       if (ref_tid->tpn != (u2_t) ~ 0)
  48. {
  49.   tid = ref_tid;
  50. }
  51.       pn = tid->tpn;
  52.       while ((asp = getpg (&pg, sn, pn, 'x')) == NULL);
  53.       idm = begmop (asp);
  54.       ai = (u2_t *) (asp + phsize) + tid->tindex;
  55.       if (delta > 0)
  56.         compress (sn, tid, idm, asp, oldsize, newsize);
  57.       else
  58.         recmjform (OLD, sn, pn, idm, *ai, oldsize, asp + *ai, 0);
  59.       bcopy (nc, asp + *ai, newsize);
  60.       MJ_PUTBL ();
  61.       putpg (&pg, 'm');
  62.       if (delta > 0)
  63.         modrec (sn, rn, pn, delta);
  64.     }
  65.   else
  66.     {
  67.       pn = tid->tpn;
  68.       ind = tid->tindex;
  69.       if (ref_tid->tpn == (u2_t) ~ 0)
  70. {
  71.   if (nordins (sn, rn, tid, CORT, oldsize, newsize, nc) != 0)
  72.     {
  73.       doindir (sn, rn, tid, oldsize, newsize, nc);
  74.       modrec (sn, rn, pn, oldsize - MIN_TUPLE_LENGTH);
  75.     }
  76. }
  77.       else
  78. {
  79.   if (nordins (sn, rn, tid, CORT, MIN_TUPLE_LENGTH, newsize, nc) == 0)
  80.             {
  81.               pn2 = ref_tid->tpn;
  82.               while ((asp = getpg (&pg, sn, pn2, 'x')) == NULL);
  83.               idm = begmop (asp);
  84.               compress (sn, ref_tid, idm, asp, oldsize, 0);
  85.               MJ_PUTBL ();
  86.               putpg (&pg, 'm');
  87.               modrec (sn, rn, pn2, oldsize + size2b);
  88.             }
  89.   else if (nordins (sn, rn, ref_tid, CREM, oldsize, newsize, nc) != 0)
  90.     {
  91.       doindir (sn, rn, tid, MIN_TUPLE_LENGTH, newsize, nc);
  92.               pn2 = ref_tid->tpn;
  93.               while ((asp = getpg (&pg, sn, pn2, 'x')) == NULL);
  94.               idm = begmop (asp);
  95.               compress (sn, ref_tid, idm, asp, oldsize, 0);
  96.               MJ_PUTBL ();
  97.               putpg (&pg, 'm');
  98.               modrec (sn, rn, pn2, oldsize + size2b);
  99.     }
  100. }
  101.     }
  102. }
  103. static int
  104. analoc (u2_t sn, u2_t pn, u2_t delta, struct A *pg, i4_t * idm, u2_t pfms)
  105. {
  106.   u2_t lind, fs;
  107.   char *asp = NULL;
  108.   
  109.   while ((asp = getpg (pg, sn, pn, 'x')) == NULL);
  110.   lind = ((struct page_head *) asp)->lastin;
  111.   fs = *((u2_t *) (asp + phsize) + lind) - (phsize + size2b * (lind + 1));
  112.   if (testfree (asp, fs, delta) == -1)
  113.     {
  114.       putpg (pg, 'n');
  115.       return (-1);
  116.     }
  117.   *idm = begmop (asp);
  118.   if (fs < pfms)
  119.     rempbd (asp, sn, pn, *idm);
  120.   return (0);
  121. }
  122. int
  123. nordins (u2_t sn, i4_t rn, struct des_tid *tid, i4_t type,
  124.          u2_t oldsize, u2_t newsize, char *nc)
  125. {
  126.   struct A pg;
  127.   u2_t size, offloc, pn;
  128.   i2_t delta;
  129.   delta = newsize - oldsize;
  130.   pn = tid->tpn;
  131.   if ((size = getrec (sn, rn, pn, &pg, &offloc)) >= (u2_t) delta)
  132.     {
  133.       char *asp, *a;
  134.       i4_t idm;
  135.       u2_t *ai, pnifam;
  136.       struct A pg_table;
  137.       
  138.       if (analoc (sn, pn, delta, &pg_table, &idm, size) != 0)
  139. {
  140.   BUF_unlock (sn, 1, &pg.p_pn);
  141.   return (-1);
  142. }
  143.       *nc = type;
  144.       asp = pg_table.p_shm;
  145.       ai = (u2_t *) (asp + phsize) + tid->tindex;
  146.       if (*ai == 0)
  147.         inscort (sn, tid, idm, asp, nc, newsize);
  148.       else
  149.         exspind (sn, tid, idm, asp, oldsize, newsize, nc);
  150.       MJ_PUTBL ();
  151.       putpg (&pg_table, 'm');
  152.       pnifam = pg.p_pn;
  153.       while (BUF_enforce (sn, pnifam) < 0);
  154.       asp = getwl (&pg, sn, pnifam);
  155.       a = asp + offloc;
  156.       idm = begmop (asp);
  157.       recmjform (OLD, sn, pn, idm, offloc, size2b, a, 0);
  158.       MJ_PUTBL ();
  159.       t2bpack (size - delta, a);
  160.       putpg (&pg, 'm');
  161.       return (0);
  162.     }
  163.   else
  164.     {
  165.       BUF_unlock (sn, 1, &pg.p_pn);
  166.       return (-1);
  167.     }
  168. }
  169. void
  170. doindir (u2_t sn, i4_t rn, struct des_tid *tid,
  171.          u2_t oldsize, u2_t newsize, char *nc)
  172. {
  173.   i4_t rep, idm;
  174.   struct d_r_t *desrel;
  175.   char *a, *asp = NULL;
  176.   u2_t cpn, pfms, *ai, pn;
  177.   struct d_sc_i *scind;
  178.   struct ldesscan *disc;
  179.   i2_t num;
  180.   struct A pg;
  181.   struct des_tid ref_tid;
  182.   for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist)
  183.     if (desrel->desrbd.relnum == rn)
  184.       break;
  185.   *nc = CREM;
  186.   scind = rel_scan (sn, rn, (char *) desrel, &num, 0, NULL, NULL, 0, 0, NULL);
  187.   disc = &scind->dessc;
  188.   pn = cpn = tid->tpn;
  189.   rep = fgetnext (disc, &cpn, &pfms, FASTSCAN);
  190.   while (rep != EOI && cpn != pn)
  191.     rep = getnext (disc, &cpn, &pfms, FASTSCAN);
  192.   if (rep != EOI)
  193.     rep = getnext (disc, &cpn, &pfms, FASTSCAN);
  194.   if (rep != EOI && pfms >= newsize)
  195.     {
  196.       if (analoc (sn, cpn, (i2_t) newsize, &pg, &idm, pfms) == 0)
  197.         {
  198.           u2_t nind = 0, lind;
  199.           asp = pg.p_shm;
  200.           ai = (u2_t *) (asp + phsize);
  201.           lind = ((struct page_head *) asp)->lastin;
  202.           while ((nind <= lind) && (*ai != 0))
  203.             {
  204.               CHECK_PG_ENTRY(ai);
  205.               ai++;
  206.               nind++;
  207.             }
  208.           ref_tid.tpn = cpn;
  209.           ref_tid.tindex = nind;
  210.           inscort (sn, &ref_tid, idm, asp, nc, newsize);
  211.           MJ_PUTBL ();
  212.           putpg (&pg, 'm');
  213.           modcur (disc, pfms - newsize - size2b);
  214. }
  215.       else
  216.         {
  217.           BUF_unlock (sn, 1, &disc->curlpn);
  218.           ref_tid = ordins (sn, rn, nc, newsize, 'n');
  219.         }
  220.     }
  221.   else
  222.     {
  223.       if (rep != EOI)
  224.         BUF_unlock (sn, 1, &disc->curlpn);
  225.       ref_tid = ordins (sn, rn, nc, newsize, 'n');
  226.     }
  227.   delscan (num);
  228.   while ((asp = getpg (&pg, sn, tid->tpn, 'x')) == NULL);
  229.   idm = begmop (asp);
  230.   if (oldsize > MIN_TUPLE_LENGTH)
  231.     compress (sn, tid, idm, asp, oldsize, MIN_TUPLE_LENGTH);
  232.   ai = (u2_t *) (asp + phsize) + tid->tindex;
  233.   a = asp + *ai;
  234.   *a++ = IND;
  235.   t2bpack (ref_tid.tindex, a);
  236.   t2bpack (ref_tid.tpn, a + size2b);
  237.   MJ_PUTBL ();
  238.   putpg (&pg, 'm');
  239. }