home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / db / esm-3.1 / esm-3 / usr / local / sm / src / serverlib / undo / undoBtree.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  10.4 KB  |  365 lines

  1. /*
  2.  *   $RCSfile: undoBtree.C,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:56:03 $      
  5.  */ 
  6. /**********************************************************************
  7. * EXODUS Database Toolkit Software
  8. * Copyright (c) 1991 Computer Sciences Department, University of
  9. *                    Wisconsin -- Madison
  10. * All Rights Reserved.
  11. *
  12. * Permission to use, copy, modify and distribute this software and its
  13. * documentation is hereby granted, provided that both the copyright
  14. * notice and this permission notice appear in all copies of the
  15. * software, derivative works or modified versions, and any portions
  16. * thereof, and that both notices appear in supporting documentation.
  17. *
  18. * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
  19. * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.  
  20. * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
  21. * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  22. *
  23. * The EXODUS Project Group requests users of this software to return 
  24. * any improvements or extensions that they make to:
  25. *
  26. *   EXODUS Project Group 
  27. *     c/o David J. DeWitt and Michael J. Carey
  28. *   Computer Sciences Department
  29. *   University of Wisconsin -- Madison
  30. *   Madison, WI 53706
  31. *
  32. *     or exodus@cs.wisc.edu
  33. *
  34. * In addition, the EXODUS Project Group requests that users grant the 
  35. * Computer Sciences Department rights to redistribute these changes.
  36. **********************************************************************/
  37. #include "BTREEPAGE.h"
  38. #include "BT_Log.h"
  39. #ifdef INIT_LRC_IS_LSN
  40. #   include "log_globals.h"
  41. #endif
  42. #include "undo_extfuncs.h"
  43.  
  44. #ifdef DEBUG
  45. int undoBtreeTrace = FALSE;
  46. #undef BT_TRACE
  47. #define BT_TRACE(x)  { if (undoBtreeTrace)  printf x; }
  48.  
  49.  
  50. char* BT_PrintKey(SMDATATYPE type, void* key, int unused)
  51. {
  52.     static char buf[80];
  53.     switch (type)  {
  54.         case SM_char:
  55.             (void) sprintf(buf, "%c", key);
  56.             break;
  57.         case SM_int:
  58.             (void) sprintf(buf, "%d", * (int*) key);
  59.             break;
  60.         case SM_long:
  61.             (void) sprintf(buf, "%d", * (long*) key);
  62.             break;
  63.         case SM_short:
  64.             (void) sprintf(buf, "%d", * (short*) key);
  65.             break;
  66.         case SM_float:
  67.             (void) sprintf(buf, "%f", * (float*) key);
  68.             break;
  69.         case SM_double:
  70.             (void) sprintf(buf, "%f", * (double*) key);
  71.             break;
  72.         case SM_string:
  73.             return (char*) key;
  74.         default:
  75.             return 0;
  76.         }
  77.     
  78.     return buf;
  79. }
  80. #else
  81. #define BT_TRACE(x)  
  82. #endif DEBUG
  83.  
  84.  
  85.  
  86.  
  87.  
  88. // call the friend separately to avoid g++ bug
  89. void undoBtree(LOGRECORDHDR* recHdr)
  90. {
  91.     undoBtree_fr(recHdr);
  92. }
  93.  
  94. void undoBtree_fr(LOGRECORDHDR* recHdr)
  95. {
  96. #ifdef INIT_LRC_IS_LSN
  97.     LRC                 tempLRC;
  98.     LRC                 *lrc = &tempLRC;
  99. #else
  100.     LRC                 *lrc;
  101. #endif /* INIT_LRC_IS_LSN; */
  102.  
  103.     TRPRINT(TR_IO, TR_LEVEL_1, ("lsn:%d", recHdr->recordLSN));
  104.  
  105.     TRANSREC* transRec = (TRANSREC*) Active->transRec;
  106.     INIT_MISSING_UPDATE_INFO(transRec);
  107.     PID* pid = &recHdr->actionPid;
  108.     GROUPLINK* groupLink = bf_ReadPage(UserBufGroup, pid, 
  109.                                         BTREE_PAGE2SIZE, BF_SEM);
  110.     BTREEPAGE* bp = (BTREEPAGE*) groupLink->bufFrame;
  111.     BOOL actionDone = compareLRC( &recHdr->actionLRC, &(bp->lrc())) <= 0;
  112.  
  113.     TRPRINT(TR_IO|TR_LOG, TR_LEVEL_2, ("pid:%d", pid->page));
  114.  
  115. #ifndef INIT_LRC_IS_LSN
  116.     SM_ASSERT(LEVEL_3, missingUpdateInfo != NULL);
  117. #endif INIT_LRC_IS_LSN
  118.  
  119.     RECORD_MISSING_UPDATE(actionDone, &lrc, missingUpdateInfo, pid,
  120.                         &bp->lrc(), groupLink->pageHash, recHdr, PAGE_INDEX);
  121.  
  122.     if (lrc != & bp->lrc())      GENERATE_LRC(lrc);
  123.  
  124.     LSNOFFSET undoNextLSN = recHdr->previousLSN;
  125.  
  126.     signalSemaphore( & groupLink->pageHash->semaphore);
  127.     
  128.     void* vptr = GET_LOG_IMAGE(recHdr, 0);
  129.     BT_TRACE(("U(%d,%d,%c): ", recHdr->recordLSN.offset, pid->page, actionDone ? 't' : 'f'));
  130.     PAGEHASH* pHash = actionDone ? groupLink->pageHash : 0;
  131.         
  132.     switch (recHdr->action)  {
  133.         int i;
  134.         
  135.         case LOG_ACTION_BTREE_MODIFY_LINK:
  136.             {
  137.             LogBtreeModifyLinkData* rp = (LogBtreeModifyLinkData*) vptr;
  138.             BT_TRACE(("modify link\n"));
  139.             if (actionDone)  {
  140.                 ASSERT3(bp->NextPage() == rp->newNext);
  141.                 ASSERT3(bp->PrevPage() == rp->newPrev);
  142.                 bp->btCtrl.next = rp->oldNext;
  143.                 bp->btCtrl.prev = rp->oldPrev;
  144.                 }
  145.             BT_LogModifyLink(bp->SelfID(), pHash, *lrc,
  146.                                 rp->newNext, rp->oldNext, 
  147.                                 rp->newPrev, rp->oldPrev, undoNextLSN);
  148.             }
  149.             break;
  150.             
  151.         case LOG_ACTION_BTREE_MODIFY_VECTOR0:
  152.             {
  153.             LogBtreeModifyVector0Data* rp = (LogBtreeModifyVector0Data*) vptr;
  154.             BT_TRACE(("modify vec0\n"));
  155.             if (actionDone)  {
  156.                 ASSERT3(bp->FirstVector() == rp->newPid0);
  157.                 bp->SetFirstVector(rp->oldPid0);
  158.                 }
  159.             BT_LogModifyVector0(bp->SelfID(), pHash, *lrc,
  160.                                     rp->newPid0, rp->oldPid0, undoNextLSN);
  161.             }
  162.             break;
  163.             
  164.         case LOG_ACTION_BTREE_MODIFY_LEVEL:
  165.             {
  166.             LogBtreeModifyLevelData* rp = (LogBtreeModifyLevelData*) vptr;
  167.             BT_TRACE(("modify level\n"));
  168.             if (actionDone)  {
  169.                 ASSERT3(bp->Level() == rp->newLevel);
  170.                 bp->SetLevel(rp->oldLevel);
  171.                 }
  172.             BT_LogModifyLevel(bp->SelfID(), pHash, *lrc,
  173.                                 rp->newLevel, rp->oldLevel, undoNextLSN);
  174.             }
  175.             break;
  176.             
  177.         case LOG_ACTION_BTREE_PHYSIC_INSERT:
  178.             {
  179.             LogBtreePhysicInsertData* rp = (LogBtreePhysicInsertData*) vptr;
  180.             ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
  181.             BT_TRACE(("physic insert\n"));
  182.             if (actionDone)  {
  183.                 for (i = rp->startSlot + rp->numSlots - 1;
  184.                                             i >= rp->startSlot; i--)  {
  185.                     bp->RemoveTuple(i);
  186.                     }
  187.                 }
  188.             BT_LogPhysicDelete(bp->SelfID(), pHash, *lrc,
  189.                                     rp->startSlot, rp->numSlots, 
  190.                                     (int)rp->length, rp->data, undoNextLSN);
  191.             }
  192.             break;
  193.         case LOG_ACTION_BTREE_PHYSIC_DELETE:
  194.             {
  195.             LogBtreePhysicDeleteData* rp = (LogBtreePhysicDeleteData*) vptr;
  196.             ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
  197.             BT_TRACE(("physic delete\n"));
  198.             if (actionDone)  {
  199.                 char* buff = rp->data;
  200.                 for (i = rp->startSlot; i < rp->startSlot+rp->numSlots; i++)  {
  201.                     BT_Tuple* tp = (BT_Tuple*) buff;
  202.                     bp->InsertTuple(*tp, i);
  203.                     buff += tp->Size();
  204.                     }
  205.                 ASSERT3(buff - rp->data <= rp->length);
  206.                 }
  207.             BT_LogPhysicInsert(bp->SelfID(), pHash, *lrc,
  208.                                 rp->startSlot, rp->numSlots, 
  209.                                 (int)rp->length, rp->data, undoNextLSN);
  210.             }
  211.             break;
  212.             
  213.         case LOG_ACTION_BTREE_LOGIC_INSERT:
  214.             {
  215.             LogBtreeLogicInsertData* rp = (LogBtreeLogicInsertData*) vptr;
  216.             BT_TRACE(("logic insert %s\n", 
  217.                             BT_PrintKey(rp->keyType, rp->Key(), rp->keyLen)));
  218.             if (actionDone)  {
  219.                 if (bt_RemoveEntry(transRec->tid, rp->rootPid, UserBufGroup,
  220.                                     rp->Key(), rp->keyLen, 
  221.                                     rp->elSize, rp->El(),
  222.                                     rp->maxKeyLen, rp->unique,
  223.                                     SMCOMPFUNC[rp->keyType], undoNextLSN)) {
  224.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  225.                     }
  226.                 }
  227.             else {
  228.                 BT_LogLogicDelete(bp->SelfID(), pHash, *lrc,
  229.                                     rp->rootPid, rp->Key(),
  230.                                     rp->keyLen, rp->El(),
  231.                                     rp->elSize,
  232.                                     rp->maxKeyLen,
  233.                                     rp->unique, rp->keyType, undoNextLSN);
  234.                 }
  235.             }
  236.             actionDone = FALSE;    /* assume action not done on this page */
  237.             break;
  238.         
  239.         case LOG_ACTION_BTREE_LOGIC_DELETE:
  240.             {
  241.             LogBtreeLogicDeleteData* rp = (LogBtreeLogicDeleteData*) vptr;
  242.             BT_TRACE(("logic delete %s\n", 
  243.                             BT_PrintKey(rp->keyType, rp->Key(), rp->keyLen)));
  244.             if (actionDone)  {
  245.                 if (bt_InsertEntry(transRec->tid, rp->rootPid, UserBufGroup,
  246.                                     rp->Key(), rp->keyLen, 
  247.                                     rp->elSize, rp->El(),
  248.                                     rp->maxKeyLen, rp->unique,
  249.                                     SMCOMPFUNC[rp->keyType], undoNextLSN))  {
  250.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  251.                     }
  252.                 }
  253.             else {
  254.                 BT_LogLogicInsert(bp->SelfID(), pHash, *lrc,
  255.                                     rp->rootPid, rp->Key(),
  256.                                     rp->keyLen, rp->El(), rp->elSize,
  257.                                     rp->maxKeyLen,
  258.                                     rp->unique, rp->keyType, undoNextLSN);
  259.                 }
  260.             }
  261.             actionDone = FALSE;    /* assume action not done on this page */
  262.             break;
  263.             
  264.         case LOG_ACTION_BTREE_LOGIC_INCR_OIDCNT:
  265.             {
  266.             LogBtreeLogicIncrElCntData* rp = 
  267.                                         (LogBtreeLogicIncrElCntData*) vptr;
  268.             BT_TRACE(("++oidcnt\n"));
  269.             if (actionDone)  {
  270.                 if (BT_DecrElCnt(transRec->tid, rp->rootPid, UserBufGroup,
  271.                                     rp->key, rp->keyLen, rp->maxKeyLen, 
  272.                                     SMCOMPFUNC[rp->keyType], undoNextLSN)){
  273.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  274.                     }
  275.                 }
  276.             else {
  277.                 BT_LogLogicDecrElCnt(bp->SelfID(), pHash, *lrc,
  278.                                         rp->rootPid,
  279.                                         rp->key, rp->keyLen, rp->maxKeyLen,
  280.                                         rp->keyType, undoNextLSN);
  281.                 }
  282.             }
  283.             actionDone = FALSE; /* assume action not done on this page */
  284.             break;
  285.                                     
  286.         case LOG_ACTION_BTREE_LOGIC_DECR_OIDCNT:
  287.             {
  288.             LogBtreeLogicDecrElCntData* rp =
  289.                                         (LogBtreeLogicDecrElCntData*) vptr;
  290.             BT_TRACE(("--oidcnt\n"));
  291.             if (actionDone)  {
  292.                 if (BT_IncrElCnt(transRec->tid, rp->rootPid, UserBufGroup,
  293.                                     rp->key, rp->keyLen, rp->maxKeyLen, 
  294.                                     SMCOMPFUNC[rp->keyType], undoNextLSN)){
  295.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  296.                     }
  297.                 }
  298.             else {
  299.                 BT_LogLogicIncrElCnt(bp->SelfID(), pHash, *lrc,
  300.                                     rp->rootPid,
  301.                                     rp->key, rp->keyLen, rp->maxKeyLen,
  302.                                     rp->keyType, undoNextLSN);
  303.                 }
  304.             }
  305.             actionDone = FALSE; /* assume action not done on this page */
  306.             break;
  307.  
  308.         case LOG_ACTION_BTREE_LOGIC_SET_OVERFLOW:
  309.             {
  310.             LogBtreeLogicSetOverflowData* rp =
  311.                                     (LogBtreeLogicSetOverflowData*) vptr;
  312.             BT_TRACE(("set overflow\n"));
  313.             if (actionDone)  {
  314.                 if (BT_ResetOverflow(transRec->tid, rp->rootPid, UserBufGroup,
  315.                                     rp->KeyValue(), rp->keyLen, 
  316.                                     rp->maxKeyLen, SMCOMPFUNC[rp->keyType],
  317.                                     rp->ElList(), rp->numEl, undoNextLSN))  {
  318.                     SM_ERROR(TYPE_FATAL, esmINTERNAL);
  319.                     }
  320.                 }
  321.             else {
  322.                 BT_LogLogicResetOverflow(bp->SelfID(), pHash, 
  323.                                     *lrc, rp->rootPid,
  324.                                     rp->KeyValue(), rp->keyLen,
  325.                                     rp->maxKeyLen, rp->keyType,
  326.                                     rp->numEl, rp->elSize, 
  327.                                     rp->ElList(), rp->ovPid, undoNextLSN);
  328.                 }
  329.             }
  330.             actionDone = FALSE; /* assume action not done on this page */
  331.             break;
  332.             
  333.         case LOG_ACTION_BTREE_LOGIC_RESET_OVERFLOW:
  334.             {
  335.             LogBtreeLogicResetOverflowData* rp =
  336.                                         (LogBtreeLogicResetOverflowData*) vptr;
  337.             BT_TRACE(("reset overflow\n"));
  338.             if (actionDone)  {
  339.                 if (BT_SetOverflow(transRec->tid, rp->rootPid, UserBufGroup,
  340.                                     rp->KeyValue(), rp->keyLen, 
  341.                                     rp->maxKeyLen, SMCOMPFUNC[rp->keyType],
  342.                                     rp->ElList(), rp->numEl, undoNextLSN))  {
  343.                         SM_ERROR(TYPE_FATAL, esmINTERNAL);
  344.                         }
  345.                 }
  346.             else {
  347.                 BT_LogLogicSetOverflow(bp->SelfID(), pHash, *lrc,
  348.                                     rp->rootPid, rp->KeyValue(), 
  349.                                     rp->keyLen,    rp->maxKeyLen, rp->keyType,
  350.                                     rp->numEl, rp->elSize,
  351.                                     rp->ElList(), rp->ovPid, undoNextLSN);
  352.                 }
  353.             }
  354.             actionDone = FALSE; /* assume action not done on this page */
  355.             break;
  356.  
  357.         default:                
  358.             SM_ERROR(TYPE_FATAL, esmINTERNAL);
  359.         }
  360.  
  361.     bf_UnfixPage(groupLink, BF_DEFAULT, actionDone);
  362. }
  363.  
  364.  
  365.