📄 librcv.c
字号:
/* librcv.c - Crash Recovery Utility Library * Kernel of GNU SQL-server. Recovery utilities * * This file is a part of GNU SQL Server * * Copyright (c) 1996, 1997, Free Software Foundation, Inc * Developed at the Institute of System Programming * This file is written by Vera Ponomarenko * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Contacts: gss@ispras.ru * *//* $Id: librcv.c,v 1.247 1997/04/15 11:46:20 vera Exp $ */#include "setup_os.h"#if STDC_HEADERS#include <sys/types.h>#include <sys/stat.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#include <assert.h>#if HAVE_DIRENT_H# include <dirent.h># define NAMLEN(dirent) strlen((dirent)->d_name)#else# define dirent direct# define NAMLEN(dirent) (dirent)->d_namlen# if HAVE_SYS_NDIR_H# include <sys/ndir.h># endif# if HAVE_SYS_DIR_H# include <sys/dir.h># endif# if HAVE_NDIR_H# include <ndir.h># endif#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif#if HAVE_SYS_IPC_H#include <sys/ipc.h>#endif#if HAVE_SYS_MSG_H#include <sys/msg.h>#endif#if HAVE_SYS_SHM_H#include <sys/shm.h>#endif#if HAVE_SYS_WAIT_H# include <sys/wait.h>#endif#ifndef WEXITSTATUS# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)#endif#ifndef WIFEXITED# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)#endif#include "destrn.h"#include "strml.h"#include "puprcv.h"#include "fdclrcv.h"#include "f1f2decl.h"/**************************************************************/extern i4_t msqidl, msqidm, msqidb;extern i4_t fdcurlj;char ljpage[RPAGE];u2_t pagenum;extern i4_t N_AT_SEG;extern COST cost;extern struct ADREC bllj;extern struct d_r_t *firstrel;extern struct ADBL admj;extern char *pbufmj;extern char *pbuflj;extern struct ldesind **TAB_IFAM;extern i4_t TIFAM_SZ;extern i4_t idtr;extern struct ADBL adlj;extern struct ADREC blmj;extern char *bufmj;extern unsigned ljmsize;extern u2_t trnum;extern struct ADREC blmj;extern i4_t minidnt;#define adfsize sizeof(struct ADF)static voidrllbck_tr (i4_t fd, i4_t cidtr, struct ADBL cadlj){ register char *a, type; i4_t newidtr; u2_t blsz; char *pnt, mas[RPAGE]; for (; (blsz = LJ_prev (fd, &cadlj, &pnt, mas)) > 0;) { a = pnt; type = *a++; if (type == EOTLJ || type == GRLBLJ) continue; newidtr = t4bunpack (a); a += size4b; if (newidtr == cidtr) { cadlj.npage = t2bunpack (a); a += size2b; cadlj.cm = t2bunpack (a); a += size2b; backactn (blsz, a, type); break; } } idtr = cidtr; r_tr (cadlj);}static voidrollb_nftr(i4_t fd, struct ADBL cadlj, char *a, u2_t n){ u2_t i, NFTRANS; i4_t cidtr; NFTRANS = n / size4b; for (i = 0; i < NFTRANS; i++, a += size4b) { cidtr = t4bunpack (a); rllbck_tr (fd, cidtr, cadlj); }}static voidfrwrd_mtn (struct ADBL cadlj){ char *a, type; u2_t blsz; char *pnt, mas[RPAGE]; for (; (blsz = LJ_next (fdcurlj, &cadlj, &pnt, mas)) > 0;) { /*The motion forward */ a = pnt; type = *a++; if (type == CPRLJ) continue; if (type == EOTLJ) { getmint (a, blsz - size1b); continue; } if (type == GRLBLJ) { adlj = cadlj; blsz = LJ_prev (fdcurlj, &adlj, &pnt, mas); a = pnt; type = *a++; if (type != EOTLJ) fprintf (stderr, "Serious error! LIBRCV.frwrd_mtn: type |= EOTLJ (=%d) before GRLBLJ\n", type); rollb_nftr (fdcurlj, adlj, a, blsz - size1b); continue; } idtr = t4bunpack (a); forward_action (a + size4b, type, blsz - ljmsize); }}struct ADBL frwdmtn (void){ struct ADBL cadlj; read_page (fdcurlj, 1, ljpage); cadlj.npage = 1; cadlj.cm = RTPAGE; frwrd_mtn (cadlj); return (adlj); /* use adlj because cadlj doesn't change */ /* in frwrd_mnt but adlj */ }static struct d_r_t *cr_rd(struct id_rel *idr){ char *a, *asp; struct A pg; struct d_r_t *desrel; u2_t *ai; unsigned char t; asp = getpg (&pg, idr->urn.segnum, idr->pagenum, 's'); ai = (u2_t *) (asp + phsize) + idr->index; a = asp + *ai; t = *a & MSKCORT; if (t == IND) { /* indirect reference */ u2_t pn2, ind2; char *asp = NULL; ind2 = t2bunpack (a + 1); pn2 = t2bunpack (a + 1 + size2b); putpg (&pg, 'n'); while ((asp = getpg (&pg, pg.p_sn, pn2, 's')) == NULL); ai = (u2_t *) (asp + phsize) + ind2; a = asp + *ai; assert ((*a & CREM) != 0 && *ai != 0); } desrel = crtfrd (idr, a); putpg (&pg, 'n'); return (desrel);}u2_tLJ_next (i4_t fd, struct ADBL *adj, char **pnt, char *mas){ u2_t N, offbeg, n, blsz, off, n1; char *a, *beg_of_record; N = adj->npage; offbeg = adj->cm; if (pagenum != N) read_page (fd, N, ljpage); a = ljpage + size4b; off = t2bunpack (a); a += size2b; if (off == offbeg && *a == 0) return (0); a = ljpage + offbeg; if (offbeg + RTBLK > RPAGE) { /* the top-block places in two pages*/ char buff[size2b]; n = RPAGE - offbeg; bcopy (a, buff, n); N++; read_page (fd, N, ljpage); n1 = RTBLK - n; bcopy (ljpage + RTPAGE, buff + n, n1); blsz = t2bunpack (buff); n = RTPAGE + n1; beg_of_record = ljpage + n; } else { /* the top-block places in (N)-page */ blsz = t2bunpack (a); beg_of_record = a + RTBLK; n = offbeg + RTBLK; } if (n + blsz > RPAGE) { /* block-record places in two page*/ n = RPAGE - n; bcopy(beg_of_record, mas, n); N++; read_page (fd, N, ljpage); n1 = blsz - n; bcopy (ljpage + RTPAGE, mas + n, n1); *pnt = mas; n = RTPAGE + n1; } else { *pnt = beg_of_record; n += blsz; } if (n + RTBLK > RPAGE) { /* the endtop-block places in two pages*/ N++; offbeg = RTPAGE + RTBLK - (RTBLK - n); } else offbeg = n + RTBLK; adj->npage = N; adj->cm = offbeg; return (blsz);}static voidrollback_action (char *a){ char type; struct ADBL cadlj; struct ADREC bllj; cadlj.npage = t2bunpack (a); a += size2b; cadlj.cm = t2bunpack (a); a += size2b; rcv_LJ_GETREC (&bllj, &cadlj); a = bllj.block; type = *a++; backactn (bllj.razm, a + size4b + 2 * size2b, type);}voidforward_action (char *a, char type, u2_t n){ u2_t pn, ind, pnr, indr; u2_t sn; i4_t rn, ordrn; struct d_r_t *desrel; struct des_tid tid; struct id_rel idr; if (type == RLBLJ || type == RLBLJ_AS_OP) rollback_action (a); a += 2 * size2b; sn = idr.urn.segnum = t2bunpack (a); assert (sn != 0); a += size2b; rn = idr.urn.obnum = t4bunpack (a); a += size4b; idr.pagenum = pnr = t2bunpack (a); a += size2b; idr.index = indr = t2bunpack (a); a += size2b; tid.tpn = t2bunpack (a); a += size2b; tid.tindex = t2bunpack (a); a += size2b; pn = tid.tpn; ind = tid.tindex; if (rn != RDRNUM) { for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist) if (desrel->desrbd.relnum == rn) break; if (desrel == NULL) desrel = cr_rd (&idr); } else desrel = NULL; if (type == DELLJ) redo_dltn (sn, desrel, rn, &tid, n, a); else if (type == INSLJ) { struct des_tid newtid; newtid = ordins (sn, rn, a, n, 'n'); if (newtid.tpn != pn || newtid.tindex != ind) fprintf (stderr, "LIBRCV.frwrd_mtn: Serious error! tids don't matched pn=%d\n", pn); if (rn != RDRNUM) proind (ordindi, desrel, desrel->desrbd.indnum, a, &tid); else { ordrn = t4bunpack (a + scscal (a)); idr.urn.obnum = ordrn; desrel = crtfrd (&idr, a); } } else if (type == CRILJ) redo_cind (a, n, sn, pnr, indr, &tid); else { /* The modification */ u2_t corsize; struct des_tid ref_tid; corsize = get_placement (sn, &tid, &ref_tid); n -= corsize; ordmod (sn, rn, &tid, &ref_tid, corsize, a + corsize, n); if (rn != RDRNUM) mproind (desrel, desrel->desrbd.indnum, a, a + corsize, &tid); else { ordrn = t4bunpack (a + scscal (a)); desrel = firstrel; for (; desrel->desrbd.relnum != ordrn; desrel = desrel->drlist); if (desrel == NULL) perror ("LIBRCV.frwrd_mtn: The correspondent desrel is absent\n"); if (type == DLILJ) /*nead to delete an index */ redo_dind (desrel, a + corsize); else if (type == ADFLJ) { /*nead to add fields */ struct d_r_bd drbd; u2_t fn; a += scscal (a) + corsize; drbdunpack (&drbd, a); fn = drbd.fieldnum; desrel->desrbd.fieldnum = fn; dfunpack (desrel, fn * rfsize, a + drbdsize); } } }}voidgetmint (char *a, u2_t n){ register u2_t i, NFTRANS; i4_t cidtr; NFTRANS = n / size4b; if (NFTRANS == 0) return; minidnt = t4bunpack (a); a += size4b; for (i = 1; i < NFTRANS; i++, a += size4b) { cidtr = t4bunpack (a); if (cidtr < minidnt) minidnt = cidtr; }}voidr_tr (struct ADBL cadlj)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -