home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 318_01 / redbuf.h < prev    next >
C/C++ Source or Header  |  1990-06-18  |  5KB  |  163 lines

  1. /*
  2.     Header for global buffer constants, structures.
  3.     Source:  redbuf.h
  4.     Version: November 15, 1983; January 18, 1990.
  5.  
  6.     Written by
  7.     
  8.         Edward K. Ream
  9.         166 N. Prospect
  10.         Madison WI 53705
  11.         (608) 257-0802
  12.  
  13.  
  14.     PUBLIC DOMAIN SOFTWARE
  15.  
  16.     This software is in the public domain.
  17.  
  18.     See red.h for a disclaimer of warranties and other information.
  19. */
  20.  
  21. /*
  22.     You may tune these constants for better disk performance.
  23.  
  24. DATA_SIZE:  The size of that part of struct BLOCK which is
  25.         written to the disk.  Make sure that DATA_SIZE
  26.         is a multiple of the size of your disk sectors.
  27.  
  28. MAX_RES:    The maximum number of BLOCKS resident in memory.
  29.         The code assumes this number is at least MIN_RES.
  30.         The actual number of resident blocks is DATA_RES.
  31.         DATA_RES is set by calling alloc(DATA_SIZE) until
  32.         MAX_RES blocks are allocated or until alloc() fails.
  33.  
  34.         I recommend MAX_RES = 40  so that the small data model
  35.         can be used.
  36. */
  37.  
  38. #define DATA_SIZE 1024
  39. #define MAX_RES      40    /* must have MIN_RES <= MAX_RES */
  40.  
  41. /*
  42.     !! Do NOT change the following constant !!
  43.  
  44.     The MIN_RES constant determines the minimum number of blocks that
  45.     must be allocated for RED to work properly.  MIN_RES must be large
  46.     enough so that the combine routine will work properly.  Determining
  47.     the true lower bound is tricky, and 10 is sure to work.
  48. */
  49. #define MIN_RES 10
  50.  
  51. #if MAX_RES < MIN_RES
  52. #error too few buffers specified.
  53. #endif
  54.  
  55. /*
  56.     Partially define the format of a block.  The end of
  57.     the data area contains an "index table" of indices
  58.     into the front of the data area.  Each index is the
  59.     index of the last byte of a line.
  60.  
  61.     Thus, it is possible to calculate the starting address
  62.     and length of each line in the block WITHOUT searching
  63.     through either the data field or the index table.
  64.  
  65.     The d_back and d_next fields in the header are used
  66.     to doubly-link the disk blocks so that stepping
  67.     through the blocks either forward or backwards is
  68.     efficient.  -1 denotes the end of each list.
  69.  
  70.     When blocks become totally empty they are entered
  71.     on a list of free blocks.  The links of this list
  72.     are kept in the blocks themselves in the d_next field.
  73.     The b_free variable is the head of this list.
  74. */
  75.  
  76. /*
  77.     Warning!!  RED will crash if the following two
  78.            defines are not right.
  79. */
  80.  
  81. #define HEADER_SIZE 3*sizeof(int)    /* size of the block header    */
  82. #define STATUS_SIZE 3*sizeof(int)    /* size of the status table    */
  83.  
  84. #define BUFF_SIZE  (DATA_SIZE - HEADER_SIZE)
  85. #define BLOCK_SIZE (DATA_SIZE + STATUS_SIZE)
  86.  
  87. struct BLOCK {
  88.  
  89.     /*    The block header.                */
  90.  
  91.     int    d_back;        /* # of previous block        */
  92.     int    d_next;        /* # of next block        */
  93.     int    d_lines;    /* # of lines on block        */
  94.  
  95.     /*    The data area and index table.            */
  96.  
  97.     char    d_data [BUFF_SIZE];
  98.  
  99.     /*    The status table -- not written to disk.    */
  100.  
  101.     int    d_lru;        /* lru count        */
  102.     int    d_status;    /* FULL, FREE or DIRTY    */
  103.     int    d_diskp;    /* disk pointer        */
  104. };
  105.  
  106. /*
  107.     Define the entries in the d_status field.
  108. */
  109.  
  110. #define FREE    1    /* status:  block is available    */
  111. #define FULL    2    /* status:  block is allocated    */
  112. #define DIRTY    3    /* status:  must swap out    */
  113.  
  114. #define bufatbot() (b_line > b_max_line)
  115. #define bufattop() (b_line == 1)
  116. #define bufchng()  b_cflag
  117. #define bufln()       b_line
  118. #define bufmax()   b_max_line
  119. #define bufnrbot() (b_line >= b_max_line)
  120.  
  121. /*
  122.     The following are all defined as macros for much greater speed.
  123.  
  124.     These macros replace corresponding functions in redbuf2.c.
  125.     See those functions for an explanation of what these macros do.
  126. */
  127. #define b1_avail()              b_avail(b_bp)
  128. #define b1_length(line)         b_length(b_bp, (line))
  129. #define b1_nlines()             (b_bp -> d_lines)
  130. #define b1_prefix(line)         b_prefix(b_bp, (line))
  131. #define b1_ptr(line)            b_ptr(b_bp, (line))
  132. #define b1_settab(index, value)    b_settab(b_bp, (index), (value))
  133. #define b1_tab(index)            b_tab(b_bp, (index))
  134.  
  135. #define b_getnum(p)             (* ((int *) (p)))
  136. #define b_putnum(p, num)        (* ((int *) (p)) = (num))
  137.  
  138. #define b_avail(bp) \
  139.     ( ((bp)-> d_lines==0) ?    BUFF_SIZE : \
  140.       (BUFF_SIZE-b_tab((bp),(bp)->d_lines-1)-(sizeof(int)*bp->d_lines)) )
  141.  
  142. #define b_length(bp,line) \
  143.     ( (bufatbot()) ? 0 : \
  144.     ( ((line)==0) ? (b_tab((bp), line)) : \
  145.       (b_tab((bp),(line)) - b_tab((bp),(line)-1)) ))
  146.  
  147. #define b_nlines(bp) ((bp) -> d_lines)
  148.  
  149. #define b_prefix(bp, line) \
  150.     ( ((line)==0) ? 0 : (b_tab((bp),(line)-1)) )
  151.  
  152. #define b_ptr(bp, line) \
  153.     ( ((line)==0) ? ((bp)->d_data) : \
  154.       ((bp)->d_data + b_tab((bp),(line)-1)) )
  155.  
  156. #define b_settab(bp,index,value) \
  157.     b_putnum((bp)->d_data+BUFF_SIZE-(sizeof(int)*((index)+1)),(value))
  158.  
  159. #define b_tab(bp, index) \
  160.     b_getnum((bp)->d_data+BUFF_SIZE-(sizeof(int)*((index)+1)))
  161.  
  162. #define is_dirty(bp) ((bp) -> d_status = DIRTY)
  163.