rllbfn.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:10k
- /*
- * rllbfn.c - Rollback Functions
- *
- * 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: rllbfn.c,v 1.249 1997/04/17 11:03:20 vera Exp $ */
- #include "xmem.h"
- #include "destrn.h"
- #include "strml.h"
- #include "fdcltrn.h"
- #include "totdecl.h"
- #include <assert.h>
- extern struct d_r_t *firstrel;
- extern i2_t maxscan;
- extern char **scptab;
- #define INDEX_PTR(table_tuple_ptr,table_descriptor_ptr)
- (table_tuple_ptr + scscal (table_tuple_ptr) + drbdsize + table_descriptor_ptr->desrbd.fieldnum * rfsize)
- /*
- * redo relation tuple deletion
- */
- void
- redo_dltn (u2_t sn, struct d_r_t *desrel, i4_t rn,
- struct des_tid *tid, u2_t n, char *a)
- {
- i4_t ordrn;
- struct des_tid ref_tid;
- ref_tid.tpn = (u2_t) ~ 0;
- orddel (sn, rn, tid, &ref_tid, n);
- if (rn != RDRNUM)
- {
- proind (ordindd, desrel, desrel->desrbd.indnum, a, tid);
- return;
- }
- /* else */
- ordrn = t4bunpack (a + scscal (a));
-
- /* find relation descriptor */
- for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist)
- if (desrel->desrbd.relnum == ordrn)
- break;
-
- if (desrel == NULL) /* if descrel not found */
- return; /* just return - but it looks strange -- may be we should produce warning ?? */
- /* delete all indexes, defined on given table */
- while ( desrel->pid != NULL )
- {
- struct ldesind *di;
- di = desrel->pid;
- desrel->pid = di->listind;
- delscd (di->oscni, (char *) di);
- killind (di);
- xfree ((void *) di);
- }
-
- delscd (desrel->oscnum, (char *) desrel);
- /* remove desrel from list */
- if (desrel == firstrel)
- firstrel = desrel->drlist;
- else
- {
- struct d_r_t *dr;
- for (dr = firstrel; dr->drlist != desrel; dr = dr->drlist);
- assert( dr->drlist == desrel );
- dr->drlist = desrel->drlist;
- }
- xfree ((void *) desrel);
- }
- /*
- * redo tuple insertation
- */
- void
- redo_insrtn (u2_t sn, struct d_r_t *desrel, i4_t rn,
- struct des_tid *tid, i2_t n, char *a)
- {
- if (nordins (sn, rn, tid, CORT, MIN_TUPLE_LENGTH, n, a) != 0)
- doindir (sn, rn, tid, MIN_TUPLE_LENGTH, n, a);
- if (rn != RDRNUM)
- proind (ordindi, desrel, desrel->desrbd.indnum, a, tid);
- else
- {
- i4_t ordrn;
- struct d_r_t *desrel1;
- struct ldesind *di;
- struct id_rel idr;
-
- ordrn = t4bunpack (a + scscal (a));
- idr.urn.segnum = sn;
- idr.urn.obnum = ordrn;
- idr.pagenum = tid->tpn;
- idr.index = tid->tindex;
- desrel1 = crtfrd (&idr, a);
- for (di = desrel1->pid; di != NULL; di = di->listind)
- crindci (di);
- }
- }
- /*
- * redo "delete index" operation.
- *
- * DESCREL point to present relation structure b_e_f_o_r_e deletion operation
- * NEW_TABLE_TUPLE points to new descriptor tuple a_f_t_e_r modification
- *
- * this function compares index description prior and after modification and
- * executes all required operations to tranform index structure
- */
- void
- redo_dind (struct d_r_t *desrel, char *new_table_tuple)
- {
- struct ldesind *di, *prdi;
- char *pnt;
- char *indexes_prt;
- u2_t kn, indn, i;
- indexes_prt = INDEX_PTR(new_table_tuple,desrel);
-
- indn = desrel->desrbd.indnum - 1; /* (++) this function expect deletion of only one index */
-
- for (prdi = NULL, di = desrel->pid ;
- di != NULL;
- prdi = di, di = (di?di->listind:desrel->pid))
- { /* for every existent index */
- pnt = indexes_prt;
- for (i = 0; i < indn; i++) /* scan new table tuple */
- {
- struct des_index desind;
-
- BUFUPACK(pnt,desind); /* unpack it indexes descr */
- kn = desind.kifn & ~UNIQ & MSK21B; /* calculate number of keys */
- pnt += kn * size2b; /* and skip keys' descriptors */
- if (desind.unindex == di->ldi.unindex) /* if existent index is in */
- break; /* new tuple check another one*/
- }
- if (i < indn) /* if current index has not */
- continue; /* been removed goto next one */
- /* current index WAS removed -- redo index deletion */
- /* delete index from table list */
- if (prdi == NULL)
- desrel->pid = di->listind;
- else
- prdi->listind = di->listind;
- desrel->desrbd.indnum--;
- delscd (di->oscni, (char *) di);
- killind (di);
- xfree ((void *) di);
- di = prdi;
- /* here we have done redo of one index deletion. */
- break; /* this function expect deletion of only one index - see (++) above */
- }
- }
- /*
- * redo "create index" operation.
- * unclear logic ??? /mk
- *
- */
- void
- redo_cind (char *a, i2_t n, u2_t sn, u2_t pnr,
- u2_t indr, struct des_tid *tid)
- {
- struct ldesind *di;
- char *tuple;
- struct des_index desind;
- struct d_r_t *desrel;
- u2_t kn = 0, size = 0, indn, i, corsize;
- i4_t ordrn;
- struct des_tid ref_tid;
-
- ordrn = t4bunpack (a + scscal (a));
- for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist)
- if (desrel->desrbd.relnum == ordrn)
- break;
- if (desrel == NULL)
- {
- struct id_rel idr;
- idr.urn.segnum = sn;
- idr.urn.obnum = ordrn;
- idr.pagenum = pnr;
- idr.index = indr;
- desrel = crtfrd (&idr, a);
- }
- corsize = get_placement (sn, tid, &ref_tid);
- a += corsize;
- tuple = a;
- a = INDEX_PTR(tuple,desrel);
- indn = desrel->desrbd.indnum + 1; /* we expect creation of only one index */
- assert( indn >0);
- for (i = 0; i < indn; i++)
- {
- BUFUPACK(a,desind);
- kn = desind.kifn & ~UNIQ & MSK21B;
- size = kn * size2b;
- for (di = desrel->pid; di != NULL; di = di->listind)
- if (desind.unindex == di->ldi.unindex)
- break;
- else
- a += size; /* ???/mk */
- }
- if ((kn % 2) != 0)
- size += size2b;
- di = (struct ldesind *) xmalloc (size + ldisize + rfsize);
- bcopy (a, (char *) (di + 1), kn * size2b);
- di->ldi = desind;
- crtid (di, desrel);
- crindci (di);
- desrel->desrbd.indnum++;
- n -= corsize;
- ordmod (sn, RDRNUM, tid, &ref_tid, corsize, tuple, n);
- fill_ind (desrel, di);
- }
- u2_t
- get_placement (u2_t sn, struct des_tid *tid, struct des_tid *ref_tid)
- {
- char *a, *asp = NULL;
- u2_t *afi, *ai, corsize;
- struct A pg;
- unsigned char t;
- while ((asp = getpg (&pg, sn, tid->tpn, 's')) == NULL);
- afi = (u2_t *) (asp + phsize);
- ai = afi + tid->tindex;
- a = asp + *ai;
- t = *a & MSKCORT;
- if (t == IND)
- { /* indirect reference */
- u2_t pn2, ind2;
- ind2 = t2bunpack (a + 1);
- pn2 = t2bunpack (a + 1 + size2b);
- putpg (&pg, 'n');
- while ((asp = getpg (&pg, sn, pn2, 's')) == NULL);
- afi = (u2_t *) (asp + phsize);
- ai = afi + ind2;
- assert (*ai != 0);
- ref_tid->tpn = pn2;
- ref_tid->tindex = ind2;
- }
- else
- ref_tid->tpn = (u2_t) ~ 0;
- corsize = calsc (afi, ai);
- putpg (&pg, 'n');
- return (corsize);
- }
- void
- delscd (u2_t n, char *a)
- {
- char *s;
- i4_t k;
- for (k = 0; n != 0 && k < maxscan; k++)
- for (; (s = *(scptab + k)) != NULL; k++)
- if (a == ((struct d_mesc *) s)->pobsc)
- {
- xfree ((void *) s);
- n--;
- }
- }
- void
- fill_ind (struct d_r_t *desrel, struct ldesind *desind)
- {
- char *c = NULL, *cort;
- u2_t *ai, *afi, *ali, ind;
- struct A inpg;
- struct d_sc_i *scind;
- struct ldesscan *disc;
- u2_t sn, pn, size, fdf;
- i2_t num;
- i4_t rep;
- struct des_tid tid;
- struct ldesind *di, *prevdi;
- char mas[BD_PAGESIZE];
- sn = desrel->segnr;
- fdf = desrel->desrbd.fdfnum;
- scind = rel_scan (sn, desrel->desrbd.relnum, (char *) desrel, &num, 0, NULL, NULL, 0, 0, NULL);
- disc = &scind->dessc;
- rep = fgetnext (disc, &pn, &size, FASTSCAN);
- for (; rep != EOI;)
- {
- while ((c = getpg (&inpg, sn, pn, 's')) == NULL);
- afi = (u2_t *) (c + phsize);
- ali = afi + ((struct page_head *) c)->lastin;
- tid.tpn = pn;
- for (ai = afi, ind = 0; ai <= ali; ai++, ind++)
- if (*ai != 0 && CHECK_PG_ENTRY(ai))
- {
- tid.tindex = ind;
- cort = c + *ai;
- keyform (desind, fdf, mas, cort);
- ordindi (desind, mas, &tid);
- }
- putpg (&inpg, 'n');
- rep = getnext (disc, &pn, &size, FASTSCAN);
- }
- delscan (num);
- if ((di = desrel->pid) == NULL)
- desrel->pid = desind;
- else
- {
- do
- {
- prevdi = di;
- di = di->listind;
- }
- while( di != NULL);
- prevdi->listind = desind;
- }
- desind->listind = NULL;
- }
- struct d_r_t *
- crtfrd (struct id_rel *pidrel, char *tuple)
- {
- struct d_r_t *desrel;
- desrel = crtrd (pidrel, tuple);
- if (desrel->desrbd.indnum != 0)
- crt_all_id (desrel, tuple);
- return (desrel);
- }
- void
- crt_all_id (struct d_r_t *desrel, char *a)
- {
- u2_t i, indn, size;
- u2_t kn1, size1;
- struct des_index cdi;
- struct ldesind *di;
- a += scscal (a) + drbdsize + desrel->desrbd.fieldnum * rfsize;
- indn = desrel->desrbd.indnum;
- for (i = 0; i < indn; i++)
- {
- dindunpack (&cdi, a);
- a += dinsize;
- kn1 = cdi.kifn & ~UNIQ & MSK21B;
- size = kn1 * size2b;
- size1 = size;
- if (kn1 % 2 != 0)
- size1 += size2b;
- size1 += rfsize;
- di = (struct ldesind *) xmalloc (ldisize + size1);
- di->ldi = cdi;
- bcopy (a, (char *) (di + 1), size);
- a += size;
- di->listind = desrel->pid;
- desrel->pid = di;
- crtid (di, desrel);
- }
- }
- void
- dindunpack (struct des_index *di, char *pnt)
- {
- /*
- di->unindex=t4bunpack(pnt); pnt+=size4b;
- di->rootpn=t2bunpack(pnt); pnt+=size2b;
- di->kifn=t2bunpack(pnt); pnt+=size2b;
- */
- bcopy (pnt, (char *) di, dinsize);
- }