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 / log / calculateLogSpace.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-05  |  6.4 KB  |  254 lines

  1. /*
  2.  *   $RCSfile: calculateLogSpace.c,v $  
  3.  *   $Revision: 1.1.1.1 $  
  4.  *   $Date: 1996/05/04 21:55:49 $      
  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.  
  38. #include "sysdefs.h"
  39. #include "ess.h"
  40. #include "checking.h"
  41. #include "trace.h"
  42. #include "error.h"
  43. #include "list.h"
  44. #include "pool.h"
  45. #include "tid.h"
  46. #include "io.h"
  47. #include "lock.h"
  48. #include "object.h"
  49. #include "msgdefs.h"
  50. #include "thread.h"
  51. #include "semaphore.h"
  52. #include "latch.h"
  53. #include "link.h"
  54. #include "lsn.h"
  55. #include "bf.h"
  56. #include "volume.h"
  57. #include "openlog.h"
  58. #include "trans.h"
  59. #include "logrecs.h"
  60. #include "threadstate.h"
  61. #include "log.h"
  62. #include "log_intfuncs.h"
  63. #include "log_extfuncs.h"
  64. #include "log_globals.h"
  65. #include "thread_globals.h"
  66.  
  67.  int
  68. calculateLogSpace (
  69.  
  70.     OPENLOG        *openLog,
  71.     int            length 
  72. )
  73. {
  74.     SHORTPID    limitPid;
  75.     LSNOFFSET    limitLSN;
  76.     BOOL        checkLimit;
  77.     SHORTPID    tailPid;
  78.     int            freePages;
  79.     TRANSREC     *transRec;
  80.  
  81.     TRPRINT(TR_LOG, TR_LEVEL_1, ("length:%d", length));
  82.  
  83.     /*
  84.      *    check to make sure the the thing will fit in the undo buffer
  85.      *    and is less than the max log record length
  86.      */
  87.     if ( (length + sizeof(LOGRECORDHDR)) > MAX_LOGREC_LEN)  {
  88.         SM_ERROR(TYPE_LOG, esmLOGRECORDTOOBIG);
  89.         return(esmFAILURE);
  90.     }
  91.  
  92.     /*
  93.      *    Calculate how much space needs to be reserved in the log
  94.      *    This is dependent upon whether the log record is for an
  95.      *    aborting transaction or for a transaction performing
  96.      *    normal operations
  97.      *    PRAKASH: normal operations include those in T_PREPARED,
  98.      *             and T_COMMIT states
  99.      */
  100.     transRec = (TRANSREC *) Active->transRec;
  101.     if    ((transRec != NULL) && 
  102.          ((transRec->transState == T_ACTIVE) ||
  103.           (transRec->transState == T_PREPARED) ||
  104.           (transRec->transState == T_COMMIT))) {
  105.         
  106.         /*
  107.          *    The transactions is performing normal operations, and
  108.          *    therefore the log must have enough space to 
  109.          *    guarantee that all currently active transactions can
  110.          *    be undone.  Space for two maximum size log records is
  111.          *    also required to be available as a precaution.
  112.          */
  113.         length += ActiveLogSpace + LOG_SLACK;
  114.         TRPRINT(TR_LOG, TR_LEVEL_2, ("space needed:%d", length));
  115.  
  116.     } else {
  117.         
  118.         /*
  119.          *    The transaction is being undone, so only reserve two
  120.          *    extra pages.
  121.          *
  122.          */
  123.         length += openLog->pageSize * 2;
  124.         TRPRINT(TR_LOG, TR_LEVEL_2, ("space needed:%d", length));
  125.     }
  126.  
  127.     /*
  128.      *    calculate the space left in the file between the last
  129.      *    active transaction and the last checkpoint
  130.      */
  131.     if (openLog->activePid < 0)    {
  132.  
  133.         /*
  134.          *    there are no active transactions so the byte offset of
  135.          *    the checkpoint record is the limiting page
  136.          */
  137.         limitLSN  = OldestDirtyPageLSN.offset;
  138.         limitPid  = LSN_TO_LOG_PAGE(limitLSN, openLog);
  139.         checkLimit = TRUE;
  140.         TRPRINT(TR_LOG, TR_LEVEL_2, ("no active transaction"));
  141.  
  142.     } else if (openLog->activeUnique < openLog->checkPointUnique)    {
  143.  
  144.         /*
  145.          *    the active transaction is the limiting factor
  146.          */
  147.         limitPid = openLog->activePid;
  148.         limitLSN = openLog->activeLSN;
  149.         checkLimit = FALSE;
  150.         TRPRINT(TR_LOG, TR_LEVEL_2, ("active limiting"));
  151.  
  152.     } else {
  153.  
  154.         /*
  155.          *    there are no transactions before the checkpoint
  156.          *    so the checkpoint record is the limit
  157.          */
  158.         limitLSN  = OldestDirtyPageLSN.offset;
  159.         limitPid  = LSN_TO_LOG_PAGE(limitLSN, openLog);
  160.         checkLimit = TRUE;
  161.         TRPRINT(TR_LOG, TR_LEVEL_2, ("checkpoint limiting"));
  162.     }
  163.     TRPRINT(TR_LOG, TR_LEVEL_2, ("limitPid:%d limitLSN:%d", limitPid, limitLSN));
  164.  
  165.     /*
  166.      *    get the tail pid in a register
  167.      */
  168.     tailPid = openLog->tailPid;
  169.  
  170.     /*
  171.      *    calculate the space that can be used
  172.      */
  173.     if (tailPid < limitPid)    {
  174.  
  175.         /*
  176.          *    calculate the space between
  177.          */
  178.         freePages = (((int)limitPid - (int) tailPid) - 1);
  179.         TRPRINT(TR_LOG, TR_LEVEL_2, ("freePages:%d", freePages));
  180.  
  181.     } else if (tailPid > limitPid)    {
  182.  
  183.         /*
  184.          *    calculate the space at the end and beginning of file
  185.          */
  186.         freePages = ((int)openLog->filePages - ((int)tailPid + 1)) + (int)limitPid;
  187.         TRPRINT(TR_LOG, TR_LEVEL_2, ("freePages:%d", freePages));
  188.  
  189.     } else {
  190.  
  191.         /*
  192.          *    check to see which order the records appear on the page
  193.          */
  194.         if (limitLSN < openLog->tailLSN)    {
  195.  
  196.             /*
  197.              *    set free pages to filesize minus one page
  198.              */
  199.             freePages = openLog->filePages - 1;
  200.             TRPRINT(TR_LOG, TR_LEVEL_2, ("freePages:%d", freePages));
  201.  
  202.         } else {
  203.  
  204.             /*
  205.              *    there is no room
  206.              */
  207.             freePages = 0;
  208.             TRPRINT(TR_LOG, TR_LEVEL_2, ("freePages:%d", freePages));
  209.         }
  210.     }
  211.     TRPRINT(TR_LOG, TR_LEVEL_2, ("tailPid:%d limitPid:%d freePages:%d freeSpace:%d",
  212.             tailPid, limitPid, freePages, freePages << openLog->page2size));
  213.  
  214.     /*
  215.      *    check to see if there is enough space to satisfy the request
  216.      */
  217.     if (length < (freePages << openLog->page2size))    {
  218.  
  219.         /*
  220.          *    return success
  221.          */
  222.         TRPRINT(TR_LOG, TR_LEVEL_2, ("enough space"));
  223.         return(esmNOERROR);
  224.     
  225.     } else {
  226.  
  227.         /*
  228.          *    take action based on limiting factor
  229.          */
  230.         if (checkLimit)    {
  231.  
  232.             /*
  233.              *    return an error code that will force a checkpoint
  234.              */
  235.             TRPRINT(TR_LOG, TR_LEVEL_2, ("need checkpoint"));
  236.             return(LOG_DO_CHECKPOINT);
  237.  
  238.         } else {
  239.  
  240.             /*
  241.              *    abort the transactions that have not completed
  242.              */
  243.             abortLogSpace(openLog, length);
  244.  
  245.             /*
  246.              *    return the error to the caller
  247.              */
  248.             TRPRINT(TR_LOG, TR_LEVEL_2, ("abort transactions"));
  249.             return(esmNOFREELOGSPACE);
  250.         }
  251.     }
  252. }
  253.  
  254.