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

SQL Server

开发平台:

Unix_Linux

  1. /*
  2.  *  helpfu.c  - Common finctions of Logical Journal and Microjournal
  3.  *              Kernel of GNU SQL-server. Journals 
  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: helpfu.c,v 1.245 1997/03/31 03:46:38 kml Exp $ */
  29. #include "setup_os.h"
  30. #include <sys/types.h>
  31. #if HAVE_SYS_FILE_H 
  32. #include <sys/file.h>
  33. #endif
  34. #if HAVE_UNISTD_H
  35. #include <unistd.h>
  36. #endif
  37. #include <sys/stat.h>
  38. #include <assert.h>
  39. #include "rnmtp.h"
  40. #include "pupsi.h"
  41. #include "strml.h"
  42. #include "fdeclmj.h"
  43. #include "xmem.h"
  44. extern char pl1[RPAGE], pl2[RPAGE];
  45. extern char *p[2];
  46. extern u2_t pushpn[2]; /* contains the page number*/
  47. extern i4_t PROB[2]; /* state of JOURN-pushs (i=0,1) */
  48. extern i4_t RFILE;
  49. extern i4_t NB; /* J-version number*/
  50. extern i4_t ilast; /* the number of page, contained the last page of jounal*/
  51. #define size2b sizeof(u2_t)
  52. #define size4b sizeof(i4_t)
  53. void
  54. getrfile (i4_t fd)
  55. {
  56.   struct stat buf;
  57.   if (fstat (fd, &buf) < 0)
  58.     ADM_ERRFU (MERR);
  59.   RFILE = buf.st_size / (RPAGE);
  60. }
  61. void
  62. get_last_page (i4_t fd) /* Search the last page of a journal;*/
  63. {         /* ilast(global) is equal the number of the push */
  64. /* contained the last page */
  65.   i4_t PCP, i;
  66.   u2_t N;
  67.   PROB[0] = -1;
  68.   PROB[1] = -1;
  69.   pushpn[0] = (u2_t) ~ 0;
  70.   pushpn[1] = 0;
  71.   READPG (1, 0, fd);
  72.   NB = t4bunpack (p[0]);
  73.   for (N = 1, i = 0;; N++)
  74.     {
  75.       ilast = i;
  76.       if (N == RFILE)
  77. break;
  78.       PCP = *(p[i] + size4b + size2b);
  79.       if (PCP == SIGN_NOCONT)
  80. break;
  81.       i = (i == 0) ? 1 : 0;
  82.       READPG (N, i, fd);
  83.       if (NB != t4bunpack (p[i]))
  84. {
  85.   i = (i == 0) ? 1 : 0;
  86.   break;
  87. }
  88.     }
  89.   ilast = i;
  90. }
  91. int
  92. get_page (i4_t j, u2_t N, i4_t fd) /* Prepare page number N into one push*/
  93.                                   /* j - is the number of the current push */
  94. {
  95.   register i4_t k;
  96.   k = (j == 0) ? 1 : 0;
  97.   if (pushpn[k] == N)
  98.     {
  99.       if ((PROB[0] == 1) || (PROB[1] == 1))
  100. WAIT ((PROB[0] == 1) ? 0 : 1);
  101.     }
  102.   else
  103.     {
  104.       k = (j == ilast) ? k : j;
  105.       READPG (N, k, fd);
  106.     }
  107.   return (k);
  108. }
  109. void
  110. get_rec (char *pnt, struct ADBL adj, i4_t fd)
  111. {
  112.   register char *end_of_record;
  113.   register i4_t k;
  114.   register u2_t n, N, n1, razm;
  115.   N = adj.npage;
  116.   n = adj.cm;
  117.   k = (N == pushpn[0]) ? 0 : ((N == pushpn[1]) ? 1 : (-1));
  118.   if (k == (-1))
  119.     {
  120.       k = (ilast == 0) ? 1 : 0;
  121.       READPG (N, k, fd);
  122.     }
  123.   n -= RTPAGE;
  124.   if (n < RTBLK)
  125.     { /* the top-block places in two pages*/
  126.       char buff[size2b];
  127.       n1 = RTBLK - n;
  128.       bcopy (p[k] + RTPAGE, buff + n1, n);
  129.       k = get_page (k, pushpn[k] - 1, fd);
  130.       end_of_record = p[k] + RPAGE - n1;
  131.       bcopy (end_of_record, buff, n1);
  132.       razm = t2bunpack (buff);
  133.       n = RPAGE - RTPAGE - n1;
  134.     }
  135.   else
  136.     { /* the top-block places in (N)-page */
  137.       end_of_record = p[k] + n + RTPAGE - RTBLK;
  138.       razm = t2bunpack (end_of_record);
  139.       n -= RTBLK;
  140.       if (n == 0)
  141.         {
  142.           k = get_page (k, pushpn[k] - 1, fd);
  143.           end_of_record = p[k] + RPAGE;
  144.           n = RPAGE - RTPAGE;
  145.         }
  146.     }
  147.   t2bpack (razm, pnt);
  148.   pnt += size2b;
  149.   assert (razm <= RPAGE);
  150.   if (n < razm)
  151.     { /* block-record places in two pages */
  152.       n1 = razm - n;
  153.       bcopy (p[k] + RTPAGE, pnt + n1, n);
  154.       k = get_page (k, pushpn[k] - 1, fd);
  155.       bcopy (p[k] + RPAGE - n1, pnt, n1);
  156.     }
  157.   else /*block-record places in (N)-page all*/
  158.     bcopy (end_of_record - razm, pnt, razm);
  159. }
  160. void
  161. MOREFILE (i4_t n) /* Add n page to base-file and pictures them */
  162. {
  163.   RFILE = RFILE + n;
  164.   PICTURE (RFILE - n + 1);
  165. }
  166. void
  167. PICTURE (i4_t n) /* Put standard top-journal and  top-pages into disk, */
  168. {         /* beginning with the page number "n" */
  169.   register i4_t i, j;
  170.   if (n > 1)
  171.     j = (ilast == 0) ? 1 : 0;
  172.   else
  173.     j = 0;
  174.   for (i = n; i <= RFILE; i++)
  175.     {
  176.       t4bpack (0, p[j]);
  177.       PROB[j] = 2;
  178.       pushpn[j] = i;
  179.       out_push (j, 1); /*with wait*/
  180.     }
  181. }
  182. void
  183. out_push (i4_t i, i4_t c) /* Write push number "i" into disk;*/
  184. {                /*(if is it needed). c=1 -wait; c=0 -no wait; */
  185.   
  186.   if (PROB[i] == 1)
  187.     {
  188.       WAIT (i);
  189.     }
  190.   else if (PROB[i] == 2)
  191.     {
  192.       i4_t j;
  193.       j = ((i == 0) ? 1 : 0);
  194.       if (PROB[j] == 1)
  195. WAIT (j);
  196.       write_disk (i, c);
  197.     }
  198. }
  199. void
  200. WAIT (i4_t i) /* i- push number */
  201. {
  202.   PROB[i] = 0;
  203. }
  204. void
  205. READPG (u2_t N, i4_t i, i4_t fd) /* Read "N"-page from JRN-basefile into i-push */
  206. {
  207.   if ((PROB[0] == 1) || (PROB[1] == 1))
  208.     WAIT ((PROB[0] == 1) ? 0 : 1);
  209.   if (lseek (fd, (i4_t) (RPAGE * (N - 1)), SEEK_SET) < 0)
  210.     {
  211.       perror ("JRN.lseek: READPG");
  212.       exit (1);
  213.     }
  214.   if (read (fd, (i == 0) ? pl1 : pl2, RPAGE) != RPAGE)
  215.     {
  216.       perror ("JRN.read: READPG");
  217.       exit (1);
  218.     }
  219.   pushpn[i] = N;
  220. }
  221. void
  222. WRITEPG (i4_t i,i4_t c,i4_t fd) /* Write push number "i" into page with number N */
  223. {                         /* of the JRN-basefile; c=1 -wait; c=0 -no wait; */
  224.   i4_t N;
  225.   N = pushpn[i];
  226.   switch (c)
  227.     {
  228.     case 1:
  229.       if (lseek (fd, (i4_t) (RPAGE * (N - 1)), SEEK_SET) < 0)
  230. ADM_ERRFU (MERR);
  231.       if (write (fd, (i == 0) ? pl1 : pl2, RPAGE) != RPAGE)
  232. ADM_ERRFU (MERR);
  233.       PROB[i] = 0;
  234.       break;
  235.     case 0:
  236.       if (lseek (fd, (i4_t) (RPAGE * (N - 1)), SEEK_SET) < 0)
  237. ADM_ERRFU (MERR);
  238. #if 0
  239.       printf ("helpfu.WRITEPG: no wait fd = %d, N = %dn", fd, N);
  240.       for (j = 0, a = (i == 0) ? pl1 : pl2 ; j < 16; j++)
  241.         printf (" %X", a[j]);
  242.       printf ("n");
  243. #endif
  244.       if (write (fd, (i == 0) ? pl1 : pl2, RPAGE) != RPAGE)
  245. ADM_ERRFU (MERR);
  246.       PROB[i] = 1;
  247.       break;
  248.     default:
  249.       printf ("err in wait-coden");
  250.       break;
  251.     }
  252. }
  253. char *
  254. write_topblock (u2_t size, u2_t off, char *a)
  255. {
  256.   if (off + RTBLK > RPAGE)
  257.     { /* the top-block places in two pages*/
  258.       u2_t n, n1;
  259.       char buff[size2b];
  260.       n = RPAGE - off;
  261.       t2bpack (size, buff);
  262.       bcopy (buff, a, n);
  263.       do_cont ();
  264.       a = p[ilast] + RTPAGE;
  265.       n1 = RTBLK - n;
  266.       bcopy (buff + n, a, n1);
  267.       a += n1;
  268.     }
  269.   else
  270.     { /* the top-block places in (N)-page */
  271.       t2bpack (size, a);
  272.       a += size2b;
  273.     }
  274.   return (a);
  275. }
  276. void
  277. do_cont (void)
  278. {
  279.   register char *a;
  280.   *(p[ilast] + size4b + size2b) = SIGN_CONT;
  281.   out_push (ilast, 0);
  282.   pushpn[(ilast == 0) ? 1 : 0] = pushpn[ilast] + 1;
  283.   ilast = (ilast == 0) ? 1 : 0;
  284.   a = p[ilast];
  285.   t4bpack (NB, a);
  286.   a += size4b;
  287.   t2bpack (RTPAGE, a);
  288.   a += size2b;
  289.   *a = SIGN_NOCONT;
  290. }